Refactor the Pileup Element with regards to indels
Eric reported this bug due to the reduced reads failing with an index out of bounds on what we thought was a deletion, but turned out to be a read starting with insertion. * Refactored PileupElement to distinguish clearly between deletions and read starting with insertion * Modified ExtendedEventPileup to correctly distinguish elements with deletion when creating new pileups * Refactored most of the lazyLoadNextAlignment() function of the LocusIteratorByState for clarity and to create clear separation between what is a pileup with a deletion and what's not one. Got rid of many useless if statements. * Changed the way LocusIteratorByState creates extended event pileups to differentiate between insertions in the beginning of the read and deletions. * Every deletion now has an offset (start of the event) * Fixed bug when LocusITeratorByState found a read starting with insertion that happened to be a reduced read. * Separated the definitions of deletion/insertion (in the beginning of the read) in all UG annotations (and the annotator engine). * Pileup depth of coverage for a deleted base will now return the average coverage around the deletion. * Indel ReadPositionRankSum test now uses the deletion true offset from the read, changed all appropriate md5's * The extra pileup elements now properly read by the Indel mode of the UG made any subsequent call have a different random number and therefore all RankSum tests have slightly different values (in the 10^-3 range). Updated all appropriate md5s after extremely careful inspection -- Thanks Ryan! phew!
This commit is contained in:
parent
4aacaf8916
commit
ffd61f4c1c
|
|
@ -47,6 +47,7 @@ public class AllLocusView extends LocusView {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new queue of locus contexts.
|
* Create a new queue of locus contexts.
|
||||||
|
*
|
||||||
* @param provider
|
* @param provider
|
||||||
*/
|
*/
|
||||||
public AllLocusView(LocusShardDataProvider provider) {
|
public AllLocusView(LocusShardDataProvider provider) {
|
||||||
|
|
@ -129,11 +130,14 @@ public class AllLocusView extends LocusView {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a blank locus context at the specified location.
|
* Creates a blank locus context at the specified location.
|
||||||
|
*
|
||||||
* @param site Site at which to create the blank locus context.
|
* @param site Site at which to create the blank locus context.
|
||||||
* @return empty context.
|
* @return empty context.
|
||||||
*/
|
*/
|
||||||
private final static List<GATKSAMRecord> EMPTY_PILEUP_READS = Collections.emptyList();
|
private final static List<GATKSAMRecord> EMPTY_PILEUP_READS = Collections.emptyList();
|
||||||
private final static List<Integer> EMPTY_PILEUP_OFFSETS = Collections.emptyList();
|
private final static List<Integer> EMPTY_PILEUP_OFFSETS = Collections.emptyList();
|
||||||
|
private final static List<Boolean> EMPTY_DELETION_STATUS = Collections.emptyList();
|
||||||
|
|
||||||
private AlignmentContext createEmptyLocus(GenomeLoc site) {
|
private AlignmentContext createEmptyLocus(GenomeLoc site) {
|
||||||
return new AlignmentContext(site, new ReadBackedPileupImpl(site, EMPTY_PILEUP_READS, EMPTY_PILEUP_OFFSETS));
|
return new AlignmentContext(site, new ReadBackedPileupImpl(site, EMPTY_PILEUP_READS, EMPTY_PILEUP_OFFSETS));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,9 +49,13 @@ import org.broadinstitute.sting.utils.sam.ReadUtils;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
/** Iterator that traverses a SAM File, accumulating information on a per-locus basis */
|
/**
|
||||||
|
* Iterator that traverses a SAM File, accumulating information on a per-locus basis
|
||||||
|
*/
|
||||||
public class LocusIteratorByState extends LocusIterator {
|
public class LocusIteratorByState extends LocusIterator {
|
||||||
/** our log, which we want to capture anything from this class */
|
/**
|
||||||
|
* our log, which we want to capture anything from this class
|
||||||
|
*/
|
||||||
private static Logger logger = Logger.getLogger(LocusIteratorByState.class);
|
private static Logger logger = Logger.getLogger(LocusIteratorByState.class);
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------------------------------------
|
||||||
|
|
@ -92,11 +96,13 @@ public class LocusIteratorByState extends LocusIterator {
|
||||||
boolean generateExtendedEvents = true; // should we generate an additional, special pile for indels between the ref bases?
|
boolean generateExtendedEvents = true; // should we generate an additional, special pile for indels between the ref bases?
|
||||||
// the only purpose of this flag is to shield away a few additional lines of code
|
// the only purpose of this flag is to shield away a few additional lines of code
|
||||||
// when extended piles are not needed, it may not be even worth it...
|
// when extended piles are not needed, it may not be even worth it...
|
||||||
|
|
||||||
byte[] insertedBases = null; // remember full inserted sequence if we are generating piles of extended events (indels)
|
byte[] insertedBases = null; // remember full inserted sequence if we are generating piles of extended events (indels)
|
||||||
int eventLength = -1; // will be set to the length of insertion/deletion if we are generating piles of extended events
|
int eventLength = -1; // will be set to the length of insertion/deletion if we are generating piles of extended events
|
||||||
byte eventDelayedFlag = 0; // will be set to non-0 if there was an event (indel) right before the
|
byte eventDelayedFlag = 0; // will be set to non-0 if there was an event (indel) right before the
|
||||||
// current base on the ref. We use a counter-like variable here since clearing the indel event is
|
// current base on the ref. We use a counter-like variable here since clearing the indel event is
|
||||||
// delayed by one base, so we need to remember how long ago we have seen the actual event
|
// delayed by one base, so we need to remember how long ago we have seen the actual event
|
||||||
|
|
||||||
int eventStart = -1; // where on the read the extended event starts (i.e. the last position on the read prior to the
|
int eventStart = -1; // where on the read the extended event starts (i.e. the last position on the read prior to the
|
||||||
// event, or -1 if alignment starts with an insertion); this one is easy to recompute on the fly,
|
// event, or -1 if alignment starts with an insertion); this one is easy to recompute on the fly,
|
||||||
// we cache it here mainly for convenience
|
// we cache it here mainly for convenience
|
||||||
|
|
@ -111,23 +117,31 @@ public class LocusIteratorByState extends LocusIterator {
|
||||||
//System.out.printf("Creating a SAMRecordState: %s%n", this);
|
//System.out.printf("Creating a SAMRecordState: %s%n", this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SAMRecord getRead() { return read; }
|
public SAMRecord getRead() {
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* What is our current offset in the read's bases that aligns us with the reference genome?
|
* What is our current offset in the read's bases that aligns us with the reference genome?
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public int getReadOffset() { return readOffset; }
|
public int getReadOffset() {
|
||||||
|
return readOffset;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* What is the current offset w.r.t. the alignment state that aligns us to the readOffset?
|
* What is the current offset w.r.t. the alignment state that aligns us to the readOffset?
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public int getGenomeOffset() { return genomeOffset; }
|
public int getGenomeOffset() {
|
||||||
|
return genomeOffset;
|
||||||
|
}
|
||||||
|
|
||||||
public int getGenomePosition() { return read.getAlignmentStart() + getGenomeOffset(); }
|
public int getGenomePosition() {
|
||||||
|
return read.getAlignmentStart() + getGenomeOffset();
|
||||||
|
}
|
||||||
|
|
||||||
public GenomeLoc getLocation(GenomeLocParser genomeLocParser) {
|
public GenomeLoc getLocation(GenomeLocParser genomeLocParser) {
|
||||||
return genomeLocParser.createGenomeLoc(read.getReferenceName(), getGenomePosition());
|
return genomeLocParser.createGenomeLoc(read.getReferenceName(), getGenomePosition());
|
||||||
|
|
@ -137,7 +151,8 @@ public class LocusIteratorByState extends LocusIterator {
|
||||||
return curElement.getOperator();
|
return curElement.getOperator();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns true if we just stepped over insertion/into a deletion prior to the last return from stepForwardOnGenome.
|
/**
|
||||||
|
* Returns true if we just stepped over insertion/into a deletion prior to the last return from stepForwardOnGenome.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
@ -145,11 +160,17 @@ public class LocusIteratorByState extends LocusIterator {
|
||||||
return (eventLength > 0);
|
return (eventLength > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getEventLength() { return eventLength; }
|
public int getEventLength() {
|
||||||
|
return eventLength;
|
||||||
|
}
|
||||||
|
|
||||||
public byte[] getEventBases() { return insertedBases; }
|
public byte[] getEventBases() {
|
||||||
|
return insertedBases;
|
||||||
|
}
|
||||||
|
|
||||||
public int getReadEventStartOffset() { return eventStart; }
|
public int getReadEventStartOffset() {
|
||||||
|
return eventStart;
|
||||||
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
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);
|
||||||
|
|
@ -193,7 +214,6 @@ public class LocusIteratorByState extends LocusIterator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
boolean done = false;
|
boolean done = false;
|
||||||
switch (curElement.getOperator()) {
|
switch (curElement.getOperator()) {
|
||||||
case H: // ignore hard clips
|
case H: // ignore hard clips
|
||||||
|
|
@ -204,7 +224,8 @@ public class LocusIteratorByState extends LocusIterator {
|
||||||
if (generateExtendedEvents) {
|
if (generateExtendedEvents) {
|
||||||
// we see insertions only once, when we step right onto them; the position on the read is scrolled
|
// we see insertions only once, when we step right onto them; the position on the read is scrolled
|
||||||
// past the insertion right after that
|
// past the insertion right after that
|
||||||
if ( eventDelayedFlag > 1 ) throw new UserException.MalformedBAM(read, "Adjacent I/D events in read "+read.getReadName());
|
if (eventDelayedFlag > 1)
|
||||||
|
throw new UserException.MalformedBAM(read, "Adjacent I/D events in read " + read.getReadName());
|
||||||
insertedBases = Arrays.copyOfRange(read.getReadBases(), readOffset + 1, readOffset + 1 + curElement.getLength());
|
insertedBases = Arrays.copyOfRange(read.getReadBases(), readOffset + 1, readOffset + 1 + curElement.getLength());
|
||||||
eventLength = curElement.getLength();
|
eventLength = curElement.getLength();
|
||||||
eventStart = readOffset;
|
eventStart = readOffset;
|
||||||
|
|
@ -220,7 +241,8 @@ public class LocusIteratorByState extends LocusIterator {
|
||||||
if (cigarElementCounter == 1) {
|
if (cigarElementCounter == 1) {
|
||||||
// generate an extended event only if we just stepped into the deletion (i.e. don't
|
// generate an extended event only if we just stepped into the deletion (i.e. don't
|
||||||
// generate the event at every deleted position on the ref, that's what cigarElementCounter==1 is for!)
|
// generate the event at every deleted position on the ref, that's what cigarElementCounter==1 is for!)
|
||||||
if ( eventDelayedFlag > 1 ) throw new UserException.MalformedBAM(read, "Adjacent I/D events in read "+read.getReadName());
|
if (eventDelayedFlag > 1)
|
||||||
|
throw new UserException.MalformedBAM(read, "Adjacent I/D events in read " + read.getReadName());
|
||||||
eventLength = curElement.getLength();
|
eventLength = curElement.getLength();
|
||||||
eventDelayedFlag = 2; // deletion on the ref causes an immediate return, so we have to delay by 1 only
|
eventDelayedFlag = 2; // deletion on the ref causes an immediate return, so we have to delay by 1 only
|
||||||
eventStart = readOffset;
|
eventStart = readOffset;
|
||||||
|
|
@ -241,12 +263,13 @@ public class LocusIteratorByState extends LocusIterator {
|
||||||
genomeOffset++;
|
genomeOffset++;
|
||||||
done = true;
|
done = true;
|
||||||
break;
|
break;
|
||||||
default : throw new IllegalStateException("Case statement didn't deal with cigar op: " + curElement.getOperator());
|
default:
|
||||||
|
throw new IllegalStateException("Case statement didn't deal with cigar op: " + curElement.getOperator());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (generateExtendedEvents) {
|
if (generateExtendedEvents) {
|
||||||
if (eventDelayedFlag > 0 && done) {
|
if (eventDelayedFlag > 0 && done) {
|
||||||
// if we did make a successful step on the ref, decrement delayed flag. If, upon the decrementthe,
|
// if we did make a successful step on the ref, decrement delayed flag. If, upon the decrementing the,
|
||||||
// the flag is 1, we are standing on the reference base right after the indel (so we have to keep it).
|
// the flag is 1, we are standing on the reference base right after the indel (so we have to keep it).
|
||||||
// Otherwise, we are away from the previous indel and have to clear our memories...
|
// Otherwise, we are away from the previous indel and have to clear our memories...
|
||||||
eventDelayedFlag--; // when we notice an indel, we set delayed flag to 2, so now
|
eventDelayedFlag--; // when we notice an indel, we set delayed flag to 2, so now
|
||||||
|
|
@ -369,95 +392,100 @@ public class LocusIteratorByState extends LocusIterator {
|
||||||
int maxDeletionLength = 0;
|
int maxDeletionLength = 0;
|
||||||
|
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
SAMRecordState state = iterator.next();
|
final SAMRecordState state = iterator.next();
|
||||||
if ( state.hadIndel() ) {
|
final GATKSAMRecord read = (GATKSAMRecord) state.getRead(); // the actual read
|
||||||
|
final CigarOperator op = state.getCurrentCigarOperator(); // current cigar operator
|
||||||
|
final int readOffset = state.getReadOffset(); // the base offset on this read
|
||||||
|
final int eventStartOffset = state.getReadEventStartOffset(); // this will be -1 if base is not a deletion, or if base is the first deletion in the event. Otherwise, it will give the last base before the deletion began.
|
||||||
|
final int eventLength = state.getEventLength();
|
||||||
|
|
||||||
|
// if (op != CigarOperator.N) // N's are never added to any pileup
|
||||||
|
// continue;
|
||||||
|
//
|
||||||
|
if (state.hadIndel()) { // this read has an indel associated with the previous position on the ref
|
||||||
size++;
|
size++;
|
||||||
if ( state.getEventBases() == null ) {
|
ExtendedEventPileupElement pileupElement;
|
||||||
|
if (state.getEventBases() == null) { // Deletion event
|
||||||
nDeletions++;
|
nDeletions++;
|
||||||
maxDeletionLength = Math.max(maxDeletionLength, state.getEventLength());
|
maxDeletionLength = Math.max(maxDeletionLength, state.getEventLength());
|
||||||
|
pileupElement = new ExtendedEventPileupElement(read, eventStartOffset, eventLength);
|
||||||
|
}
|
||||||
|
else { // Insertion event
|
||||||
|
nInsertions++;
|
||||||
|
pileupElement = new ExtendedEventPileupElement(read, eventStartOffset, eventLength, state.getEventBases());
|
||||||
}
|
}
|
||||||
else nInsertions++;
|
|
||||||
indelPile.add ( new ExtendedEventPileupElement((GATKSAMRecord) state.getRead(), state.getReadEventStartOffset(), state.getEventLength(), state.getEventBases()) );
|
|
||||||
|
|
||||||
} else {
|
indelPile.add(pileupElement);
|
||||||
// HACK: The readahead mechanism for LocusIteratorByState will effectively read past the current position
|
}
|
||||||
// and add in extra reads that start after this indel. Skip these reads.
|
|
||||||
// My belief at this moment after empirically looking at read->ref alignment is that, in a cigar string
|
|
||||||
// like 1I76M, the first insertion is between alignment start-1 and alignment start, so we shouldn't be
|
|
||||||
// filtering these out.
|
|
||||||
// TODO: UPDATE! Eric tells me that we *might* want reads adjacent to the pileup in the pileup. Strike this block.
|
|
||||||
//if(state.getRead().getAlignmentStart() > loc.getStart())
|
|
||||||
// continue;
|
|
||||||
|
|
||||||
if ( state.getCurrentCigarOperator() != CigarOperator.N ) {
|
// this read has no indel associated with the previous position on the ref. Criteria to include in the pileup are:
|
||||||
// this read has no indel associated with the previous position on the ref;
|
// we only add reads that are not N's
|
||||||
// we count this read in only if it has actual bases, not N span...
|
// we only include deletions to the pileup if the walker requests it
|
||||||
if ( state.getCurrentCigarOperator() != CigarOperator.D || readInfo.includeReadsWithDeletionAtLoci() ) {
|
else if ( (op != CigarOperator.N) && (op != CigarOperator.D || readInfo.includeReadsWithDeletionAtLoci())) {
|
||||||
|
|
||||||
// if cigar operator is D but the read has no extended event reported (that's why we ended
|
|
||||||
// up in this branch), it means that we are currently inside a deletion that started earlier;
|
|
||||||
// we count such reads (with a longer deletion spanning over a deletion at the previous base we are
|
|
||||||
// about to report) only if includeReadsWithDeletionAtLoci is true.
|
|
||||||
size++;
|
size++;
|
||||||
indelPile.add ( new ExtendedEventPileupElement((GATKSAMRecord) state.getRead(), state.getReadOffset()-1, -1) // length=-1 --> noevent
|
indelPile.add(new ExtendedEventPileupElement((GATKSAMRecord) state.getRead(), readOffset));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( state.getRead().getMappingQuality() == 0 ) {
|
if (state.getRead().getMappingQuality() == 0)
|
||||||
nMQ0Reads++;
|
nMQ0Reads++;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if( indelPile.size() != 0 ) fullExtendedEventPileup.put(sample,new ReadBackedExtendedEventPileupImpl(loc,indelPile,size,maxDeletionLength,nInsertions,nDeletions,nMQ0Reads));
|
if (indelPile.size() != 0)
|
||||||
|
fullExtendedEventPileup.put(sample, new ReadBackedExtendedEventPileupImpl(loc, indelPile, size, maxDeletionLength, nInsertions, nDeletions, nMQ0Reads));
|
||||||
}
|
}
|
||||||
hasExtendedEvents = false; // we are done with extended events prior to current ref base
|
hasExtendedEvents = false; // we are done with extended events prior to current ref base
|
||||||
// System.out.println("Indel(s) at "+loc);
|
|
||||||
// for ( ExtendedEventPileupElement pe : indelPile ) { if ( pe.isIndel() ) System.out.println(" "+pe.toString()); }
|
|
||||||
nextAlignmentContext = new AlignmentContext(loc, new ReadBackedExtendedEventPileupImpl(loc, fullExtendedEventPileup), hasBeenSampled);
|
nextAlignmentContext = new AlignmentContext(loc, new ReadBackedExtendedEventPileupImpl(loc, fullExtendedEventPileup), hasBeenSampled);
|
||||||
} else {
|
}
|
||||||
|
else { // this is a regular event pileup (not extended)
|
||||||
GenomeLoc location = getLocation();
|
GenomeLoc location = getLocation();
|
||||||
Map<String, ReadBackedPileupImpl> fullPileup = new HashMap<String, ReadBackedPileupImpl>();
|
Map<String, ReadBackedPileupImpl> fullPileup = new HashMap<String, ReadBackedPileupImpl>();
|
||||||
|
|
||||||
boolean hasBeenSampled = false;
|
boolean hasBeenSampled = false;
|
||||||
for (final String sample : samples) {
|
for (final String sample : samples) {
|
||||||
Iterator<SAMRecordState> iterator = readStates.iterator(sample);
|
Iterator<SAMRecordState> iterator = readStates.iterator(sample);
|
||||||
List<PileupElement> pile = new ArrayList<PileupElement>(readStates.size(sample));
|
List<PileupElement> pile = new ArrayList<PileupElement>(readStates.size(sample));
|
||||||
hasBeenSampled |= location.getStart() <= readStates.getDownsamplingExtent(sample);
|
hasBeenSampled |= location.getStart() <= readStates.getDownsamplingExtent(sample);
|
||||||
|
|
||||||
size = 0;
|
size = 0; // number of elements in this sample's pileup
|
||||||
nDeletions = 0;
|
nDeletions = 0; // number of deletions in this sample's pileup
|
||||||
nMQ0Reads = 0;
|
nMQ0Reads = 0; // number of MQ0 reads in this sample's pileup (warning: current implementation includes N bases that are MQ0)
|
||||||
|
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
SAMRecordState state = iterator.next();
|
final SAMRecordState state = iterator.next(); // state object with the read/offset information
|
||||||
if ( state.getCurrentCigarOperator() != CigarOperator.D && state.getCurrentCigarOperator() != CigarOperator.N ) {
|
final GATKSAMRecord read = (GATKSAMRecord) state.getRead(); // the actual read
|
||||||
if ( filterBaseInRead((GATKSAMRecord) state.getRead(), location.getStart()) ) {
|
final CigarOperator op = state.getCurrentCigarOperator(); // current cigar operator
|
||||||
//discarded_bases++;
|
final int readOffset = state.getReadOffset(); // the base offset on this read
|
||||||
//printStatus("Adaptor bases", discarded_adaptor_bases);
|
final int eventStartOffset = state.getReadEventStartOffset(); // this will be -1 if base is not a deletion, or if base is the first deletion in the event. Otherwise, it will give the last base before the deletion began.
|
||||||
|
|
||||||
|
if (op == CigarOperator.N) // N's are never added to any pileup
|
||||||
continue;
|
continue;
|
||||||
} else {
|
|
||||||
//observed_bases++;
|
if (read.getMappingQuality() == 0)
|
||||||
pile.add(new PileupElement((GATKSAMRecord) state.getRead(), state.getReadOffset()));
|
nMQ0Reads++;
|
||||||
|
|
||||||
|
if (op == CigarOperator.D) {
|
||||||
|
if (readInfo.includeReadsWithDeletionAtLoci()) { // only add deletions to the pileup if we are authorized to do so
|
||||||
|
int leftAlignedStart = (eventStartOffset < 0) ? readOffset : eventStartOffset;
|
||||||
|
pile.add(new PileupElement(read, leftAlignedStart, true));
|
||||||
size++;
|
size++;
|
||||||
}
|
|
||||||
} else if ( readInfo.includeReadsWithDeletionAtLoci() && state.getCurrentCigarOperator() != CigarOperator.N ) {
|
|
||||||
size++;
|
|
||||||
pile.add(new PileupElement((GATKSAMRecord) state.getRead(), -1));
|
|
||||||
nDeletions++;
|
nDeletions++;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
if ( state.getRead().getMappingQuality() == 0 ) {
|
if (!filterBaseInRead(read, location.getStart())) {
|
||||||
nMQ0Reads++;
|
pile.add(new PileupElement(read, readOffset, false));
|
||||||
|
size++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( pile.size() != 0 )
|
if (pile.size() != 0) // if this pileup added at least one base, add it to the full pileup
|
||||||
fullPileup.put(sample, new ReadBackedPileupImpl(location, pile, size, nDeletions, nMQ0Reads));
|
fullPileup.put(sample, new ReadBackedPileupImpl(location, pile, size, nDeletions, nMQ0Reads));
|
||||||
}
|
}
|
||||||
|
|
||||||
updateReadStates(); // critical - must be called after we get the current state offsets and location
|
updateReadStates(); // critical - must be called after we get the current state offsets and location
|
||||||
// if we got reads with non-D/N over the current position, we are done
|
if (!fullPileup.isEmpty()) // if we got reads with non-D/N over the current position, we are done
|
||||||
if ( !fullPileup.isEmpty() ) nextAlignmentContext = new AlignmentContext(location, new ReadBackedPileupImpl(location,fullPileup),hasBeenSampled);
|
nextAlignmentContext = new AlignmentContext(location, new ReadBackedPileupImpl(location, fullPileup), hasBeenSampled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -490,15 +518,13 @@ public class LocusIteratorByState extends LocusIterator {
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
SAMRecordState state = it.next();
|
SAMRecordState state = it.next();
|
||||||
CigarOperator op = state.stepForwardOnGenome();
|
CigarOperator op = state.stepForwardOnGenome();
|
||||||
if ( state.hadIndel() && readInfo.generateExtendedEvents() ) hasExtendedEvents = true;
|
if (state.hadIndel() && readInfo.generateExtendedEvents())
|
||||||
else {
|
hasExtendedEvents = true;
|
||||||
|
else if (op == null) {
|
||||||
// we discard the read only when we are past its end AND indel at the end of the read (if any) was
|
// we discard the read only when we are past its end AND indel at the end of the read (if any) was
|
||||||
// already processed. Keeping the read state that retunred null upon stepForwardOnGenome() is safe
|
// already processed. Keeping the read state that retunred null upon stepForwardOnGenome() is safe
|
||||||
// as the next call to stepForwardOnGenome() will return null again AND will clear hadIndel() flag.
|
// as the next call to stepForwardOnGenome() will return null again AND will clear hadIndel() flag.
|
||||||
if ( op == null ) { // we've stepped off the end of the object
|
it.remove(); // we've stepped off the end of the object
|
||||||
//if (DEBUG) logger.debug(String.format(" removing read %s at %d", state.getRead().getReadName(), state.getRead().getAlignmentStart()));
|
|
||||||
it.remove();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -541,6 +567,7 @@ public class LocusIteratorByState extends LocusIterator {
|
||||||
/**
|
/**
|
||||||
* Returns a iterator over all the reads associated with the given sample. Note that remove() is implemented
|
* Returns a iterator over all the reads associated with the given sample. Note that remove() is implemented
|
||||||
* for this iterator; if present, total read states will be decremented.
|
* for this iterator; if present, total read states will be decremented.
|
||||||
|
*
|
||||||
* @param sample The sample.
|
* @param sample The sample.
|
||||||
* @return Iterator over the reads associated with that sample.
|
* @return Iterator over the reads associated with that sample.
|
||||||
*/
|
*/
|
||||||
|
|
@ -569,6 +596,7 @@ public class LocusIteratorByState extends LocusIterator {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the total number of reads in the manager across all samples.
|
* Retrieves the total number of reads in the manager across all samples.
|
||||||
|
*
|
||||||
* @return Total number of reads over all samples.
|
* @return Total number of reads over all samples.
|
||||||
*/
|
*/
|
||||||
public int size() {
|
public int size() {
|
||||||
|
|
@ -577,6 +605,7 @@ public class LocusIteratorByState extends LocusIterator {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the total number of reads in the manager in the given sample.
|
* Retrieves the total number of reads in the manager in the given sample.
|
||||||
|
*
|
||||||
* @param sample The sample.
|
* @param sample The sample.
|
||||||
* @return Total number of reads in the given sample.
|
* @return Total number of reads in the given sample.
|
||||||
*/
|
*/
|
||||||
|
|
@ -587,6 +616,7 @@ public class LocusIteratorByState extends LocusIterator {
|
||||||
/**
|
/**
|
||||||
* The extent of downsampling; basically, the furthest base out which has 'fallen
|
* The extent of downsampling; basically, the furthest base out which has 'fallen
|
||||||
* victim' to the downsampler.
|
* victim' to the downsampler.
|
||||||
|
*
|
||||||
* @param sample Sample, downsampled independently.
|
* @param sample Sample, downsampled independently.
|
||||||
* @return Integer stop of the furthest undownsampled region.
|
* @return Integer stop of the furthest undownsampled region.
|
||||||
*/
|
*/
|
||||||
|
|
@ -617,8 +647,7 @@ public class LocusIteratorByState extends LocusIterator {
|
||||||
while (iterator.hasNext() && iterator.peek().getReferenceIndex() == firstContigIndex && iterator.peek().getAlignmentStart() == firstAlignmentStart) {
|
while (iterator.hasNext() && iterator.peek().getReferenceIndex() == firstContigIndex && iterator.peek().getAlignmentStart() == firstAlignmentStart) {
|
||||||
samplePartitioner.submitRead(iterator.next());
|
samplePartitioner.submitRead(iterator.next());
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// Fast fail in the case that the read is past the current position.
|
// Fast fail in the case that the read is past the current position.
|
||||||
if (readIsPastCurrentPosition(iterator.peek()))
|
if (readIsPastCurrentPosition(iterator.peek()))
|
||||||
return;
|
return;
|
||||||
|
|
@ -642,8 +671,7 @@ public class LocusIteratorByState extends LocusIterator {
|
||||||
long readLimit = aggregator.getNumReadsSeen();
|
long readLimit = aggregator.getNumReadsSeen();
|
||||||
addReadsToSample(statesBySample, newReads, readLimit);
|
addReadsToSample(statesBySample, newReads, readLimit);
|
||||||
statesBySample.specifyNewDownsamplingExtent(downsamplingExtent);
|
statesBySample.specifyNewDownsamplingExtent(downsamplingExtent);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
int[] counts = statesBySample.getCountsPerAlignmentStart();
|
int[] counts = statesBySample.getCountsPerAlignmentStart();
|
||||||
int[] updatedCounts = new int[counts.length];
|
int[] updatedCounts = new int[counts.length];
|
||||||
System.arraycopy(counts, 0, updatedCounts, 0, counts.length);
|
System.arraycopy(counts, 0, updatedCounts, 0, counts.length);
|
||||||
|
|
@ -688,6 +716,7 @@ public class LocusIteratorByState extends LocusIterator {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add reads with the given sample name to the given hanger entry.
|
* Add reads with the given sample name to the given hanger entry.
|
||||||
|
*
|
||||||
* @param readStates The list of read states to add this collection of reads.
|
* @param readStates The list of read states to add this collection of reads.
|
||||||
* @param reads Reads to add. Selected reads will be pulled from this source.
|
* @param reads Reads to add. Selected reads will be pulled from this source.
|
||||||
* @param maxReads Maximum number of reads to add.
|
* @param maxReads Maximum number of reads to add.
|
||||||
|
|
@ -704,7 +733,8 @@ public class LocusIteratorByState extends LocusIterator {
|
||||||
state.stepForwardOnGenome();
|
state.stepForwardOnGenome();
|
||||||
newReadStates.add(state);
|
newReadStates.add(state);
|
||||||
// TODO: What if we downsample the extended events away?
|
// TODO: What if we downsample the extended events away?
|
||||||
if (state.hadIndel()) hasExtendedEvents = true;
|
if (state.hadIndel())
|
||||||
|
hasExtendedEvents = true;
|
||||||
readCount++;
|
readCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -775,6 +805,7 @@ public class LocusIteratorByState extends LocusIterator {
|
||||||
/**
|
/**
|
||||||
* Purge the given elements from the bitset. If an element in the bitset is true, purge
|
* Purge the given elements from the bitset. If an element in the bitset is true, purge
|
||||||
* the corresponding read state.
|
* the corresponding read state.
|
||||||
|
*
|
||||||
* @param elements bits from the set to purge.
|
* @param elements bits from the set to purge.
|
||||||
* @return the extent of the final downsampled read.
|
* @return the extent of the final downsampled read.
|
||||||
*/
|
*/
|
||||||
|
|
@ -849,12 +880,14 @@ public class LocusIteratorByState extends LocusIterator {
|
||||||
interface ReadSelector {
|
interface ReadSelector {
|
||||||
/**
|
/**
|
||||||
* All previous selectors in the chain have allowed this read. Submit it to this selector for consideration.
|
* All previous selectors in the chain have allowed this read. Submit it to this selector for consideration.
|
||||||
|
*
|
||||||
* @param read the read to evaluate.
|
* @param read the read to evaluate.
|
||||||
*/
|
*/
|
||||||
public void submitRead(SAMRecord read);
|
public void submitRead(SAMRecord read);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A previous selector has deemed this read unfit. Notify this selector so that this selector's counts are valid.
|
* A previous selector has deemed this read unfit. Notify this selector so that this selector's counts are valid.
|
||||||
|
*
|
||||||
* @param read the read previously rejected.
|
* @param read the read previously rejected.
|
||||||
*/
|
*/
|
||||||
public void notifyReadRejected(SAMRecord read);
|
public void notifyReadRejected(SAMRecord read);
|
||||||
|
|
@ -866,12 +899,14 @@ interface ReadSelector {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the number of reads seen by this selector so far.
|
* Retrieve the number of reads seen by this selector so far.
|
||||||
|
*
|
||||||
* @return number of reads seen.
|
* @return number of reads seen.
|
||||||
*/
|
*/
|
||||||
public long getNumReadsSeen();
|
public long getNumReadsSeen();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the number of reads accepted by this selector so far.
|
* Return the number of reads accepted by this selector so far.
|
||||||
|
*
|
||||||
* @return number of reads selected.
|
* @return number of reads selected.
|
||||||
*/
|
*/
|
||||||
public long getNumReadsSelected();
|
public long getNumReadsSelected();
|
||||||
|
|
@ -880,12 +915,14 @@ interface ReadSelector {
|
||||||
* Gets the locus at which the last of the downsampled reads selected by this selector ends. The value returned will be the
|
* Gets the locus at which the last of the downsampled reads selected by this selector ends. The value returned will be the
|
||||||
* last aligned position from this selection to which a downsampled read aligns -- in other words, if a read is thrown out at
|
* last aligned position from this selection to which a downsampled read aligns -- in other words, if a read is thrown out at
|
||||||
* position 3 whose cigar string is 76M, the value of this parameter will be 78.
|
* position 3 whose cigar string is 76M, the value of this parameter will be 78.
|
||||||
|
*
|
||||||
* @return If any read has been downsampled, this will return the last aligned base of the longest alignment. Else, 0.
|
* @return If any read has been downsampled, this will return the last aligned base of the longest alignment. Else, 0.
|
||||||
*/
|
*/
|
||||||
public int getDownsamplingExtent();
|
public int getDownsamplingExtent();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the reads selected by this selector.
|
* Get the reads selected by this selector.
|
||||||
|
*
|
||||||
* @return collection of reads selected by this selector.
|
* @return collection of reads selected by this selector.
|
||||||
*/
|
*/
|
||||||
public Collection<SAMRecord> getSelectedReads();
|
public Collection<SAMRecord> getSelectedReads();
|
||||||
|
|
|
||||||
|
|
@ -25,13 +25,13 @@ public class BaseQualityRankSumTest extends RankSumTest {
|
||||||
protected void fillQualsFromPileup(byte ref, byte alt, ReadBackedPileup pileup, List<Double> refQuals, List<Double> altQuals) {
|
protected void fillQualsFromPileup(byte ref, byte alt, ReadBackedPileup pileup, List<Double> refQuals, List<Double> altQuals) {
|
||||||
for ( final PileupElement p : pileup ) {
|
for ( final PileupElement p : pileup ) {
|
||||||
if( isUsableBase(p) ) {
|
if( isUsableBase(p) ) {
|
||||||
if ( p.getBase() == ref ) {
|
if ( p.getBase() == ref )
|
||||||
refQuals.add((double)p.getQual());
|
refQuals.add((double)p.getQual());
|
||||||
} else if ( p.getBase() == alt ) {
|
else if ( p.getBase() == alt )
|
||||||
altQuals.add((double)p.getQual());
|
altQuals.add((double)p.getQual());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
protected void fillIndelQualsFromPileup(ReadBackedPileup pileup, List<Double> refQuals, List<Double> altQuals) {
|
protected void fillIndelQualsFromPileup(ReadBackedPileup pileup, List<Double> refQuals, List<Double> altQuals) {
|
||||||
// equivalent is whether indel likelihoods for reads corresponding to ref allele are more likely than reads corresponding to alt allele ?
|
// equivalent is whether indel likelihoods for reads corresponding to ref allele are more likely than reads corresponding to alt allele ?
|
||||||
|
|
@ -57,8 +57,6 @@ public class BaseQualityRankSumTest extends RankSumTest {
|
||||||
refQuals.add(-10.0*refLikelihood);
|
refQuals.add(-10.0*refLikelihood);
|
||||||
else if (altLikelihood > refLikelihood + INDEL_LIKELIHOOD_THRESH)
|
else if (altLikelihood > refLikelihood + INDEL_LIKELIHOOD_THRESH)
|
||||||
altQuals.add(-10.0*altLikelihood);
|
altQuals.add(-10.0*altLikelihood);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -205,7 +205,7 @@ public class FisherStrand extends InfoFieldAnnotation implements StandardAnnotat
|
||||||
|
|
||||||
for ( Map.Entry<String, AlignmentContext> sample : stratifiedContexts.entrySet() ) {
|
for ( Map.Entry<String, AlignmentContext> sample : stratifiedContexts.entrySet() ) {
|
||||||
for (PileupElement p : sample.getValue().getBasePileup()) {
|
for (PileupElement p : sample.getValue().getBasePileup()) {
|
||||||
if ( p.isDeletion() || p.isReducedRead() ) // ignore deletions and reduced reads
|
if ( p.isDeletion() || p.getRead().isReducedRead() ) // ignore deletions and reduced reads
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ( p.getRead().getMappingQuality() < 20 || p.getQual() < 20 )
|
if ( p.getRead().getMappingQuality() < 20 || p.getQual() < 20 )
|
||||||
|
|
@ -258,7 +258,7 @@ public class FisherStrand extends InfoFieldAnnotation implements StandardAnnotat
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (final PileupElement p: pileup) {
|
for (final PileupElement p: pileup) {
|
||||||
if ( p.isReducedRead() ) // ignore reduced reads
|
if ( p.getRead().isReducedRead() ) // ignore reduced reads
|
||||||
continue;
|
continue;
|
||||||
if ( p.getRead().getMappingQuality() < 20)
|
if ( p.getRead().getMappingQuality() < 20)
|
||||||
continue;
|
continue;
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@
|
||||||
|
|
||||||
package org.broadinstitute.sting.gatk.walkers.annotator;
|
package org.broadinstitute.sting.gatk.walkers.annotator;
|
||||||
|
|
||||||
import net.sf.samtools.SAMRecord;
|
|
||||||
import org.broadinstitute.sting.gatk.contexts.AlignmentContext;
|
import org.broadinstitute.sting.gatk.contexts.AlignmentContext;
|
||||||
import org.broadinstitute.sting.gatk.contexts.AlignmentContextUtils;
|
import org.broadinstitute.sting.gatk.contexts.AlignmentContextUtils;
|
||||||
import org.broadinstitute.sting.gatk.contexts.ReferenceContext;
|
import org.broadinstitute.sting.gatk.contexts.ReferenceContext;
|
||||||
|
|
@ -43,6 +42,7 @@ import org.broadinstitute.sting.utils.exceptions.ReviewedStingException;
|
||||||
import org.broadinstitute.sting.utils.pileup.PileupElement;
|
import org.broadinstitute.sting.utils.pileup.PileupElement;
|
||||||
import org.broadinstitute.sting.utils.pileup.ReadBackedPileup;
|
import org.broadinstitute.sting.utils.pileup.ReadBackedPileup;
|
||||||
import org.broadinstitute.sting.utils.sam.AlignmentUtils;
|
import org.broadinstitute.sting.utils.sam.AlignmentUtils;
|
||||||
|
import org.broadinstitute.sting.utils.sam.GATKSAMRecord;
|
||||||
import org.broadinstitute.sting.utils.variantcontext.Allele;
|
import org.broadinstitute.sting.utils.variantcontext.Allele;
|
||||||
import org.broadinstitute.sting.utils.variantcontext.Genotype;
|
import org.broadinstitute.sting.utils.variantcontext.Genotype;
|
||||||
import org.broadinstitute.sting.utils.variantcontext.VariantContext;
|
import org.broadinstitute.sting.utils.variantcontext.VariantContext;
|
||||||
|
|
@ -108,8 +108,7 @@ public class HaplotypeScore extends InfoFieldAnnotation implements StandardAnnot
|
||||||
if (d == null)
|
if (d == null)
|
||||||
return null;
|
return null;
|
||||||
scoreRA.add(d); // Taking the simple average of all sample's score since the score can be negative and the RMS doesn't make sense
|
scoreRA.add(d); // Taking the simple average of all sample's score since the score can be negative and the RMS doesn't make sense
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -161,8 +160,7 @@ public class HaplotypeScore extends InfoFieldAnnotation implements StandardAnnot
|
||||||
consensusHaplotypeQueue.add(consensusHaplotype);
|
consensusHaplotypeQueue.add(consensusHaplotype);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
lastCheckedHaplotype = haplotypeFromList;
|
lastCheckedHaplotype = haplotypeFromList;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -185,7 +183,9 @@ public class HaplotypeScore extends InfoFieldAnnotation implements StandardAnnot
|
||||||
|
|
||||||
for (int k = 1; k < haplotypesToCompute; k++) {
|
for (int k = 1; k < haplotypesToCompute; k++) {
|
||||||
Haplotype haplotype2 = consensusHaplotypeQueue.poll();
|
Haplotype haplotype2 = consensusHaplotypeQueue.poll();
|
||||||
if(haplotype2 == null ) { haplotype2 = haplotype1; } // Sometimes only the reference haplotype can be found
|
if (haplotype2 == null) {
|
||||||
|
haplotype2 = haplotype1;
|
||||||
|
} // Sometimes only the reference haplotype can be found
|
||||||
hlist.add(new Haplotype(haplotype2.getBases(), 20));
|
hlist.add(new Haplotype(haplotype2.getBases(), 20));
|
||||||
}
|
}
|
||||||
return hlist;
|
return hlist;
|
||||||
|
|
@ -194,7 +194,7 @@ public class HaplotypeScore extends InfoFieldAnnotation implements StandardAnnot
|
||||||
}
|
}
|
||||||
|
|
||||||
private Haplotype getHaplotypeFromRead(final PileupElement p, final int contextSize, final int locus) {
|
private Haplotype getHaplotypeFromRead(final PileupElement p, final int contextSize, final int locus) {
|
||||||
final SAMRecord read = p.getRead();
|
final GATKSAMRecord read = p.getRead();
|
||||||
int readOffsetFromPileup = p.getOffset();
|
int readOffsetFromPileup = p.getOffset();
|
||||||
|
|
||||||
final byte[] haplotypeBases = new byte[contextSize];
|
final byte[] haplotypeBases = new byte[contextSize];
|
||||||
|
|
@ -203,11 +203,11 @@ public class HaplotypeScore extends InfoFieldAnnotation implements StandardAnnot
|
||||||
Arrays.fill(baseQualities, 0.0);
|
Arrays.fill(baseQualities, 0.0);
|
||||||
|
|
||||||
byte[] readBases = read.getReadBases();
|
byte[] readBases = read.getReadBases();
|
||||||
readBases = AlignmentUtils.readToAlignmentByteArray(p.getRead().getCigar(), readBases); // Adjust the read bases based on the Cigar string
|
readBases = AlignmentUtils.readToAlignmentByteArray(read.getCigar(), readBases); // Adjust the read bases based on the Cigar string
|
||||||
byte[] readQuals = read.getBaseQualities();
|
byte[] readQuals = read.getBaseQualities();
|
||||||
readQuals = AlignmentUtils.readToAlignmentByteArray(p.getRead().getCigar(), readQuals); // Shift the location of the qual scores based on the Cigar string
|
readQuals = AlignmentUtils.readToAlignmentByteArray(read.getCigar(), readQuals); // Shift the location of the qual scores based on the Cigar string
|
||||||
|
|
||||||
readOffsetFromPileup = AlignmentUtils.calcAlignmentByteArrayOffset(p.getRead().getCigar(), readOffsetFromPileup, p.getRead().getAlignmentStart(), locus);
|
readOffsetFromPileup = AlignmentUtils.calcAlignmentByteArrayOffset(read.getCigar(), p, read.getAlignmentStart(), locus);
|
||||||
final int baseOffsetStart = readOffsetFromPileup - (contextSize - 1) / 2;
|
final int baseOffsetStart = readOffsetFromPileup - (contextSize - 1) / 2;
|
||||||
|
|
||||||
for (int i = 0; i < contextSize; i++) {
|
for (int i = 0; i < contextSize; i++) {
|
||||||
|
|
@ -218,10 +218,17 @@ public class HaplotypeScore extends InfoFieldAnnotation implements StandardAnnot
|
||||||
if (baseOffset >= readBases.length) {
|
if (baseOffset >= readBases.length) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if( readQuals[baseOffset] == PileupElement.DELETION_BASE) { readQuals[baseOffset] = PileupElement.DELETION_QUAL; }
|
if (readQuals[baseOffset] == PileupElement.DELETION_BASE) {
|
||||||
if( !BaseUtils.isRegularBase(readBases[baseOffset]) ) { readBases[baseOffset] = (byte)REGEXP_WILDCARD; readQuals[baseOffset] = (byte) 0; } // N's shouldn't be treated as distinct bases
|
readQuals[baseOffset] = PileupElement.DELETION_QUAL;
|
||||||
|
}
|
||||||
|
if (!BaseUtils.isRegularBase(readBases[baseOffset])) {
|
||||||
|
readBases[baseOffset] = (byte) REGEXP_WILDCARD;
|
||||||
|
readQuals[baseOffset] = (byte) 0;
|
||||||
|
} // N's shouldn't be treated as distinct bases
|
||||||
readQuals[baseOffset] = (byte) Math.min((int) readQuals[baseOffset], p.getMappingQual());
|
readQuals[baseOffset] = (byte) Math.min((int) readQuals[baseOffset], p.getMappingQual());
|
||||||
if( ((int)readQuals[baseOffset]) < 5 ) { readQuals[baseOffset] = (byte) 0; } // quals less than 5 are used as codes and don't have actual probabilistic meaning behind them
|
if (((int) readQuals[baseOffset]) < 5) {
|
||||||
|
readQuals[baseOffset] = (byte) 0;
|
||||||
|
} // quals less than 5 are used as codes and don't have actual probabilistic meaning behind them
|
||||||
haplotypeBases[i] = readBases[baseOffset];
|
haplotypeBases[i] = readBases[baseOffset];
|
||||||
baseQualities[i] = (double) readQuals[baseOffset];
|
baseQualities[i] = (double) readQuals[baseOffset];
|
||||||
}
|
}
|
||||||
|
|
@ -257,12 +264,10 @@ public class HaplotypeScore extends InfoFieldAnnotation implements StandardAnnot
|
||||||
if ((chA == wc) && (chB == wc)) {
|
if ((chA == wc) && (chB == wc)) {
|
||||||
consensusChars[i] = wc;
|
consensusChars[i] = wc;
|
||||||
consensusQuals[i] = 0.0;
|
consensusQuals[i] = 0.0;
|
||||||
}
|
} else if ((chA == wc)) {
|
||||||
else if ((chA == wc)) {
|
|
||||||
consensusChars[i] = chB;
|
consensusChars[i] = chB;
|
||||||
consensusQuals[i] = qualsB[i];
|
consensusQuals[i] = qualsB[i];
|
||||||
}
|
} else if ((chB == wc)) {
|
||||||
else if ((chB == wc)){
|
|
||||||
consensusChars[i] = chA;
|
consensusChars[i] = chA;
|
||||||
consensusQuals[i] = qualsA[i];
|
consensusQuals[i] = qualsA[i];
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -287,7 +292,9 @@ public class HaplotypeScore extends InfoFieldAnnotation implements StandardAnnot
|
||||||
final Haplotype haplotype = haplotypes.get(i);
|
final Haplotype haplotype = haplotypes.get(i);
|
||||||
final double score = scoreReadAgainstHaplotype(p, contextSize, haplotype, locus);
|
final double score = scoreReadAgainstHaplotype(p, contextSize, haplotype, locus);
|
||||||
scores[i] = score;
|
scores[i] = score;
|
||||||
if ( DEBUG ) { System.out.printf(" vs. haplotype %d = %f%n", i, score); }
|
if (DEBUG) {
|
||||||
|
System.out.printf(" vs. haplotype %d = %f%n", i, score);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
haplotypeScores.add(scores);
|
haplotypeScores.add(scores);
|
||||||
}
|
}
|
||||||
|
|
@ -315,14 +322,14 @@ public class HaplotypeScore extends InfoFieldAnnotation implements StandardAnnot
|
||||||
// the chance that it is actually a mismatch is 1 - e, since any of the other 3 options would be a mismatch.
|
// the chance that it is actually a mismatch is 1 - e, since any of the other 3 options would be a mismatch.
|
||||||
// so the probability-weighted mismatch rate is sum_i ( matched ? e_i / 3 : 1 - e_i ) for i = 1 ... n
|
// so the probability-weighted mismatch rate is sum_i ( matched ? e_i / 3 : 1 - e_i ) for i = 1 ... n
|
||||||
final byte[] haplotypeBases = haplotype.getBases();
|
final byte[] haplotypeBases = haplotype.getBases();
|
||||||
final SAMRecord read = p.getRead();
|
final GATKSAMRecord read = p.getRead();
|
||||||
byte[] readBases = read.getReadBases();
|
byte[] readBases = read.getReadBases();
|
||||||
|
|
||||||
readBases = AlignmentUtils.readToAlignmentByteArray(p.getRead().getCigar(), readBases); // Adjust the read bases based on the Cigar string
|
readBases = AlignmentUtils.readToAlignmentByteArray(p.getRead().getCigar(), readBases); // Adjust the read bases based on the Cigar string
|
||||||
byte[] readQuals = read.getBaseQualities();
|
byte[] readQuals = read.getBaseQualities();
|
||||||
readQuals = AlignmentUtils.readToAlignmentByteArray(p.getRead().getCigar(), readQuals); // Shift the location of the qual scores based on the Cigar string
|
readQuals = AlignmentUtils.readToAlignmentByteArray(p.getRead().getCigar(), readQuals); // Shift the location of the qual scores based on the Cigar string
|
||||||
int readOffsetFromPileup = p.getOffset();
|
int readOffsetFromPileup = p.getOffset();
|
||||||
readOffsetFromPileup = AlignmentUtils.calcAlignmentByteArrayOffset(p.getRead().getCigar(), readOffsetFromPileup, p.getRead().getAlignmentStart(), locus);
|
readOffsetFromPileup = AlignmentUtils.calcAlignmentByteArrayOffset(p.getRead().getCigar(), p, read.getAlignmentStart(), locus);
|
||||||
final int baseOffsetStart = readOffsetFromPileup - (contextSize - 1) / 2;
|
final int baseOffsetStart = readOffsetFromPileup - (contextSize - 1) / 2;
|
||||||
|
|
||||||
for (int i = 0; i < contextSize; i++) {
|
for (int i = 0; i < contextSize; i++) {
|
||||||
|
|
@ -339,7 +346,9 @@ public class HaplotypeScore extends InfoFieldAnnotation implements StandardAnnot
|
||||||
|
|
||||||
final boolean matched = (readBase == haplotypeBase || haplotypeBase == (byte) REGEXP_WILDCARD);
|
final boolean matched = (readBase == haplotypeBase || haplotypeBase == (byte) REGEXP_WILDCARD);
|
||||||
byte qual = readQuals[baseOffset];
|
byte qual = readQuals[baseOffset];
|
||||||
if( qual == PileupElement.DELETION_BASE ) { qual = PileupElement.DELETION_QUAL; } // calcAlignmentByteArrayOffset fills the readQuals array with DELETION_BASE at deletions
|
if (qual == PileupElement.DELETION_BASE) {
|
||||||
|
qual = PileupElement.DELETION_QUAL;
|
||||||
|
} // calcAlignmentByteArrayOffset fills the readQuals array with DELETION_BASE at deletions
|
||||||
qual = (byte) Math.min((int) qual, p.getMappingQual());
|
qual = (byte) Math.min((int) qual, p.getMappingQual());
|
||||||
if (((int) qual) >= 5) { // quals less than 5 are used as codes and don't have actual probabilistic meaning behind them
|
if (((int) qual) >= 5) { // quals less than 5 are used as codes and don't have actual probabilistic meaning behind them
|
||||||
final double e = QualityUtils.qualToErrorProb(qual);
|
final double e = QualityUtils.qualToErrorProb(qual);
|
||||||
|
|
@ -355,7 +364,6 @@ public class HaplotypeScore extends InfoFieldAnnotation implements StandardAnnot
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private Double scoreIndelsAgainstHaplotypes(final ReadBackedPileup pileup) {
|
private Double scoreIndelsAgainstHaplotypes(final ReadBackedPileup pileup) {
|
||||||
final ArrayList<double[]> haplotypeScores = new ArrayList<double[]>();
|
final ArrayList<double[]> haplotypeScores = new ArrayList<double[]>();
|
||||||
|
|
||||||
|
|
@ -374,7 +382,9 @@ public class HaplotypeScore extends InfoFieldAnnotation implements StandardAnnot
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (Allele a : el.keySet()) {
|
for (Allele a : el.keySet()) {
|
||||||
scores[i++] = -el.get(a);
|
scores[i++] = -el.get(a);
|
||||||
if ( DEBUG ) { System.out.printf(" vs. haplotype %d = %f%n", i-1, scores[i-1]); }
|
if (DEBUG) {
|
||||||
|
System.out.printf(" vs. haplotype %d = %f%n", i - 1, scores[i - 1]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
haplotypeScores.add(scores);
|
haplotypeScores.add(scores);
|
||||||
|
|
@ -392,6 +402,11 @@ public class HaplotypeScore extends InfoFieldAnnotation implements StandardAnnot
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public List<String> getKeyNames() { return Arrays.asList("HaplotypeScore"); }
|
public List<String> getKeyNames() {
|
||||||
public List<VCFInfoHeaderLine> getDescriptions() { return Arrays.asList(new VCFInfoHeaderLine("HaplotypeScore", 1, VCFHeaderLineType.Float, "Consistency of the site with at most two segregating haplotypes")); }
|
return Arrays.asList("HaplotypeScore");
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<VCFInfoHeaderLine> getDescriptions() {
|
||||||
|
return Arrays.asList(new VCFInfoHeaderLine("HaplotypeScore", 1, VCFHeaderLineType.Float, "Consistency of the site with at most two segregating haplotypes"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,8 +50,7 @@ public abstract class RankSumTest extends InfoFieldAnnotation implements Standar
|
||||||
}
|
}
|
||||||
fillQualsFromPileup(ref.getBase(), vc.getAlternateAllele(0).getBases()[0], context.getBasePileup(), refQuals, altQuals);
|
fillQualsFromPileup(ref.getBase(), vc.getAlternateAllele(0).getBases()[0], context.getBasePileup(), refQuals, altQuals);
|
||||||
}
|
}
|
||||||
}
|
} else if (vc.isIndel() || vc.isMixed()) {
|
||||||
else if (vc.isIndel() || vc.isMixed()) {
|
|
||||||
|
|
||||||
for (final Genotype genotype : genotypes.iterateInSampleNameOrder()) {
|
for (final Genotype genotype : genotypes.iterateInSampleNameOrder()) {
|
||||||
final AlignmentContext context = stratifiedContexts.get(genotype.getSampleName());
|
final AlignmentContext context = stratifiedContexts.get(genotype.getSampleName());
|
||||||
|
|
@ -74,8 +73,7 @@ public abstract class RankSumTest extends InfoFieldAnnotation implements Standar
|
||||||
|
|
||||||
fillIndelQualsFromPileup(pileup, refQuals, altQuals);
|
fillIndelQualsFromPileup(pileup, refQuals, altQuals);
|
||||||
}
|
}
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
final MannWhitneyU mannWhitneyU = new MannWhitneyU();
|
final MannWhitneyU mannWhitneyU = new MannWhitneyU();
|
||||||
|
|
@ -108,10 +106,12 @@ public abstract class RankSumTest extends InfoFieldAnnotation implements Standar
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void fillQualsFromPileup(byte ref, byte alt, ReadBackedPileup pileup, List<Double> refQuals, List<Double> altQuals);
|
protected abstract void fillQualsFromPileup(byte ref, byte alt, ReadBackedPileup pileup, List<Double> refQuals, List<Double> altQuals);
|
||||||
|
|
||||||
protected abstract void fillIndelQualsFromPileup(ReadBackedPileup pileup, List<Double> refQuals, List<Double> altQuals);
|
protected abstract void fillIndelQualsFromPileup(ReadBackedPileup pileup, List<Double> refQuals, List<Double> altQuals);
|
||||||
|
|
||||||
protected static boolean isUsableBase(final PileupElement p) {
|
protected static boolean isUsableBase(final PileupElement p) {
|
||||||
return !( p.isDeletion() ||
|
return !(p.isInsertionAtBeginningOfRead() ||
|
||||||
|
p.isDeletion() ||
|
||||||
p.getMappingQual() == 0 ||
|
p.getMappingQual() == 0 ||
|
||||||
p.getMappingQual() == QualityUtils.MAPPING_QUALITY_UNAVAILABLE ||
|
p.getMappingQual() == QualityUtils.MAPPING_QUALITY_UNAVAILABLE ||
|
||||||
((int) p.getQual()) < QualityUtils.MIN_USABLE_Q_SCORE); // need the unBAQed quality score here
|
((int) p.getQual()) < QualityUtils.MIN_USABLE_Q_SCORE); // need the unBAQed quality score here
|
||||||
|
|
|
||||||
|
|
@ -24,27 +24,32 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
public class ReadPosRankSumTest extends RankSumTest {
|
public class ReadPosRankSumTest extends RankSumTest {
|
||||||
|
|
||||||
public List<String> getKeyNames() { return Arrays.asList("ReadPosRankSum"); }
|
public List<String> getKeyNames() {
|
||||||
|
return Arrays.asList("ReadPosRankSum");
|
||||||
|
}
|
||||||
|
|
||||||
public List<VCFInfoHeaderLine> getDescriptions() { return Arrays.asList(new VCFInfoHeaderLine("ReadPosRankSum", 1, VCFHeaderLineType.Float, "Z-score from Wilcoxon rank sum test of Alt vs. Ref read position bias")); }
|
public List<VCFInfoHeaderLine> getDescriptions() {
|
||||||
|
return Arrays.asList(new VCFInfoHeaderLine("ReadPosRankSum", 1, VCFHeaderLineType.Float, "Z-score from Wilcoxon rank sum test of Alt vs. Ref read position bias"));
|
||||||
|
}
|
||||||
|
|
||||||
protected void fillQualsFromPileup(byte ref, byte alt, ReadBackedPileup pileup, List<Double> refQuals, List<Double> altQuals) {
|
protected void fillQualsFromPileup(byte ref, byte alt, ReadBackedPileup pileup, List<Double> refQuals, List<Double> altQuals) {
|
||||||
for (final PileupElement p : pileup) {
|
for (final PileupElement p : pileup) {
|
||||||
if (isUsableBase(p)) {
|
if (isUsableBase(p)) {
|
||||||
int readPos = AlignmentUtils.calcAlignmentByteArrayOffset(p.getRead().getCigar(), p.getOffset(), 0, 0);
|
int readPos = AlignmentUtils.calcAlignmentByteArrayOffset(p.getRead().getCigar(), p, 0, 0);
|
||||||
final int numAlignedBases = AlignmentUtils.getNumAlignedBases(p.getRead());
|
final int numAlignedBases = AlignmentUtils.getNumAlignedBases(p.getRead());
|
||||||
if( readPos > numAlignedBases / 2 ) {
|
if (readPos > numAlignedBases / 2)
|
||||||
readPos = numAlignedBases - (readPos + 1);
|
readPos = numAlignedBases - (readPos + 1);
|
||||||
|
|
||||||
|
|
||||||
|
if (p.getBase() == ref)
|
||||||
|
refQuals.add((double) readPos);
|
||||||
|
else if (p.getBase() == alt)
|
||||||
|
altQuals.add((double) readPos);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( p.getBase() == ref ) {
|
|
||||||
refQuals.add( (double)readPos );
|
|
||||||
} else if ( p.getBase() == alt ) {
|
|
||||||
altQuals.add( (double)readPos );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
protected void fillIndelQualsFromPileup(ReadBackedPileup pileup, List<Double> refQuals, List<Double> altQuals) {
|
protected void fillIndelQualsFromPileup(ReadBackedPileup pileup, List<Double> refQuals, List<Double> altQuals) {
|
||||||
// equivalent is whether indel likelihoods for reads corresponding to ref allele are more likely than reads corresponding to alt allele
|
// equivalent is whether indel likelihoods for reads corresponding to ref allele are more likely than reads corresponding to alt allele
|
||||||
// to classify a pileup element as ref or alt, we look at the likelihood associated with the allele associated to this element.
|
// to classify a pileup element as ref or alt, we look at the likelihood associated with the allele associated to this element.
|
||||||
|
|
@ -55,13 +60,10 @@ public class ReadPosRankSumTest extends RankSumTest {
|
||||||
final HashMap<PileupElement, LinkedHashMap<Allele, Double>> indelLikelihoodMap = IndelGenotypeLikelihoodsCalculationModel.getIndelLikelihoodMap();
|
final HashMap<PileupElement, LinkedHashMap<Allele, Double>> indelLikelihoodMap = IndelGenotypeLikelihoodsCalculationModel.getIndelLikelihoodMap();
|
||||||
for (final PileupElement p : pileup) {
|
for (final PileupElement p : pileup) {
|
||||||
if (indelLikelihoodMap.containsKey(p)) {
|
if (indelLikelihoodMap.containsKey(p)) {
|
||||||
// retrieve likelihood information corresponding to this read
|
LinkedHashMap<Allele, Double> el = indelLikelihoodMap.get(p); // retrieve likelihood information corresponding to this read
|
||||||
LinkedHashMap<Allele,Double> el = indelLikelihoodMap.get(p);
|
double refLikelihood = 0.0, altLikelihood = Double.NEGATIVE_INFINITY; // by design, first element in LinkedHashMap was ref allele
|
||||||
// by design, first element in LinkedHashMap was ref allele
|
|
||||||
double refLikelihood=0.0, altLikelihood=Double.NEGATIVE_INFINITY;
|
|
||||||
|
|
||||||
for (Allele a : el.keySet()) {
|
for (Allele a : el.keySet()) {
|
||||||
|
|
||||||
if (a.isReference())
|
if (a.isReference())
|
||||||
refLikelihood = el.get(a);
|
refLikelihood = el.get(a);
|
||||||
else {
|
else {
|
||||||
|
|
@ -88,8 +90,7 @@ public class ReadPosRankSumTest extends RankSumTest {
|
||||||
if (refLikelihood > (altLikelihood + INDEL_LIKELIHOOD_THRESH)) {
|
if (refLikelihood > (altLikelihood + INDEL_LIKELIHOOD_THRESH)) {
|
||||||
refQuals.add((double) readPos);
|
refQuals.add((double) readPos);
|
||||||
//if (DEBUG) System.out.format("REF like: %4.1f, pos: %d\n",refLikelihood,readPos);
|
//if (DEBUG) System.out.format("REF like: %4.1f, pos: %d\n",refLikelihood,readPos);
|
||||||
}
|
} else if (altLikelihood > (refLikelihood + INDEL_LIKELIHOOD_THRESH)) {
|
||||||
else if (altLikelihood > (refLikelihood + INDEL_LIKELIHOOD_THRESH)) {
|
|
||||||
altQuals.add((double) readPos);
|
altQuals.add((double) readPos);
|
||||||
//if (DEBUG) System.out.format("ALT like: %4.1f, pos: %d\n",refLikelihood,readPos);
|
//if (DEBUG) System.out.format("ALT like: %4.1f, pos: %d\n",refLikelihood,readPos);
|
||||||
|
|
||||||
|
|
@ -157,8 +158,6 @@ public class ReadPosRankSumTest extends RankSumTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
int getOffsetFromClippedReadStart(SAMRecord read, int offset) {
|
int getOffsetFromClippedReadStart(SAMRecord read, int offset) {
|
||||||
|
|
||||||
|
|
||||||
return offset - getNumClippedBasesAtStart(read);
|
return offset - getNumClippedBasesAtStart(read);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -278,7 +278,7 @@ public class DiploidSNPGenotypeLikelihoods implements Cloneable {
|
||||||
if ( qual == 0 )
|
if ( qual == 0 )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if ( elt.isReducedRead() ) {
|
if ( elt.getRead().isReducedRead() ) {
|
||||||
// reduced read representation
|
// reduced read representation
|
||||||
if ( BaseUtils.isRegularBase( obsBase )) {
|
if ( BaseUtils.isRegularBase( obsBase )) {
|
||||||
int representativeCount = elt.getRepresentativeCount();
|
int representativeCount = elt.getRepresentativeCount();
|
||||||
|
|
|
||||||
|
|
@ -125,8 +125,6 @@ public class IndelGenotypeLikelihoodsCalculationModel extends GenotypeLikelihood
|
||||||
final ReadBackedExtendedEventPileup indelPileup = context.getExtendedEventPileup();
|
final ReadBackedExtendedEventPileup indelPileup = context.getExtendedEventPileup();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for (ExtendedEventPileupElement p : indelPileup.toExtendedIterable()) {
|
for (ExtendedEventPileupElement p : indelPileup.toExtendedIterable()) {
|
||||||
//SAMRecord read = p.getRead();
|
//SAMRecord read = p.getRead();
|
||||||
GATKSAMRecord read = ReadClipper.hardClipAdaptorSequence(p.getRead());
|
GATKSAMRecord read = ReadClipper.hardClipAdaptorSequence(p.getRead());
|
||||||
|
|
@ -156,8 +154,7 @@ public class IndelGenotypeLikelihoodsCalculationModel extends GenotypeLikelihood
|
||||||
consensusIndelStrings.put(s, cnt + 1);
|
consensusIndelStrings.put(s, cnt + 1);
|
||||||
foundKey = true;
|
foundKey = true;
|
||||||
break;
|
break;
|
||||||
}
|
} else if (indelString.startsWith(s)) {
|
||||||
else if (indelString.startsWith(s)) {
|
|
||||||
// case 2: indel stored in hash table is prefix of current insertion
|
// case 2: indel stored in hash table is prefix of current insertion
|
||||||
// In this case, new bases are new key.
|
// In this case, new bases are new key.
|
||||||
consensusIndelStrings.remove(s);
|
consensusIndelStrings.remove(s);
|
||||||
|
|
@ -170,8 +167,7 @@ public class IndelGenotypeLikelihoodsCalculationModel extends GenotypeLikelihood
|
||||||
// none of the above: event bases not supported by previous table, so add new key
|
// none of the above: event bases not supported by previous table, so add new key
|
||||||
consensusIndelStrings.put(indelString, 1);
|
consensusIndelStrings.put(indelString, 1);
|
||||||
|
|
||||||
}
|
} else if (read.getAlignmentStart() == loc.getStart() + 1) {
|
||||||
else if (read.getAlignmentStart() == loc.getStart()+1) {
|
|
||||||
// opposite corner condition: read will start at current locus with an insertion
|
// opposite corner condition: read will start at current locus with an insertion
|
||||||
for (String s : consensusIndelStrings.keySet()) {
|
for (String s : consensusIndelStrings.keySet()) {
|
||||||
int cnt = consensusIndelStrings.get(s);
|
int cnt = consensusIndelStrings.get(s);
|
||||||
|
|
@ -180,8 +176,7 @@ public class IndelGenotypeLikelihoodsCalculationModel extends GenotypeLikelihood
|
||||||
consensusIndelStrings.put(s, cnt + 1);
|
consensusIndelStrings.put(s, cnt + 1);
|
||||||
foundKey = true;
|
foundKey = true;
|
||||||
break;
|
break;
|
||||||
}
|
} else if (indelString.endsWith(s)) {
|
||||||
else if (indelString.endsWith(s)) {
|
|
||||||
// case 2: indel stored in hash table is suffix of current insertion
|
// case 2: indel stored in hash table is suffix of current insertion
|
||||||
// In this case, new bases are new key.
|
// In this case, new bases are new key.
|
||||||
|
|
||||||
|
|
@ -195,15 +190,13 @@ public class IndelGenotypeLikelihoodsCalculationModel extends GenotypeLikelihood
|
||||||
// none of the above: event bases not supported by previous table, so add new key
|
// none of the above: event bases not supported by previous table, so add new key
|
||||||
consensusIndelStrings.put(indelString, 1);
|
consensusIndelStrings.put(indelString, 1);
|
||||||
|
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// normal case: insertion somewhere in the middle of a read: add count to hash map
|
// normal case: insertion somewhere in the middle of a read: add count to hash map
|
||||||
int cnt = consensusIndelStrings.containsKey(indelString) ? consensusIndelStrings.get(indelString) : 0;
|
int cnt = consensusIndelStrings.containsKey(indelString) ? consensusIndelStrings.get(indelString) : 0;
|
||||||
consensusIndelStrings.put(indelString, cnt + 1);
|
consensusIndelStrings.put(indelString, cnt + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} else if (p.isDeletion()) {
|
||||||
else if (p.isDeletion()) {
|
|
||||||
indelString = String.format("D%d", p.getEventLength());
|
indelString = String.format("D%d", p.getEventLength());
|
||||||
int cnt = consensusIndelStrings.containsKey(indelString) ? consensusIndelStrings.get(indelString) : 0;
|
int cnt = consensusIndelStrings.containsKey(indelString) ? consensusIndelStrings.get(indelString) : 0;
|
||||||
consensusIndelStrings.put(indelString, cnt + 1);
|
consensusIndelStrings.put(indelString, cnt + 1);
|
||||||
|
|
@ -235,8 +228,7 @@ public class IndelGenotypeLikelihoodsCalculationModel extends GenotypeLikelihood
|
||||||
refAllele = Allele.create(refBases, true);
|
refAllele = Allele.create(refBases, true);
|
||||||
altAllele = Allele.create(Allele.NULL_ALLELE_STRING, false);
|
altAllele = Allele.create(Allele.NULL_ALLELE_STRING, false);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// insertion case
|
// insertion case
|
||||||
if (Allele.acceptableAlleleBases(s)) {
|
if (Allele.acceptableAlleleBases(s)) {
|
||||||
refAllele = Allele.create(Allele.NULL_ALLELE_STRING, true);
|
refAllele = Allele.create(Allele.NULL_ALLELE_STRING, true);
|
||||||
|
|
@ -324,14 +316,12 @@ public class IndelGenotypeLikelihoodsCalculationModel extends GenotypeLikelihood
|
||||||
else
|
else
|
||||||
alleleList.add(a);
|
alleleList.add(a);
|
||||||
|
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
for (Allele a : vc.getAlleles())
|
for (Allele a : vc.getAlleles())
|
||||||
alleleList.add(a);
|
alleleList.add(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
alleleList = computeConsensusAlleles(ref, contexts, contextType, locParser);
|
alleleList = computeConsensusAlleles(ref, contexts, contextType, locParser);
|
||||||
if (alleleList.isEmpty())
|
if (alleleList.isEmpty())
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -444,7 +434,7 @@ public class IndelGenotypeLikelihoodsCalculationModel extends GenotypeLikelihood
|
||||||
protected int getFilteredDepth(ReadBackedPileup pileup) {
|
protected int getFilteredDepth(ReadBackedPileup pileup) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (PileupElement p : pileup) {
|
for (PileupElement p : pileup) {
|
||||||
if (p.isDeletion() || BaseUtils.isRegularBase(p.getBase()) )
|
if (p.isDeletion() || p.isInsertionAtBeginningOfRead() || BaseUtils.isRegularBase(p.getBase()))
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -212,7 +212,7 @@ public class SNPGenotypeLikelihoodsCalculationModel extends GenotypeLikelihoodsC
|
||||||
|
|
||||||
public class BAQedPileupElement extends PileupElement {
|
public class BAQedPileupElement extends PileupElement {
|
||||||
public BAQedPileupElement( final PileupElement PE ) {
|
public BAQedPileupElement( final PileupElement PE ) {
|
||||||
super(PE.getRead(), PE.getOffset());
|
super(PE.getRead(), PE.getOffset(), PE.isDeletion());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ public abstract class AbstractReadBackedPileup<RBP extends AbstractReadBackedPil
|
||||||
* reads[i] for all i in offsets. Does not make a copy of the data, so it's not safe to
|
* reads[i] for all i in offsets. Does not make a copy of the data, so it's not safe to
|
||||||
* go changing the reads.
|
* go changing the reads.
|
||||||
*
|
*
|
||||||
* @param loc
|
* @param loc The genome loc to associate reads wotj
|
||||||
* @param reads
|
* @param reads
|
||||||
* @param offsets
|
* @param offsets
|
||||||
*/
|
*/
|
||||||
|
|
@ -64,14 +64,9 @@ public abstract class AbstractReadBackedPileup<RBP extends AbstractReadBackedPil
|
||||||
this.pileupElementTracker = readsOffsets2Pileup(reads, offsets);
|
this.pileupElementTracker = readsOffsets2Pileup(reads, offsets);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AbstractReadBackedPileup(GenomeLoc loc, List<GATKSAMRecord> reads, int offset ) {
|
|
||||||
this.loc = loc;
|
|
||||||
this.pileupElementTracker = readsOffsets2Pileup(reads,offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new version of a read backed pileup at loc without any aligned reads
|
* Create a new version of a read backed pileup at loc without any aligned reads
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public AbstractReadBackedPileup(GenomeLoc loc) {
|
public AbstractReadBackedPileup(GenomeLoc loc) {
|
||||||
this(loc, new UnifiedPileupElementTracker<PE>());
|
this(loc, new UnifiedPileupElementTracker<PE>());
|
||||||
|
|
@ -81,7 +76,6 @@ public abstract class AbstractReadBackedPileup<RBP extends AbstractReadBackedPil
|
||||||
* Create a new version of a read backed pileup at loc, using the reads and their corresponding
|
* Create a new version of a read backed pileup at loc, using the reads and their corresponding
|
||||||
* offsets. This lower level constructure assumes pileup is well-formed and merely keeps a
|
* offsets. This lower level constructure assumes pileup is well-formed and merely keeps a
|
||||||
* pointer to pileup. Don't go changing the data in pileup.
|
* pointer to pileup. Don't go changing the data in pileup.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public AbstractReadBackedPileup(GenomeLoc loc, List<PE> pileup) {
|
public AbstractReadBackedPileup(GenomeLoc loc, List<PE> pileup) {
|
||||||
if (loc == null) throw new ReviewedStingException("Illegal null genomeloc in ReadBackedPileup");
|
if (loc == null) throw new ReviewedStingException("Illegal null genomeloc in ReadBackedPileup");
|
||||||
|
|
@ -94,6 +88,7 @@ public abstract class AbstractReadBackedPileup<RBP extends AbstractReadBackedPil
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optimization of above constructor where all of the cached data is provided
|
* Optimization of above constructor where all of the cached data is provided
|
||||||
|
*
|
||||||
* @param loc
|
* @param loc
|
||||||
* @param pileup
|
* @param pileup
|
||||||
*/
|
*/
|
||||||
|
|
@ -125,6 +120,11 @@ public abstract class AbstractReadBackedPileup<RBP extends AbstractReadBackedPil
|
||||||
this.pileupElementTracker = tracker;
|
this.pileupElementTracker = tracker;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AbstractReadBackedPileup(GenomeLoc loc, List<GATKSAMRecord> reads, int offset) {
|
||||||
|
this.loc = loc;
|
||||||
|
this.pileupElementTracker = readsOffsets2Pileup(reads, offset);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate cached sizes, nDeletion, and base counts for the pileup. This calculation is done upfront,
|
* Calculate cached sizes, nDeletion, and base counts for the pileup. This calculation is done upfront,
|
||||||
* so you pay the cost at the start, but it's more efficient to do this rather than pay the cost of calling
|
* so you pay the cost at the start, but it's more efficient to do this rather than pay the cost of calling
|
||||||
|
|
@ -170,11 +170,14 @@ public abstract class AbstractReadBackedPileup<RBP extends AbstractReadBackedPil
|
||||||
private PileupElementTracker<PE> readsOffsets2Pileup(List<GATKSAMRecord> reads, List<Integer> offsets) {
|
private PileupElementTracker<PE> readsOffsets2Pileup(List<GATKSAMRecord> reads, List<Integer> offsets) {
|
||||||
if (reads == null) throw new ReviewedStingException("Illegal null read list in UnifiedReadBackedPileup");
|
if (reads == null) throw new ReviewedStingException("Illegal null read list in UnifiedReadBackedPileup");
|
||||||
if (offsets == null) throw new ReviewedStingException("Illegal null offsets list in UnifiedReadBackedPileup");
|
if (offsets == null) throw new ReviewedStingException("Illegal null offsets list in UnifiedReadBackedPileup");
|
||||||
if ( reads.size() != offsets.size() ) throw new ReviewedStingException("Reads and offset lists have different sizes!");
|
if (reads.size() != offsets.size())
|
||||||
|
throw new ReviewedStingException("Reads and offset lists have different sizes!");
|
||||||
|
|
||||||
UnifiedPileupElementTracker<PE> pileup = new UnifiedPileupElementTracker<PE>();
|
UnifiedPileupElementTracker<PE> pileup = new UnifiedPileupElementTracker<PE>();
|
||||||
for (int i = 0; i < reads.size(); i++) {
|
for (int i = 0; i < reads.size(); i++) {
|
||||||
pileup.add(createNewPileupElement(reads.get(i),offsets.get(i)));
|
GATKSAMRecord read = reads.get(i);
|
||||||
|
int offset = offsets.get(i);
|
||||||
|
pileup.add(createNewPileupElement(read, offset, BaseUtils.simpleBaseToBaseIndex(read.getReadBases()[offset]) == BaseUtils.D));
|
||||||
}
|
}
|
||||||
|
|
||||||
return pileup;
|
return pileup;
|
||||||
|
|
@ -192,15 +195,16 @@ public abstract class AbstractReadBackedPileup<RBP extends AbstractReadBackedPil
|
||||||
if (offset < 0) throw new ReviewedStingException("Illegal offset < 0 UnifiedReadBackedPileup");
|
if (offset < 0) throw new ReviewedStingException("Illegal offset < 0 UnifiedReadBackedPileup");
|
||||||
|
|
||||||
UnifiedPileupElementTracker<PE> pileup = new UnifiedPileupElementTracker<PE>();
|
UnifiedPileupElementTracker<PE> pileup = new UnifiedPileupElementTracker<PE>();
|
||||||
for ( int i = 0; i < reads.size(); i++ ) {
|
for (GATKSAMRecord read : reads) {
|
||||||
pileup.add(createNewPileupElement( reads.get(i), offset ));
|
pileup.add(createNewPileupElement(read, offset, BaseUtils.simpleBaseToBaseIndex(read.getReadBases()[offset]) == BaseUtils.D));
|
||||||
}
|
}
|
||||||
|
|
||||||
return pileup;
|
return pileup;
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
|
protected abstract PE createNewPileupElement(GATKSAMRecord read, int offset, boolean isDeletion);
|
||||||
|
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
//
|
//
|
||||||
|
|
@ -229,8 +233,7 @@ public abstract class AbstractReadBackedPileup<RBP extends AbstractReadBackedPil
|
||||||
}
|
}
|
||||||
return (RBP) createNewPileup(loc, filteredTracker);
|
return (RBP) createNewPileup(loc, filteredTracker);
|
||||||
|
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
UnifiedPileupElementTracker<PE> tracker = (UnifiedPileupElementTracker<PE>) pileupElementTracker;
|
UnifiedPileupElementTracker<PE> tracker = (UnifiedPileupElementTracker<PE>) pileupElementTracker;
|
||||||
UnifiedPileupElementTracker<PE> filteredTracker = new UnifiedPileupElementTracker<PE>();
|
UnifiedPileupElementTracker<PE> filteredTracker = new UnifiedPileupElementTracker<PE>();
|
||||||
|
|
||||||
|
|
@ -266,8 +269,7 @@ public abstract class AbstractReadBackedPileup<RBP extends AbstractReadBackedPil
|
||||||
filteredTracker.addElements(sample, pileup.pileupElementTracker);
|
filteredTracker.addElements(sample, pileup.pileupElementTracker);
|
||||||
}
|
}
|
||||||
return (RBP) createNewPileup(loc, filteredTracker);
|
return (RBP) createNewPileup(loc, filteredTracker);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
Map<String, PE> filteredPileup = new HashMap<String, PE>();
|
Map<String, PE> filteredPileup = new HashMap<String, PE>();
|
||||||
|
|
||||||
for (PE p : pileupElementTracker) {
|
for (PE p : pileupElementTracker) {
|
||||||
|
|
@ -321,8 +323,7 @@ public abstract class AbstractReadBackedPileup<RBP extends AbstractReadBackedPil
|
||||||
}
|
}
|
||||||
return (RBP) createNewPileup(loc, filteredTracker);
|
return (RBP) createNewPileup(loc, filteredTracker);
|
||||||
|
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
UnifiedPileupElementTracker<PE> tracker = (UnifiedPileupElementTracker<PE>) pileupElementTracker;
|
UnifiedPileupElementTracker<PE> tracker = (UnifiedPileupElementTracker<PE>) pileupElementTracker;
|
||||||
UnifiedPileupElementTracker<PE> filteredTracker = new UnifiedPileupElementTracker<PE>();
|
UnifiedPileupElementTracker<PE> filteredTracker = new UnifiedPileupElementTracker<PE>();
|
||||||
|
|
||||||
|
|
@ -349,8 +350,7 @@ public abstract class AbstractReadBackedPileup<RBP extends AbstractReadBackedPil
|
||||||
filteredTracker.addElements(sample, pileup.pileupElementTracker);
|
filteredTracker.addElements(sample, pileup.pileupElementTracker);
|
||||||
}
|
}
|
||||||
return (RBP) createNewPileup(loc, filteredTracker);
|
return (RBP) createNewPileup(loc, filteredTracker);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
UnifiedPileupElementTracker<PE> tracker = (UnifiedPileupElementTracker<PE>) pileupElementTracker;
|
UnifiedPileupElementTracker<PE> tracker = (UnifiedPileupElementTracker<PE>) pileupElementTracker;
|
||||||
UnifiedPileupElementTracker<PE> filteredTracker = new UnifiedPileupElementTracker<PE>();
|
UnifiedPileupElementTracker<PE> filteredTracker = new UnifiedPileupElementTracker<PE>();
|
||||||
|
|
||||||
|
|
@ -365,6 +365,7 @@ public abstract class AbstractReadBackedPileup<RBP extends AbstractReadBackedPil
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the pileup consisting of only reads on the negative strand.
|
* Gets the pileup consisting of only reads on the negative strand.
|
||||||
|
*
|
||||||
* @return A read-backed pileup consisting only of reads on the negative strand.
|
* @return A read-backed pileup consisting only of reads on the negative strand.
|
||||||
*/
|
*/
|
||||||
public RBP getNegativeStrandPileup() {
|
public RBP getNegativeStrandPileup() {
|
||||||
|
|
@ -378,8 +379,7 @@ public abstract class AbstractReadBackedPileup<RBP extends AbstractReadBackedPil
|
||||||
filteredTracker.addElements(sample, pileup.pileupElementTracker);
|
filteredTracker.addElements(sample, pileup.pileupElementTracker);
|
||||||
}
|
}
|
||||||
return (RBP) createNewPileup(loc, filteredTracker);
|
return (RBP) createNewPileup(loc, filteredTracker);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
UnifiedPileupElementTracker<PE> tracker = (UnifiedPileupElementTracker<PE>) pileupElementTracker;
|
UnifiedPileupElementTracker<PE> tracker = (UnifiedPileupElementTracker<PE>) pileupElementTracker;
|
||||||
UnifiedPileupElementTracker<PE> filteredTracker = new UnifiedPileupElementTracker<PE>();
|
UnifiedPileupElementTracker<PE> filteredTracker = new UnifiedPileupElementTracker<PE>();
|
||||||
|
|
||||||
|
|
@ -394,6 +394,7 @@ public abstract class AbstractReadBackedPileup<RBP extends AbstractReadBackedPil
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a pileup consisting of all those elements passed by a given filter.
|
* Gets a pileup consisting of all those elements passed by a given filter.
|
||||||
|
*
|
||||||
* @param filter Filter to use when testing for elements.
|
* @param filter Filter to use when testing for elements.
|
||||||
* @return a pileup without the given filtered elements.
|
* @return a pileup without the given filtered elements.
|
||||||
*/
|
*/
|
||||||
|
|
@ -409,8 +410,7 @@ public abstract class AbstractReadBackedPileup<RBP extends AbstractReadBackedPil
|
||||||
}
|
}
|
||||||
|
|
||||||
return (RBP) createNewPileup(loc, filteredTracker);
|
return (RBP) createNewPileup(loc, filteredTracker);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
UnifiedPileupElementTracker<PE> filteredTracker = new UnifiedPileupElementTracker<PE>();
|
UnifiedPileupElementTracker<PE> filteredTracker = new UnifiedPileupElementTracker<PE>();
|
||||||
|
|
||||||
for (PE p : pileupElementTracker) {
|
for (PE p : pileupElementTracker) {
|
||||||
|
|
@ -422,8 +422,10 @@ public abstract class AbstractReadBackedPileup<RBP extends AbstractReadBackedPil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns subset of this pileup that contains only bases with quality >= minBaseQ, coming from
|
/**
|
||||||
|
* Returns subset of this pileup that contains only bases with quality >= minBaseQ, coming from
|
||||||
* reads with mapping qualities >= minMapQ. This method allocates and returns a new instance of ReadBackedPileup.
|
* reads with mapping qualities >= minMapQ. This method allocates and returns a new instance of ReadBackedPileup.
|
||||||
|
*
|
||||||
* @param minBaseQ
|
* @param minBaseQ
|
||||||
* @param minMapQ
|
* @param minMapQ
|
||||||
* @return
|
* @return
|
||||||
|
|
@ -441,8 +443,7 @@ public abstract class AbstractReadBackedPileup<RBP extends AbstractReadBackedPil
|
||||||
}
|
}
|
||||||
|
|
||||||
return (RBP) createNewPileup(loc, filteredTracker);
|
return (RBP) createNewPileup(loc, filteredTracker);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
UnifiedPileupElementTracker<PE> filteredTracker = new UnifiedPileupElementTracker<PE>();
|
UnifiedPileupElementTracker<PE> filteredTracker = new UnifiedPileupElementTracker<PE>();
|
||||||
|
|
||||||
for (PE p : pileupElementTracker) {
|
for (PE p : pileupElementTracker) {
|
||||||
|
|
@ -458,8 +459,10 @@ public abstract class AbstractReadBackedPileup<RBP extends AbstractReadBackedPil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns subset of this pileup that contains only bases with quality >= minBaseQ.
|
/**
|
||||||
|
* Returns subset of this pileup that contains only bases with quality >= minBaseQ.
|
||||||
* This method allocates and returns a new instance of ReadBackedPileup.
|
* This method allocates and returns a new instance of ReadBackedPileup.
|
||||||
|
*
|
||||||
* @param minBaseQ
|
* @param minBaseQ
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
@ -468,8 +471,10 @@ public abstract class AbstractReadBackedPileup<RBP extends AbstractReadBackedPil
|
||||||
return getBaseAndMappingFilteredPileup(minBaseQ, -1);
|
return getBaseAndMappingFilteredPileup(minBaseQ, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns subset of this pileup that contains only bases coming from reads with mapping quality >= minMapQ.
|
/**
|
||||||
|
* Returns subset of this pileup that contains only bases coming from reads with mapping quality >= minMapQ.
|
||||||
* This method allocates and returns a new instance of ReadBackedPileup.
|
* This method allocates and returns a new instance of ReadBackedPileup.
|
||||||
|
*
|
||||||
* @param minMapQ
|
* @param minMapQ
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
@ -480,6 +485,7 @@ public abstract class AbstractReadBackedPileup<RBP extends AbstractReadBackedPil
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a list of the read groups represented in this pileup.
|
* Gets a list of the read groups represented in this pileup.
|
||||||
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -492,6 +498,7 @@ public abstract class AbstractReadBackedPileup<RBP extends AbstractReadBackedPil
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the pileup for a given read group. Horrendously inefficient at this point.
|
* Gets the pileup for a given read group. Horrendously inefficient at this point.
|
||||||
|
*
|
||||||
* @param targetReadGroupId Identifier for the read group.
|
* @param targetReadGroupId Identifier for the read group.
|
||||||
* @return A read-backed pileup containing only the reads in the given read group.
|
* @return A read-backed pileup containing only the reads in the given read group.
|
||||||
*/
|
*/
|
||||||
|
|
@ -508,16 +515,14 @@ public abstract class AbstractReadBackedPileup<RBP extends AbstractReadBackedPil
|
||||||
filteredTracker.addElements(sample, pileup.pileupElementTracker);
|
filteredTracker.addElements(sample, pileup.pileupElementTracker);
|
||||||
}
|
}
|
||||||
return filteredTracker.size() > 0 ? (RBP) createNewPileup(loc, filteredTracker) : null;
|
return filteredTracker.size() > 0 ? (RBP) createNewPileup(loc, filteredTracker) : null;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
UnifiedPileupElementTracker<PE> filteredTracker = new UnifiedPileupElementTracker<PE>();
|
UnifiedPileupElementTracker<PE> filteredTracker = new UnifiedPileupElementTracker<PE>();
|
||||||
for (PE p : pileupElementTracker) {
|
for (PE p : pileupElementTracker) {
|
||||||
GATKSAMRecord read = p.getRead();
|
GATKSAMRecord read = p.getRead();
|
||||||
if (targetReadGroupId != null) {
|
if (targetReadGroupId != null) {
|
||||||
if (read.getReadGroup() != null && targetReadGroupId.equals(read.getReadGroup().getReadGroupId()))
|
if (read.getReadGroup() != null && targetReadGroupId.equals(read.getReadGroup().getReadGroupId()))
|
||||||
filteredTracker.add(p);
|
filteredTracker.add(p);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (read.getReadGroup() == null || read.getReadGroup().getReadGroupId() == null)
|
if (read.getReadGroup() == null || read.getReadGroup().getReadGroupId() == null)
|
||||||
filteredTracker.add(p);
|
filteredTracker.add(p);
|
||||||
}
|
}
|
||||||
|
|
@ -528,6 +533,7 @@ public abstract class AbstractReadBackedPileup<RBP extends AbstractReadBackedPil
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the pileup for a set of read groups. Horrendously inefficient at this point.
|
* Gets the pileup for a set of read groups. Horrendously inefficient at this point.
|
||||||
|
*
|
||||||
* @param rgSet List of identifiers for the read groups.
|
* @param rgSet List of identifiers for the read groups.
|
||||||
* @return A read-backed pileup containing only the reads in the given read groups.
|
* @return A read-backed pileup containing only the reads in the given read groups.
|
||||||
*/
|
*/
|
||||||
|
|
@ -544,16 +550,14 @@ public abstract class AbstractReadBackedPileup<RBP extends AbstractReadBackedPil
|
||||||
filteredTracker.addElements(sample, pileup.pileupElementTracker);
|
filteredTracker.addElements(sample, pileup.pileupElementTracker);
|
||||||
}
|
}
|
||||||
return filteredTracker.size() > 0 ? (RBP) createNewPileup(loc, filteredTracker) : null;
|
return filteredTracker.size() > 0 ? (RBP) createNewPileup(loc, filteredTracker) : null;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
UnifiedPileupElementTracker<PE> filteredTracker = new UnifiedPileupElementTracker<PE>();
|
UnifiedPileupElementTracker<PE> filteredTracker = new UnifiedPileupElementTracker<PE>();
|
||||||
for (PE p : pileupElementTracker) {
|
for (PE p : pileupElementTracker) {
|
||||||
GATKSAMRecord read = p.getRead();
|
GATKSAMRecord read = p.getRead();
|
||||||
if (rgSet != null && !rgSet.isEmpty()) {
|
if (rgSet != null && !rgSet.isEmpty()) {
|
||||||
if (read.getReadGroup() != null && rgSet.contains(read.getReadGroup().getReadGroupId()))
|
if (read.getReadGroup() != null && rgSet.contains(read.getReadGroup().getReadGroupId()))
|
||||||
filteredTracker.add(p);
|
filteredTracker.add(p);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (read.getReadGroup() == null || read.getReadGroup().getReadGroupId() == null)
|
if (read.getReadGroup() == null || read.getReadGroup().getReadGroupId() == null)
|
||||||
filteredTracker.add(p);
|
filteredTracker.add(p);
|
||||||
}
|
}
|
||||||
|
|
@ -575,8 +579,7 @@ public abstract class AbstractReadBackedPileup<RBP extends AbstractReadBackedPil
|
||||||
filteredTracker.addElements(sample, pileup.pileupElementTracker);
|
filteredTracker.addElements(sample, pileup.pileupElementTracker);
|
||||||
}
|
}
|
||||||
return filteredTracker.size() > 0 ? (RBP) createNewPileup(loc, filteredTracker) : null;
|
return filteredTracker.size() > 0 ? (RBP) createNewPileup(loc, filteredTracker) : null;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
UnifiedPileupElementTracker<PE> filteredTracker = new UnifiedPileupElementTracker<PE>();
|
UnifiedPileupElementTracker<PE> filteredTracker = new UnifiedPileupElementTracker<PE>();
|
||||||
for (PE p : pileupElementTracker) {
|
for (PE p : pileupElementTracker) {
|
||||||
GATKSAMRecord read = p.getRead();
|
GATKSAMRecord read = p.getRead();
|
||||||
|
|
@ -585,8 +588,7 @@ public abstract class AbstractReadBackedPileup<RBP extends AbstractReadBackedPil
|
||||||
(read.getReadGroup().getReadGroupId().startsWith(laneID + ".")) || // lane is the same, but sample identifier is different
|
(read.getReadGroup().getReadGroupId().startsWith(laneID + ".")) || // lane is the same, but sample identifier is different
|
||||||
(read.getReadGroup().getReadGroupId().equals(laneID))) // in case there is no sample identifier, they have to be exactly the same
|
(read.getReadGroup().getReadGroupId().equals(laneID))) // in case there is no sample identifier, they have to be exactly the same
|
||||||
filteredTracker.add(p);
|
filteredTracker.add(p);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (read.getReadGroup() == null || read.getReadGroup().getReadGroupId() == null)
|
if (read.getReadGroup() == null || read.getReadGroup().getReadGroupId() == null)
|
||||||
filteredTracker.add(p);
|
filteredTracker.add(p);
|
||||||
}
|
}
|
||||||
|
|
@ -599,8 +601,7 @@ public abstract class AbstractReadBackedPileup<RBP extends AbstractReadBackedPil
|
||||||
if (pileupElementTracker instanceof PerSamplePileupElementTracker) {
|
if (pileupElementTracker instanceof PerSamplePileupElementTracker) {
|
||||||
PerSamplePileupElementTracker<PE> tracker = (PerSamplePileupElementTracker<PE>) pileupElementTracker;
|
PerSamplePileupElementTracker<PE> tracker = (PerSamplePileupElementTracker<PE>) pileupElementTracker;
|
||||||
return new HashSet<String>(tracker.getSamples());
|
return new HashSet<String>(tracker.getSamples());
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
Collection<String> sampleNames = new HashSet<String>();
|
Collection<String> sampleNames = new HashSet<String>();
|
||||||
for (PileupElement p : this) {
|
for (PileupElement p : this) {
|
||||||
GATKSAMRecord read = p.getRead();
|
GATKSAMRecord read = p.getRead();
|
||||||
|
|
@ -653,8 +654,7 @@ public abstract class AbstractReadBackedPileup<RBP extends AbstractReadBackedPil
|
||||||
}
|
}
|
||||||
|
|
||||||
return (RBP) createNewPileup(loc, filteredTracker);
|
return (RBP) createNewPileup(loc, filteredTracker);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
UnifiedPileupElementTracker<PE> tracker = (UnifiedPileupElementTracker<PE>) pileupElementTracker;
|
UnifiedPileupElementTracker<PE> tracker = (UnifiedPileupElementTracker<PE>) pileupElementTracker;
|
||||||
UnifiedPileupElementTracker<PE> filteredTracker = new UnifiedPileupElementTracker<PE>();
|
UnifiedPileupElementTracker<PE> filteredTracker = new UnifiedPileupElementTracker<PE>();
|
||||||
|
|
||||||
|
|
@ -675,8 +675,7 @@ public abstract class AbstractReadBackedPileup<RBP extends AbstractReadBackedPil
|
||||||
PerSamplePileupElementTracker<PE> tracker = (PerSamplePileupElementTracker<PE>) pileupElementTracker;
|
PerSamplePileupElementTracker<PE> tracker = (PerSamplePileupElementTracker<PE>) pileupElementTracker;
|
||||||
PileupElementTracker<PE> filteredElements = tracker.getElements(sampleNames);
|
PileupElementTracker<PE> filteredElements = tracker.getElements(sampleNames);
|
||||||
return filteredElements != null ? (RBP) createNewPileup(loc, filteredElements) : null;
|
return filteredElements != null ? (RBP) createNewPileup(loc, filteredElements) : null;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
HashSet<String> hashSampleNames = new HashSet<String>(sampleNames); // to speed up the "contains" access in the for loop
|
HashSet<String> hashSampleNames = new HashSet<String>(sampleNames); // to speed up the "contains" access in the for loop
|
||||||
UnifiedPileupElementTracker<PE> filteredTracker = new UnifiedPileupElementTracker<PE>();
|
UnifiedPileupElementTracker<PE> filteredTracker = new UnifiedPileupElementTracker<PE>();
|
||||||
for (PE p : pileupElementTracker) {
|
for (PE p : pileupElementTracker) {
|
||||||
|
|
@ -684,8 +683,7 @@ public abstract class AbstractReadBackedPileup<RBP extends AbstractReadBackedPil
|
||||||
if (sampleNames != null) { // still checking on sampleNames because hashSampleNames will never be null. And empty means something else.
|
if (sampleNames != null) { // still checking on sampleNames because hashSampleNames will never be null. And empty means something else.
|
||||||
if (read.getReadGroup() != null && hashSampleNames.contains(read.getReadGroup().getSample()))
|
if (read.getReadGroup() != null && hashSampleNames.contains(read.getReadGroup().getSample()))
|
||||||
filteredTracker.add(p);
|
filteredTracker.add(p);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (read.getReadGroup() == null || read.getReadGroup().getSample() == null)
|
if (read.getReadGroup() == null || read.getReadGroup().getSample() == null)
|
||||||
filteredTracker.add(p);
|
filteredTracker.add(p);
|
||||||
}
|
}
|
||||||
|
|
@ -701,16 +699,14 @@ public abstract class AbstractReadBackedPileup<RBP extends AbstractReadBackedPil
|
||||||
PerSamplePileupElementTracker<PE> tracker = (PerSamplePileupElementTracker<PE>) pileupElementTracker;
|
PerSamplePileupElementTracker<PE> tracker = (PerSamplePileupElementTracker<PE>) pileupElementTracker;
|
||||||
PileupElementTracker<PE> filteredElements = tracker.getElements(sampleName);
|
PileupElementTracker<PE> filteredElements = tracker.getElements(sampleName);
|
||||||
return filteredElements != null ? (RBP) createNewPileup(loc, filteredElements) : null;
|
return filteredElements != null ? (RBP) createNewPileup(loc, filteredElements) : null;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
UnifiedPileupElementTracker<PE> filteredTracker = new UnifiedPileupElementTracker<PE>();
|
UnifiedPileupElementTracker<PE> filteredTracker = new UnifiedPileupElementTracker<PE>();
|
||||||
for (PE p : pileupElementTracker) {
|
for (PE p : pileupElementTracker) {
|
||||||
GATKSAMRecord read = p.getRead();
|
GATKSAMRecord read = p.getRead();
|
||||||
if (sampleName != null) {
|
if (sampleName != null) {
|
||||||
if (read.getReadGroup() != null && sampleName.equals(read.getReadGroup().getSample()))
|
if (read.getReadGroup() != null && sampleName.equals(read.getReadGroup().getSample()))
|
||||||
filteredTracker.add(p);
|
filteredTracker.add(p);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (read.getReadGroup() == null || read.getReadGroup().getSample() == null)
|
if (read.getReadGroup() == null || read.getReadGroup().getSample() == null)
|
||||||
filteredTracker.add(p);
|
filteredTracker.add(p);
|
||||||
}
|
}
|
||||||
|
|
@ -727,9 +723,9 @@ public abstract class AbstractReadBackedPileup<RBP extends AbstractReadBackedPil
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The best way to access PileupElements where you only care about the bases and quals in the pileup.
|
* The best way to access PileupElements where you only care about the bases and quals in the pileup.
|
||||||
*
|
* <p/>
|
||||||
* for (PileupElement p : this) { doSomething(p); }
|
* for (PileupElement p : this) { doSomething(p); }
|
||||||
*
|
* <p/>
|
||||||
* Provides efficient iteration of the data.
|
* Provides efficient iteration of the data.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
|
|
@ -739,9 +735,17 @@ public abstract class AbstractReadBackedPileup<RBP extends AbstractReadBackedPil
|
||||||
return new Iterator<PileupElement>() {
|
return new Iterator<PileupElement>() {
|
||||||
private final Iterator<PE> wrappedIterator = pileupElementTracker.iterator();
|
private final Iterator<PE> wrappedIterator = pileupElementTracker.iterator();
|
||||||
|
|
||||||
public boolean hasNext() { return wrappedIterator.hasNext(); }
|
public boolean hasNext() {
|
||||||
public PileupElement next() { return wrappedIterator.next(); }
|
return wrappedIterator.hasNext();
|
||||||
public void remove() { throw new UnsupportedOperationException("Cannot remove from a pileup element iterator"); }
|
}
|
||||||
|
|
||||||
|
public PileupElement next() {
|
||||||
|
return wrappedIterator.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove() {
|
||||||
|
throw new UnsupportedOperationException("Cannot remove from a pileup element iterator");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -823,8 +827,7 @@ public abstract class AbstractReadBackedPileup<RBP extends AbstractReadBackedPil
|
||||||
for (int i = 0; i < counts.length; i++)
|
for (int i = 0; i < counts.length; i++)
|
||||||
counts[i] += countsBySample[i];
|
counts[i] += countsBySample[i];
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
for (PileupElement pile : this) {
|
for (PileupElement pile : this) {
|
||||||
// skip deletion sites
|
// skip deletion sites
|
||||||
if (!pile.isDeletion()) {
|
if (!pile.isDeletion()) {
|
||||||
|
|
@ -857,59 +860,74 @@ public abstract class AbstractReadBackedPileup<RBP extends AbstractReadBackedPil
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of the reads in this pileup. Note this call costs O(n) and allocates fresh lists each time
|
* Returns a list of the reads in this pileup. Note this call costs O(n) and allocates fresh lists each time
|
||||||
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<GATKSAMRecord> getReads() {
|
public List<GATKSAMRecord> getReads() {
|
||||||
List<GATKSAMRecord> reads = new ArrayList<GATKSAMRecord>(getNumberOfElements());
|
List<GATKSAMRecord> reads = new ArrayList<GATKSAMRecord>(getNumberOfElements());
|
||||||
for ( PileupElement pile : this ) { reads.add(pile.getRead()); }
|
for (PileupElement pile : this) {
|
||||||
|
reads.add(pile.getRead());
|
||||||
|
}
|
||||||
return reads;
|
return reads;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of the offsets in this pileup. Note this call costs O(n) and allocates fresh lists each time
|
* Returns a list of the offsets in this pileup. Note this call costs O(n) and allocates fresh lists each time
|
||||||
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<Integer> getOffsets() {
|
public List<Integer> getOffsets() {
|
||||||
List<Integer> offsets = new ArrayList<Integer>(getNumberOfElements());
|
List<Integer> offsets = new ArrayList<Integer>(getNumberOfElements());
|
||||||
for ( PileupElement pile : this ) { offsets.add(pile.getOffset()); }
|
for (PileupElement pile : this) {
|
||||||
|
offsets.add(pile.getOffset());
|
||||||
|
}
|
||||||
return offsets;
|
return offsets;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array of the bases in this pileup. Note this call costs O(n) and allocates fresh array each time
|
* Returns an array of the bases in this pileup. Note this call costs O(n) and allocates fresh array each time
|
||||||
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public byte[] getBases() {
|
public byte[] getBases() {
|
||||||
byte[] v = new byte[getNumberOfElements()];
|
byte[] v = new byte[getNumberOfElements()];
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
for ( PileupElement pile : pileupElementTracker ) { v[pos++] = pile.getBase(); }
|
for (PileupElement pile : pileupElementTracker) {
|
||||||
|
v[pos++] = pile.getBase();
|
||||||
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array of the quals in this pileup. Note this call costs O(n) and allocates fresh array each time
|
* Returns an array of the quals in this pileup. Note this call costs O(n) and allocates fresh array each time
|
||||||
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public byte[] getQuals() {
|
public byte[] getQuals() {
|
||||||
byte[] v = new byte[getNumberOfElements()];
|
byte[] v = new byte[getNumberOfElements()];
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
for ( PileupElement pile : pileupElementTracker ) { v[pos++] = pile.getQual(); }
|
for (PileupElement pile : pileupElementTracker) {
|
||||||
|
v[pos++] = pile.getQual();
|
||||||
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an array of the mapping qualities
|
* Get an array of the mapping qualities
|
||||||
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public byte[] getMappingQuals() {
|
public byte[] getMappingQuals() {
|
||||||
byte[] v = new byte[getNumberOfElements()];
|
byte[] v = new byte[getNumberOfElements()];
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
for ( PileupElement pile : pileupElementTracker ) { v[pos++] = (byte)pile.getRead().getMappingQuality(); }
|
for (PileupElement pile : pileupElementTracker) {
|
||||||
|
v[pos++] = (byte) pile.getRead().getMappingQuality();
|
||||||
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import java.util.Arrays;
|
||||||
* are seen on the base-by-base basis (i.e. the pileup does keep the information about the current reference base being deleted
|
* are seen on the base-by-base basis (i.e. the pileup does keep the information about the current reference base being deleted
|
||||||
* in some reads), but the information about the extended event (deletion length, string of all deleted bases) is not kept.
|
* in some reads), but the information about the extended event (deletion length, string of all deleted bases) is not kept.
|
||||||
* The insertions that may be present in some reads are not seen at all in such strict reference traversal mode.
|
* The insertions that may be present in some reads are not seen at all in such strict reference traversal mode.
|
||||||
*
|
* <p/>
|
||||||
* By convention, any extended event (indel) is mapped onto the reference at the last base prior to the event (i.e.
|
* By convention, any extended event (indel) is mapped onto the reference at the last base prior to the event (i.e.
|
||||||
* last base before the insertion or deletion). If the special "extended" traversal mode is turned on and there is
|
* last base before the insertion or deletion). If the special "extended" traversal mode is turned on and there is
|
||||||
* an indel in at least one read that maps onto the reference position Z, the walker's map function will be called twice:
|
* an indel in at least one read that maps onto the reference position Z, the walker's map function will be called twice:
|
||||||
|
|
@ -22,9 +22,9 @@ import java.util.Arrays;
|
||||||
* (covered) reference position. Note that if the extended event at Z was a deletion, the "standard" base pileup at
|
* (covered) reference position. Note that if the extended event at Z was a deletion, the "standard" base pileup at
|
||||||
* Z+1 and following bases may still contain deleted bases. However the fully extended event call will be performed
|
* Z+1 and following bases may still contain deleted bases. However the fully extended event call will be performed
|
||||||
* only once, at the position where the indel maps (starts).
|
* only once, at the position where the indel maps (starts).
|
||||||
*
|
* <p/>
|
||||||
* This class wraps an "extended" event (indel) so that in can be added to a pileup of events at a given location.
|
* This class wraps an "extended" event (indel) so that in can be added to a pileup of events at a given location.
|
||||||
*
|
* <p/>
|
||||||
* Created by IntelliJ IDEA.
|
* Created by IntelliJ IDEA.
|
||||||
* User: asivache
|
* User: asivache
|
||||||
* Date: Dec 21, 2009
|
* Date: Dec 21, 2009
|
||||||
|
|
@ -44,7 +44,18 @@ public class ExtendedEventPileupElement extends PileupElement {
|
||||||
private int offset; // position in the read immediately BEFORE the event
|
private int offset; // position in the read immediately BEFORE the event
|
||||||
// This is broken! offset is always zero because these member variables are shadowed by base class
|
// This is broken! offset is always zero because these member variables are shadowed by base class
|
||||||
|
|
||||||
/** Constructor for extended pileup element (indel).
|
|
||||||
|
public ExtendedEventPileupElement(GATKSAMRecord read, int offset, int eventLength, String eventBases, Type type) {
|
||||||
|
super(read, offset, type == Type.DELETION);
|
||||||
|
this.read = read;
|
||||||
|
this.offset = offset;
|
||||||
|
this.eventLength = eventLength;
|
||||||
|
this.eventBases = eventBases;
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Quick constructor for insertions.
|
||||||
*
|
*
|
||||||
* @param read the read, in which the indel is observed
|
* @param read the read, in which the indel is observed
|
||||||
* @param offset position in the read immediately before the indel (can be -1 if read starts with an insertion)
|
* @param offset position in the read immediately before the indel (can be -1 if read starts with an insertion)
|
||||||
|
|
@ -52,27 +63,28 @@ public class ExtendedEventPileupElement extends PileupElement {
|
||||||
* @param eventBases inserted bases. null indicates that the event is a deletion; ignored if length<=0 (noevent)
|
* @param eventBases inserted bases. null indicates that the event is a deletion; ignored if length<=0 (noevent)
|
||||||
*/
|
*/
|
||||||
public ExtendedEventPileupElement(GATKSAMRecord read, int offset, int length, byte[] eventBases) {
|
public ExtendedEventPileupElement(GATKSAMRecord read, int offset, int length, byte[] eventBases) {
|
||||||
super(read, offset);
|
this(read, offset, length, new String(eventBases).toUpperCase(), Type.INSERTION);
|
||||||
this.eventLength = length;
|
|
||||||
if ( length <= 0 ) type = Type.NOEVENT;
|
|
||||||
else {
|
|
||||||
if ( eventBases != null ) {
|
|
||||||
this.eventBases = new String(eventBases).toUpperCase();
|
|
||||||
type = Type.INSERTION;
|
|
||||||
} else {
|
|
||||||
type = Type.DELETION;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Constructor for deletion or noevent calls - does not take event bases as an argument (as those should
|
/**
|
||||||
* be null or are ignored in these cases anyway)
|
* Quick constructor for non indels (matches)
|
||||||
* @param read
|
*
|
||||||
* @param offset
|
* @param read the read
|
||||||
* @param length
|
* @param offset where in the read the match is
|
||||||
|
*/
|
||||||
|
public ExtendedEventPileupElement(GATKSAMRecord read, int offset) {
|
||||||
|
this(read, offset, -1, null, Type.NOEVENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Quick constructor for deletions
|
||||||
|
*
|
||||||
|
* @param read the read
|
||||||
|
* @param offset the last base before the deletion starts (left aligned deletion)
|
||||||
|
* @param length length of this deletion
|
||||||
*/
|
*/
|
||||||
public ExtendedEventPileupElement(GATKSAMRecord read, int offset, int length) {
|
public ExtendedEventPileupElement(GATKSAMRecord read, int offset, int length) {
|
||||||
this(read,offset, length, null);
|
this(read, offset, length, null, Type.DELETION);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isDeletion() {
|
public boolean isDeletion() {
|
||||||
|
|
@ -87,7 +99,9 @@ public class ExtendedEventPileupElement extends PileupElement {
|
||||||
return isDeletion() || isInsertion();
|
return isDeletion() || isInsertion();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Type getType() { return type; }
|
public Type getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
// The offset can be negative with insertions at the start of the read, but a valid base does exist at this position with
|
// The offset can be negative with insertions at the start of the read, but a valid base does exist at this position with
|
||||||
// a valid base quality. The following code attempts to compensate for that.'
|
// a valid base quality. The following code attempts to compensate for that.'
|
||||||
|
|
@ -107,12 +121,19 @@ public class ExtendedEventPileupElement extends PileupElement {
|
||||||
return getQual(offset >= 0 ? offset : offset + eventLength);
|
return getQual(offset >= 0 ? offset : offset + eventLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns length of the event (number of inserted or deleted bases */
|
/**
|
||||||
public int getEventLength() { return eventLength; }
|
* 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.
|
/**
|
||||||
* */
|
* 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 String getEventBases() {
|
||||||
|
return eventBases;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
|
@ -123,8 +144,7 @@ public class ExtendedEventPileupElement extends PileupElement {
|
||||||
char[] filler = new char[eventLength];
|
char[] filler = new char[eventLength];
|
||||||
Arrays.fill(filler, 'D');
|
Arrays.fill(filler, 'D');
|
||||||
fillStr = new String(filler);
|
fillStr = new String(filler);
|
||||||
}
|
} else if (isInsertion()) c = '+';
|
||||||
else if ( isInsertion() ) c = '+';
|
|
||||||
return String.format("%s @ %d = %c%s MQ%d", getRead().getReadName(), getOffset(), c, isIndel() ?
|
return String.format("%s @ %d = %c%s MQ%d", getRead().getReadName(), getOffset(), c, isIndel() ?
|
||||||
(isInsertion() ? eventBases : fillStr) : "", getMappingQual());
|
(isInsertion() ? eventBases : fillStr) : "", getMappingQual());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package org.broadinstitute.sting.utils.pileup;
|
||||||
import com.google.java.contract.Ensures;
|
import com.google.java.contract.Ensures;
|
||||||
import com.google.java.contract.Requires;
|
import com.google.java.contract.Requires;
|
||||||
import org.broadinstitute.sting.utils.BaseUtils;
|
import org.broadinstitute.sting.utils.BaseUtils;
|
||||||
|
import org.broadinstitute.sting.utils.exceptions.ReviewedStingException;
|
||||||
import org.broadinstitute.sting.utils.sam.GATKSAMRecord;
|
import org.broadinstitute.sting.utils.sam.GATKSAMRecord;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -21,25 +22,61 @@ public class PileupElement implements Comparable<PileupElement> {
|
||||||
|
|
||||||
protected final GATKSAMRecord read;
|
protected final GATKSAMRecord read;
|
||||||
protected final int offset;
|
protected final int offset;
|
||||||
|
protected final boolean isDeletion;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new pileup element.
|
||||||
|
*
|
||||||
|
* @param read the read we are adding to the pileup
|
||||||
|
* @param offset the position in the read for this base. All deletions must be left aligned! (-1 is only allowed for reads starting with insertions)
|
||||||
|
* @param isDeletion whether or not this base is a deletion
|
||||||
|
*/
|
||||||
@Requires({
|
@Requires({
|
||||||
"read != null",
|
"read != null",
|
||||||
"offset >= -1",
|
"offset >= -1",
|
||||||
"offset <= read.getReadLength()"})
|
"offset <= read.getReadLength()"})
|
||||||
public PileupElement( GATKSAMRecord read, int offset ) {
|
public PileupElement(GATKSAMRecord read, int offset, boolean isDeletion) {
|
||||||
|
if (offset < 0 && isDeletion)
|
||||||
|
throw new ReviewedStingException("Pileup Element cannot create a deletion with a negative offset");
|
||||||
|
|
||||||
this.read = read;
|
this.read = read;
|
||||||
this.offset = offset;
|
this.offset = offset;
|
||||||
|
this.isDeletion = isDeletion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * Creates a NON DELETION pileup element.
|
||||||
|
// *
|
||||||
|
// * use this constructor only for insertions and matches/mismatches.
|
||||||
|
// * @param read the read we are adding to the pileup
|
||||||
|
// * @param offset the position in the read for this base. All deletions must be left aligned! (-1 is only allowed for reads starting with insertions)
|
||||||
|
// */
|
||||||
|
// @Requires({
|
||||||
|
// "read != null",
|
||||||
|
// "offset >= -1",
|
||||||
|
// "offset <= read.getReadLength()"})
|
||||||
|
// public PileupElement( GATKSAMRecord read, int offset ) {
|
||||||
|
// this(read, offset, false);
|
||||||
|
// }
|
||||||
|
//
|
||||||
public boolean isDeletion() {
|
public boolean isDeletion() {
|
||||||
|
return isDeletion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isInsertionAtBeginningOfRead() {
|
||||||
return offset == -1;
|
return offset == -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ensures("result != null")
|
@Ensures("result != null")
|
||||||
public GATKSAMRecord getRead() { return read; }
|
public GATKSAMRecord getRead() {
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
|
||||||
@Ensures("result == offset")
|
@Ensures("result == offset")
|
||||||
public int getOffset() { return offset; }
|
public int getOffset() {
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
public byte getBase() {
|
public byte getBase() {
|
||||||
return getBase(offset);
|
return getBase(offset);
|
||||||
|
|
@ -63,15 +100,15 @@ public class PileupElement implements Comparable<PileupElement> {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected byte getBase(final int offset) {
|
protected byte getBase(final int offset) {
|
||||||
return isDeletion() ? DELETION_BASE : read.getReadBases()[offset];
|
return (isDeletion() || isInsertionAtBeginningOfRead()) ? DELETION_BASE : read.getReadBases()[offset];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int getBaseIndex(final int offset) {
|
protected int getBaseIndex(final int offset) {
|
||||||
return BaseUtils.simpleBaseToBaseIndex(isDeletion() ? DELETION_BASE : read.getReadBases()[offset]);
|
return BaseUtils.simpleBaseToBaseIndex((isDeletion() || isInsertionAtBeginningOfRead()) ? DELETION_BASE : read.getReadBases()[offset]);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected byte getQual(final int offset) {
|
protected byte getQual(final int offset) {
|
||||||
return isDeletion() ? DELETION_QUAL : read.getBaseQualities()[offset];
|
return (isDeletion() || isInsertionAtBeginningOfRead()) ? DELETION_QUAL : read.getBaseQualities()[offset];
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -94,13 +131,26 @@ public class PileupElement implements Comparable<PileupElement> {
|
||||||
//
|
//
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
public boolean isReducedRead() {
|
// public boolean isReducedRead() {
|
||||||
return read.isReducedRead();
|
// return read.isReducedRead();
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of elements in the pileup element.
|
||||||
|
* <p/>
|
||||||
|
* Unless this is a reduced read, the number of elements in a pileup element is one. In the event of
|
||||||
|
* this being a reduced read and a deletion, we return the average number of elements between the left
|
||||||
|
* and right elements to the deletion. We assume the deletion to be left aligned.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public int getRepresentativeCount() {
|
public int getRepresentativeCount() {
|
||||||
// TODO -- if we ever decide to reduce the representation of deletions then this will need to be fixed
|
int representativeCount = 1;
|
||||||
return (!isDeletion() && isReducedRead()) ? read.getReducedCount(offset) : 1;
|
|
||||||
|
if (read.isReducedRead() && !isInsertionAtBeginningOfRead())
|
||||||
|
representativeCount = (isDeletion()) ? Math.round((read.getReducedCount(offset) + read.getReducedCount(offset + 1)) / 2) : read.getReducedCount(offset);
|
||||||
|
|
||||||
|
return representativeCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -44,6 +44,7 @@ public class ReadBackedExtendedEventPileupImpl extends AbstractReadBackedPileup<
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optimization of above constructor where all of the cached data is provided
|
* Optimization of above constructor where all of the cached data is provided
|
||||||
|
*
|
||||||
* @param loc
|
* @param loc
|
||||||
* @param pileup
|
* @param pileup
|
||||||
*/
|
*/
|
||||||
|
|
@ -95,7 +96,7 @@ public class ReadBackedExtendedEventPileupImpl extends AbstractReadBackedPileup<
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ExtendedEventPileupElement createNewPileupElement(GATKSAMRecord read, int offset) {
|
protected ExtendedEventPileupElement createNewPileupElement(GATKSAMRecord read, int offset, boolean isDeletion) {
|
||||||
throw new UnsupportedOperationException("Not enough information provided to create a new pileup element");
|
throw new UnsupportedOperationException("Not enough information provided to create a new pileup element");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -110,10 +111,12 @@ public class ReadBackedExtendedEventPileupImpl extends AbstractReadBackedPileup<
|
||||||
return nInsertions;
|
return nInsertions;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the length of the longest deletion observed at the site this
|
/**
|
||||||
|
* Returns the length of the longest deletion observed at the site this
|
||||||
* pileup is associated with (NOTE: by convention, both insertions and deletions
|
* pileup is associated with (NOTE: by convention, both insertions and deletions
|
||||||
* are associated with genomic location immediately before the actual event). If
|
* are associated with genomic location immediately before the actual event). If
|
||||||
* there are no deletions at the site, returns 0.
|
* there are no deletions at the site, returns 0.
|
||||||
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -123,12 +126,15 @@ public class ReadBackedExtendedEventPileupImpl extends AbstractReadBackedPileup<
|
||||||
|
|
||||||
public Iterable<ExtendedEventPileupElement> toExtendedIterable() {
|
public Iterable<ExtendedEventPileupElement> toExtendedIterable() {
|
||||||
return new Iterable<ExtendedEventPileupElement>() {
|
return new Iterable<ExtendedEventPileupElement>() {
|
||||||
public Iterator<ExtendedEventPileupElement> iterator() { return pileupElementTracker.iterator(); }
|
public Iterator<ExtendedEventPileupElement> iterator() {
|
||||||
|
return pileupElementTracker.iterator();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array of the events in this pileup ('I', 'D', or '.'). Note this call costs O(n) and allocates fresh array each time
|
* Returns an array of the events in this pileup ('I', 'D', or '.'). Note this call costs O(n) and allocates fresh array each time
|
||||||
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -137,17 +143,25 @@ public class ReadBackedExtendedEventPileupImpl extends AbstractReadBackedPileup<
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (ExtendedEventPileupElement e : this.toExtendedIterable()) {
|
for (ExtendedEventPileupElement e : this.toExtendedIterable()) {
|
||||||
switch (e.getType()) {
|
switch (e.getType()) {
|
||||||
case INSERTION: v[i] = 'I'; break;
|
case INSERTION:
|
||||||
case DELETION: v[i] = 'D'; break;
|
v[i] = 'I';
|
||||||
case NOEVENT: v[i] = '.'; break;
|
break;
|
||||||
default: throw new ReviewedStingException("Unknown event type encountered: "+e.getType());
|
case DELETION:
|
||||||
|
v[i] = 'D';
|
||||||
|
break;
|
||||||
|
case NOEVENT:
|
||||||
|
v[i] = '.';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ReviewedStingException("Unknown event type encountered: " + e.getType());
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A shortcut for getEventStringsWithCounts(null);
|
/**
|
||||||
|
* A shortcut for getEventStringsWithCounts(null);
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
@ -166,10 +180,12 @@ public class ReadBackedExtendedEventPileupImpl extends AbstractReadBackedPileup<
|
||||||
new String(getEvents()));
|
new String(getEvents()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns String representation of all distinct extended events (indels) at the site along with
|
/**
|
||||||
|
* Returns String representation of all distinct extended events (indels) at the site along with
|
||||||
* observation counts (numbers of reads) for each distinct event. If refBases is null, a simple string representation for
|
* observation counts (numbers of reads) for each distinct event. If refBases is null, a simple string representation for
|
||||||
* deletions will be generated as "<length>D" (i.e. "5D"); if the reference bases are provided, the actual
|
* deletions will be generated as "<length>D" (i.e. "5D"); if the reference bases are provided, the actual
|
||||||
* deleted sequence will be used in the string representation (e.g. "-AAC").
|
* deleted sequence will be used in the string representation (e.g. "-AAC").
|
||||||
|
*
|
||||||
* @param refBases reference bases, starting with the current locus (i.e. the one immediately before the indel), and
|
* @param refBases reference bases, starting with the current locus (i.e. the one immediately before the indel), and
|
||||||
* extending far enough to accomodate the longest deletion (i.e. size of refBases must be at least 1+<length of longest deletion>)
|
* extending far enough to accomodate the longest deletion (i.e. size of refBases must be at least 1+<length of longest deletion>)
|
||||||
* @return list of distinct events; first element of a pair is a string representation of the event, second element
|
* @return list of distinct events; first element of a pair is a string representation of the event, second element
|
||||||
|
|
@ -189,8 +205,10 @@ public class ReadBackedExtendedEventPileupImpl extends AbstractReadBackedPileup<
|
||||||
case DELETION:
|
case DELETION:
|
||||||
indel = getDeletionString(e.getEventLength(), refBases);
|
indel = getDeletionString(e.getEventLength(), refBases);
|
||||||
break;
|
break;
|
||||||
case NOEVENT: continue;
|
case NOEVENT:
|
||||||
default: throw new ReviewedStingException("Unknown event type encountered: "+e.getType());
|
continue;
|
||||||
|
default:
|
||||||
|
throw new ReviewedStingException("Unknown event type encountered: " + e.getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
cnt = events.get(indel);
|
cnt = events.get(indel);
|
||||||
|
|
@ -211,6 +229,7 @@ public class ReadBackedExtendedEventPileupImpl extends AbstractReadBackedPileup<
|
||||||
* will be generated. NOTE: refBases must start with the base prior to the actual deletion (i.e. deleted
|
* will be generated. NOTE: refBases must start with the base prior to the actual deletion (i.e. deleted
|
||||||
* base(s) are refBase[1], refBase[2], ...), and the length of the passed array must be sufficient to accomodate the
|
* base(s) are refBase[1], refBase[2], ...), and the length of the passed array must be sufficient to accomodate the
|
||||||
* deletion length (i.e. size of refBase must be at least length+1).
|
* deletion length (i.e. size of refBase must be at least length+1).
|
||||||
|
*
|
||||||
* @param length
|
* @param length
|
||||||
* @param refBases
|
* @param refBases
|
||||||
* @return
|
* @return
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ public class ReadBackedPileupImpl extends AbstractReadBackedPileup<ReadBackedPil
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optimization of above constructor where all of the cached data is provided
|
* Optimization of above constructor where all of the cached data is provided
|
||||||
|
*
|
||||||
* @param loc
|
* @param loc
|
||||||
* @param pileup
|
* @param pileup
|
||||||
*/
|
*/
|
||||||
|
|
@ -70,7 +71,7 @@ public class ReadBackedPileupImpl extends AbstractReadBackedPileup<ReadBackedPil
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected PileupElement createNewPileupElement(GATKSAMRecord read, int offset) {
|
protected PileupElement createNewPileupElement(GATKSAMRecord read, int offset, boolean isDeletion) {
|
||||||
return new PileupElement(read,offset);
|
return new PileupElement(read, offset, isDeletion);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -100,14 +100,16 @@ public class AlignmentUtils {
|
||||||
case H:
|
case H:
|
||||||
case P:
|
case P:
|
||||||
break;
|
break;
|
||||||
default: throw new ReviewedStingException("The " + ce.getOperator() + " cigar element is not currently supported");
|
default:
|
||||||
|
throw new ReviewedStingException("The " + ce.getOperator() + " cigar element is not currently supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return mc;
|
return mc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the number of mismatches in the pileup within the given reference context.
|
/**
|
||||||
|
* Returns the number of mismatches in the pileup within the given reference context.
|
||||||
*
|
*
|
||||||
* @param pileup the pileup with reads
|
* @param pileup the pileup with reads
|
||||||
* @param ref the reference context
|
* @param ref the reference context
|
||||||
|
|
@ -121,7 +123,8 @@ public class AlignmentUtils {
|
||||||
return mismatches;
|
return mismatches;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the number of mismatches in the pileup element within the given reference context.
|
/**
|
||||||
|
* Returns the number of mismatches in the pileup element within the given reference context.
|
||||||
*
|
*
|
||||||
* @param p the pileup element
|
* @param p the pileup element
|
||||||
* @param ref the reference context
|
* @param ref the reference context
|
||||||
|
|
@ -132,12 +135,14 @@ public class AlignmentUtils {
|
||||||
return mismatchesInRefWindow(p, ref, ignoreTargetSite, false);
|
return mismatchesInRefWindow(p, ref, ignoreTargetSite, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the number of mismatches in the pileup element within the given reference context.
|
/**
|
||||||
|
* Returns the number of mismatches in the pileup element within the given reference context.
|
||||||
*
|
*
|
||||||
* @param p the pileup element
|
* @param p the pileup element
|
||||||
* @param ref the reference context
|
* @param ref the reference context
|
||||||
* @param ignoreTargetSite if true, ignore mismatches at the target locus (i.e. the center of the window)
|
* @param ignoreTargetSite if true, ignore mismatches at the target locus (i.e. the center of the window)
|
||||||
* @param qualitySumInsteadOfMismatchCount if true, return the quality score sum of the mismatches rather than the count
|
* @param qualitySumInsteadOfMismatchCount
|
||||||
|
* if true, return the quality score sum of the mismatches rather than the count
|
||||||
* @return the number of mismatches
|
* @return the number of mismatches
|
||||||
*/
|
*/
|
||||||
public static int mismatchesInRefWindow(PileupElement p, ReferenceContext ref, boolean ignoreTargetSite, boolean qualitySumInsteadOfMismatchCount) {
|
public static int mismatchesInRefWindow(PileupElement p, ReferenceContext ref, boolean ignoreTargetSite, boolean qualitySumInsteadOfMismatchCount) {
|
||||||
|
|
@ -198,7 +203,8 @@ public class AlignmentUtils {
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the number of mismatches in the pileup element within the given reference context.
|
/**
|
||||||
|
* Returns the number of mismatches in the pileup element within the given reference context.
|
||||||
*
|
*
|
||||||
* @param read the SAMRecord
|
* @param read the SAMRecord
|
||||||
* @param ref the reference context
|
* @param ref the reference context
|
||||||
|
|
@ -301,11 +307,14 @@ public class AlignmentUtils {
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
/** Returns number of alignment blocks (continuous stretches of aligned bases) in the specified alignment.
|
|
||||||
|
/**
|
||||||
|
* Returns number of alignment blocks (continuous stretches of aligned bases) in the specified alignment.
|
||||||
* This method follows closely the SAMRecord::getAlignmentBlocks() implemented in samtools library, but
|
* This method follows closely the SAMRecord::getAlignmentBlocks() implemented in samtools library, but
|
||||||
* it only counts blocks without actually allocating and filling the list of blocks themselves. Hence, this method is
|
* it only counts blocks without actually allocating and filling the list of blocks themselves. Hence, this method is
|
||||||
* a much more efficient alternative to r.getAlignmentBlocks.size() in the situations when this number is all that is needed.
|
* a much more efficient alternative to r.getAlignmentBlocks.size() in the situations when this number is all that is needed.
|
||||||
* Formally, this method simply returns the number of M elements in the cigar.
|
* Formally, this method simply returns the number of M elements in the cigar.
|
||||||
|
*
|
||||||
* @param r alignment
|
* @param r alignment
|
||||||
* @return number of continuous alignment blocks (i.e. 'M' elements of the cigar; all indel and clipping elements are ignored).
|
* @return number of continuous alignment blocks (i.e. 'M' elements of the cigar; all indel and clipping elements are ignored).
|
||||||
*/
|
*/
|
||||||
|
|
@ -326,9 +335,9 @@ public class AlignmentUtils {
|
||||||
final Cigar cigar = r.getCigar();
|
final Cigar cigar = r.getCigar();
|
||||||
if (cigar == null) return 0;
|
if (cigar == null) return 0;
|
||||||
|
|
||||||
for (final CigarElement e : cigar.getCigarElements()) {
|
for (final CigarElement e : cigar.getCigarElements())
|
||||||
if (e.getOperator() == CigarOperator.M ) { n += e.getLength(); }
|
if (e.getOperator() == CigarOperator.M)
|
||||||
}
|
n += e.getLength();
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
@ -372,21 +381,26 @@ public class AlignmentUtils {
|
||||||
return alignment;
|
return alignment;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int calcAlignmentByteArrayOffset( final Cigar cigar, int pileupOffset, final int alignmentStart, final int refLocus ) {
|
public static int calcAlignmentByteArrayOffset(final Cigar cigar, PileupElement pileup, final int alignmentStart, final int refLocus) {
|
||||||
|
int pileupOffset = pileup.getOffset();
|
||||||
|
|
||||||
boolean atDeletion = false;
|
// Special case for reads starting with insertion
|
||||||
if(pileupOffset == -1) {
|
if (pileup.isInsertionAtBeginningOfRead())
|
||||||
atDeletion = true;
|
return 0;
|
||||||
|
|
||||||
|
// Reassign the offset if we are in the middle of a deletion because of the modified representation of the read bases
|
||||||
|
if (pileup.isDeletion()) {
|
||||||
pileupOffset = refLocus - alignmentStart;
|
pileupOffset = refLocus - alignmentStart;
|
||||||
final CigarElement ce = cigar.getCigarElement(0);
|
final CigarElement ce = cigar.getCigarElement(0);
|
||||||
if (ce.getOperator() == CigarOperator.S) {
|
if (ce.getOperator() == CigarOperator.S) {
|
||||||
pileupOffset += ce.getLength();
|
pileupOffset += ce.getLength();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
int alignmentPos = 0;
|
int alignmentPos = 0;
|
||||||
for ( int iii = 0 ; iii < cigar.numCigarElements() ; iii++ ) {
|
|
||||||
|
|
||||||
|
for (int iii = 0; iii < cigar.numCigarElements(); iii++) {
|
||||||
final CigarElement ce = cigar.getCigarElement(iii);
|
final CigarElement ce = cigar.getCigarElement(iii);
|
||||||
final int elementLength = ce.getLength();
|
final int elementLength = ce.getLength();
|
||||||
|
|
||||||
|
|
@ -400,7 +414,7 @@ public class AlignmentUtils {
|
||||||
break;
|
break;
|
||||||
case D:
|
case D:
|
||||||
case N:
|
case N:
|
||||||
if(!atDeletion) {
|
if (!pileup.isDeletion()) {
|
||||||
alignmentPos += elementLength;
|
alignmentPos += elementLength;
|
||||||
} else {
|
} else {
|
||||||
if (pos + elementLength - 1 >= pileupOffset) {
|
if (pos + elementLength - 1 >= pileupOffset) {
|
||||||
|
|
@ -426,6 +440,7 @@ public class AlignmentUtils {
|
||||||
throw new ReviewedStingException("Unsupported cigar operator: " + ce.getOperator());
|
throw new ReviewedStingException("Unsupported cigar operator: " + ce.getOperator());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return alignmentPos;
|
return alignmentPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -467,10 +482,15 @@ public class AlignmentUtils {
|
||||||
switch (ce.getOperator()) {
|
switch (ce.getOperator()) {
|
||||||
case I:
|
case I:
|
||||||
if (alignPos > 0) {
|
if (alignPos > 0) {
|
||||||
if( alignment[alignPos-1] == BaseUtils.A ) { alignment[alignPos-1] = PileupElement.A_FOLLOWED_BY_INSERTION_BASE; }
|
if (alignment[alignPos - 1] == BaseUtils.A) {
|
||||||
else if( alignment[alignPos-1] == BaseUtils.C ) { alignment[alignPos-1] = PileupElement.C_FOLLOWED_BY_INSERTION_BASE; }
|
alignment[alignPos - 1] = PileupElement.A_FOLLOWED_BY_INSERTION_BASE;
|
||||||
else if( alignment[alignPos-1] == BaseUtils.T ) { alignment[alignPos-1] = PileupElement.T_FOLLOWED_BY_INSERTION_BASE; }
|
} else if (alignment[alignPos - 1] == BaseUtils.C) {
|
||||||
else if( alignment[alignPos-1] == BaseUtils.G ) { alignment[alignPos-1] = PileupElement.G_FOLLOWED_BY_INSERTION_BASE; }
|
alignment[alignPos - 1] = PileupElement.C_FOLLOWED_BY_INSERTION_BASE;
|
||||||
|
} else if (alignment[alignPos - 1] == BaseUtils.T) {
|
||||||
|
alignment[alignPos - 1] = PileupElement.T_FOLLOWED_BY_INSERTION_BASE;
|
||||||
|
} else if (alignment[alignPos - 1] == BaseUtils.G) {
|
||||||
|
alignment[alignPos - 1] = PileupElement.G_FOLLOWED_BY_INSERTION_BASE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case S:
|
case S:
|
||||||
for (int jjj = 0; jjj < elementLength; jjj++) {
|
for (int jjj = 0; jjj < elementLength; jjj++) {
|
||||||
|
|
@ -505,6 +525,7 @@ public class AlignmentUtils {
|
||||||
* Due to (unfortunate) multiple ways to indicate that read is unmapped allowed by SAM format
|
* Due to (unfortunate) multiple ways to indicate that read is unmapped allowed by SAM format
|
||||||
* specification, one may need this convenience shortcut. Checks both 'read unmapped' flag and
|
* specification, one may need this convenience shortcut. Checks both 'read unmapped' flag and
|
||||||
* alignment reference index/start.
|
* alignment reference index/start.
|
||||||
|
*
|
||||||
* @param r record
|
* @param r record
|
||||||
* @return true if read is unmapped
|
* @return true if read is unmapped
|
||||||
*/
|
*/
|
||||||
|
|
@ -527,6 +548,7 @@ public class AlignmentUtils {
|
||||||
* Due to (unfortunate) multiple ways to indicate that read/mate is unmapped allowed by SAM format
|
* Due to (unfortunate) multiple ways to indicate that read/mate is unmapped allowed by SAM format
|
||||||
* specification, one may need this convenience shortcut. Checks both 'mate unmapped' flag and
|
* specification, one may need this convenience shortcut. Checks both 'mate unmapped' flag and
|
||||||
* alignment reference index/start of the mate.
|
* alignment reference index/start of the mate.
|
||||||
|
*
|
||||||
* @param r sam record for the read
|
* @param r sam record for the read
|
||||||
* @return true if read's mate is unmapped
|
* @return true if read's mate is unmapped
|
||||||
*/
|
*/
|
||||||
|
|
@ -545,7 +567,8 @@ public class AlignmentUtils {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns true is read is mapped and mapped uniquely (Q>0).
|
/**
|
||||||
|
* Returns true is read is mapped and mapped uniquely (Q>0).
|
||||||
*
|
*
|
||||||
* @param read
|
* @param read
|
||||||
* @return
|
* @return
|
||||||
|
|
@ -554,10 +577,12 @@ public class AlignmentUtils {
|
||||||
return (!AlignmentUtils.isReadUnmapped(read)) && read.getMappingQuality() > 0;
|
return (!AlignmentUtils.isReadUnmapped(read)) && read.getMappingQuality() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the array of base qualitites in the order the bases were read on the machine (i.e. always starting from
|
/**
|
||||||
|
* Returns the array of base qualitites in the order the bases were read on the machine (i.e. always starting from
|
||||||
* cycle 1). In other words, if the read is unmapped or aligned in the forward direction, the read's own base
|
* cycle 1). In other words, if the read is unmapped or aligned in the forward direction, the read's own base
|
||||||
* qualities are returned as stored in the SAM record; if the read is aligned in the reverse direction, the array
|
* qualities are returned as stored in the SAM record; if the read is aligned in the reverse direction, the array
|
||||||
* of read's base qualitites is inverted (in this case new array is allocated and returned).
|
* of read's base qualitites is inverted (in this case new array is allocated and returned).
|
||||||
|
*
|
||||||
* @param read
|
* @param read
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
@ -567,11 +592,13 @@ public class AlignmentUtils {
|
||||||
return Utils.reverse(read.getBaseQualities());
|
return Utils.reverse(read.getBaseQualities());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the array of original base qualitites (before recalibration) in the order the bases were read on the machine (i.e. always starting from
|
/**
|
||||||
|
* Returns the array of original base qualitites (before recalibration) in the order the bases were read on the machine (i.e. always starting from
|
||||||
* cycle 1). In other words, if the read is unmapped or aligned in the forward direction, the read's own base
|
* cycle 1). In other words, if the read is unmapped or aligned in the forward direction, the read's own base
|
||||||
* qualities are returned as stored in the SAM record; if the read is aligned in the reverse direction, the array
|
* qualities are returned as stored in the SAM record; if the read is aligned in the reverse direction, the array
|
||||||
* of read's base qualitites is inverted (in this case new array is allocated and returned). If no original base qualities
|
* of read's base qualitites is inverted (in this case new array is allocated and returned). If no original base qualities
|
||||||
* are available this method will throw a runtime exception.
|
* are available this method will throw a runtime exception.
|
||||||
|
*
|
||||||
* @param read
|
* @param read
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
@ -581,18 +608,20 @@ public class AlignmentUtils {
|
||||||
return Utils.reverse(read.getOriginalBaseQualities());
|
return Utils.reverse(read.getOriginalBaseQualities());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Takes the alignment of the read sequence <code>readSeq</code> to the reference sequence <code>refSeq</code>
|
/**
|
||||||
|
* Takes the alignment of the read sequence <code>readSeq</code> to the reference sequence <code>refSeq</code>
|
||||||
* starting at 0-based position <code>refIndex</code> on the <code>refSeq</code> and specified by its <code>cigar</code>.
|
* starting at 0-based position <code>refIndex</code> on the <code>refSeq</code> and specified by its <code>cigar</code>.
|
||||||
* The last argument <code>readIndex</code> specifies 0-based position on the read where the alignment described by the
|
* The last argument <code>readIndex</code> specifies 0-based position on the read where the alignment described by the
|
||||||
* <code>cigar</code> starts. Usually cigars specify alignments of the whole read to the ref, so that readIndex is normally 0.
|
* <code>cigar</code> starts. Usually cigars specify alignments of the whole read to the ref, so that readIndex is normally 0.
|
||||||
* Use non-zero readIndex only when the alignment cigar represents alignment of a part of the read. The refIndex in this case
|
* Use non-zero readIndex only when the alignment cigar represents alignment of a part of the read. The refIndex in this case
|
||||||
* should be the position where the alignment of that part of the read starts at. In other words, both refIndex and readIndex are
|
* should be the position where the alignment of that part of the read starts at. In other words, both refIndex and readIndex are
|
||||||
* always the positions where the cigar starts on the ref and on the read, respectively.
|
* always the positions where the cigar starts on the ref and on the read, respectively.
|
||||||
*
|
* <p/>
|
||||||
* If the alignment has an indel, then this method attempts moving this indel left across a stretch of repetitive bases. For instance, if the original cigar
|
* If the alignment has an indel, then this method attempts moving this indel left across a stretch of repetitive bases. For instance, if the original cigar
|
||||||
* specifies that (any) one AT is deleted from a repeat sequence TATATATA, the output cigar will always mark the leftmost AT
|
* specifies that (any) one AT is deleted from a repeat sequence TATATATA, the output cigar will always mark the leftmost AT
|
||||||
* as deleted. If there is no indel in the original cigar, or the indel position is determined unambiguously (i.e. inserted/deleted sequence
|
* as deleted. If there is no indel in the original cigar, or the indel position is determined unambiguously (i.e. inserted/deleted sequence
|
||||||
* is not repeated), the original cigar is returned.
|
* is not repeated), the original cigar is returned.
|
||||||
|
*
|
||||||
* @param cigar structure of the original alignment
|
* @param cigar structure of the original alignment
|
||||||
* @param refSeq reference sequence the read is aligned to
|
* @param refSeq reference sequence the read is aligned to
|
||||||
* @param readSeq read sequence
|
* @param readSeq read sequence
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,6 @@ public class ArtificialSAMUtils {
|
||||||
* @param numberOfChromosomes the number of chromosomes to create
|
* @param numberOfChromosomes the number of chromosomes to create
|
||||||
* @param startingChromosome the starting number for the chromosome (most likely set to 1)
|
* @param startingChromosome the starting number for the chromosome (most likely set to 1)
|
||||||
* @param chromosomeSize the length of each chromosome
|
* @param chromosomeSize the length of each chromosome
|
||||||
*
|
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static SAMFileHeader createArtificialSamHeader(int numberOfChromosomes, int startingChromosome, int chromosomeSize) {
|
public static SAMFileHeader createArtificialSamHeader(int numberOfChromosomes, int startingChromosome, int chromosomeSize) {
|
||||||
|
|
@ -95,7 +94,6 @@ public class ArtificialSAMUtils {
|
||||||
* @param header the header to set
|
* @param header the header to set
|
||||||
* @param readGroupID the read group ID tag
|
* @param readGroupID the read group ID tag
|
||||||
* @param sampleName the sample name
|
* @param sampleName the sample name
|
||||||
*
|
|
||||||
* @return the adjusted SAMFileHeader
|
* @return the adjusted SAMFileHeader
|
||||||
*/
|
*/
|
||||||
public static SAMFileHeader createDefaultReadGroup(SAMFileHeader header, String readGroupID, String sampleName) {
|
public static SAMFileHeader createDefaultReadGroup(SAMFileHeader header, String readGroupID, String sampleName) {
|
||||||
|
|
@ -113,7 +111,6 @@ public class ArtificialSAMUtils {
|
||||||
* @param header the header to set
|
* @param header the header to set
|
||||||
* @param readGroupIDs the read group ID tags
|
* @param readGroupIDs the read group ID tags
|
||||||
* @param sampleNames the sample names
|
* @param sampleNames the sample names
|
||||||
*
|
|
||||||
* @return the adjusted SAMFileHeader
|
* @return the adjusted SAMFileHeader
|
||||||
*/
|
*/
|
||||||
public static SAMFileHeader createEnumeratedReadGroups(SAMFileHeader header, List<String> readGroupIDs, List<String> sampleNames) {
|
public static SAMFileHeader createEnumeratedReadGroups(SAMFileHeader header, List<String> readGroupIDs, List<String> sampleNames) {
|
||||||
|
|
@ -137,13 +134,11 @@ public class ArtificialSAMUtils {
|
||||||
/**
|
/**
|
||||||
* Create an artificial read based on the parameters. The cigar string will be *M, where * is the length of the read
|
* Create an artificial read based on the parameters. The cigar string will be *M, where * is the length of the read
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* @param header the SAM header to associate the read with
|
* @param header the SAM header to associate the read with
|
||||||
* @param name the name of the read
|
* @param name the name of the read
|
||||||
* @param refIndex the reference index, i.e. what chromosome to associate it with
|
* @param refIndex the reference index, i.e. what chromosome to associate it with
|
||||||
* @param alignmentStart where to start the alignment
|
* @param alignmentStart where to start the alignment
|
||||||
* @param length the length of the read
|
* @param length the length of the read
|
||||||
*
|
|
||||||
* @return the artificial read
|
* @return the artificial read
|
||||||
*/
|
*/
|
||||||
public static GATKSAMRecord createArtificialRead(SAMFileHeader header, String name, int refIndex, int alignmentStart, int length) {
|
public static GATKSAMRecord createArtificialRead(SAMFileHeader header, String name, int refIndex, int alignmentStart, int length) {
|
||||||
|
|
@ -183,7 +178,6 @@ public class ArtificialSAMUtils {
|
||||||
* @param alignmentStart where to start the alignment
|
* @param alignmentStart where to start the alignment
|
||||||
* @param bases the sequence of the read
|
* @param bases the sequence of the read
|
||||||
* @param qual the qualities of the read
|
* @param qual the qualities of the read
|
||||||
*
|
|
||||||
* @return the artificial read
|
* @return the artificial read
|
||||||
*/
|
*/
|
||||||
public static GATKSAMRecord createArtificialRead(SAMFileHeader header, String name, int refIndex, int alignmentStart, byte[] bases, byte[] qual) {
|
public static GATKSAMRecord createArtificialRead(SAMFileHeader header, String name, int refIndex, int alignmentStart, byte[] bases, byte[] qual) {
|
||||||
|
|
@ -210,7 +204,6 @@ public class ArtificialSAMUtils {
|
||||||
* @param bases the sequence of the read
|
* @param bases the sequence of the read
|
||||||
* @param qual the qualities of the read
|
* @param qual the qualities of the read
|
||||||
* @param cigar the cigar string of the read
|
* @param cigar the cigar string of the read
|
||||||
*
|
|
||||||
* @return the artificial read
|
* @return the artificial read
|
||||||
*/
|
*/
|
||||||
public static GATKSAMRecord createArtificialRead(SAMFileHeader header, String name, int refIndex, int alignmentStart, byte[] bases, byte[] qual, String cigar) {
|
public static GATKSAMRecord createArtificialRead(SAMFileHeader header, String name, int refIndex, int alignmentStart, byte[] bases, byte[] qual, String cigar) {
|
||||||
|
|
@ -233,7 +226,6 @@ public class ArtificialSAMUtils {
|
||||||
* @param bases the sequence of the read
|
* @param bases the sequence of the read
|
||||||
* @param qual the qualities of the read
|
* @param qual the qualities of the read
|
||||||
* @param cigar the cigar string of the read
|
* @param cigar the cigar string of the read
|
||||||
*
|
|
||||||
* @return the artificial read
|
* @return the artificial read
|
||||||
*/
|
*/
|
||||||
public static GATKSAMRecord createArtificialRead(byte[] bases, byte[] qual, String cigar) {
|
public static GATKSAMRecord createArtificialRead(byte[] bases, byte[] qual, String cigar) {
|
||||||
|
|
@ -279,7 +271,6 @@ public class ArtificialSAMUtils {
|
||||||
* @param startingChr the chromosome (reference ID) to start from
|
* @param startingChr the chromosome (reference ID) to start from
|
||||||
* @param endingChr the id to end with
|
* @param endingChr the id to end with
|
||||||
* @param readCount the number of reads per chromosome
|
* @param readCount the number of reads per chromosome
|
||||||
*
|
|
||||||
* @return StingSAMIterator representing the specified amount of fake data
|
* @return StingSAMIterator representing the specified amount of fake data
|
||||||
*/
|
*/
|
||||||
public static StingSAMIterator mappedReadIterator(int startingChr, int endingChr, int readCount) {
|
public static StingSAMIterator mappedReadIterator(int startingChr, int endingChr, int readCount) {
|
||||||
|
|
@ -295,7 +286,6 @@ public class ArtificialSAMUtils {
|
||||||
* @param endingChr the id to end with
|
* @param endingChr the id to end with
|
||||||
* @param readCount the number of reads per chromosome
|
* @param readCount the number of reads per chromosome
|
||||||
* @param unmappedReadCount the count of unmapped reads to place at the end of the iterator, like in a sorted bam file
|
* @param unmappedReadCount the count of unmapped reads to place at the end of the iterator, like in a sorted bam file
|
||||||
*
|
|
||||||
* @return StingSAMIterator representing the specified amount of fake data
|
* @return StingSAMIterator representing the specified amount of fake data
|
||||||
*/
|
*/
|
||||||
public static StingSAMIterator mappedAndUnmappedReadIterator(int startingChr, int endingChr, int readCount, int unmappedReadCount) {
|
public static StingSAMIterator mappedAndUnmappedReadIterator(int startingChr, int endingChr, int readCount, int unmappedReadCount) {
|
||||||
|
|
@ -310,7 +300,6 @@ public class ArtificialSAMUtils {
|
||||||
* @param startingChr the chromosome (reference ID) to start from
|
* @param startingChr the chromosome (reference ID) to start from
|
||||||
* @param endingChr the id to end with
|
* @param endingChr the id to end with
|
||||||
* @param readCount the number of reads per chromosome
|
* @param readCount the number of reads per chromosome
|
||||||
*
|
|
||||||
* @return StingSAMIterator representing the specified amount of fake data
|
* @return StingSAMIterator representing the specified amount of fake data
|
||||||
*/
|
*/
|
||||||
public static ArtificialSAMQueryIterator queryReadIterator(int startingChr, int endingChr, int readCount) {
|
public static ArtificialSAMQueryIterator queryReadIterator(int startingChr, int endingChr, int readCount) {
|
||||||
|
|
@ -326,7 +315,6 @@ public class ArtificialSAMUtils {
|
||||||
* @param endingChr the id to end with
|
* @param endingChr the id to end with
|
||||||
* @param readCount the number of reads per chromosome
|
* @param readCount the number of reads per chromosome
|
||||||
* @param unmappedReadCount the count of unmapped reads to place at the end of the iterator, like in a sorted bam file
|
* @param unmappedReadCount the count of unmapped reads to place at the end of the iterator, like in a sorted bam file
|
||||||
*
|
|
||||||
* @return StingSAMIterator representing the specified amount of fake data
|
* @return StingSAMIterator representing the specified amount of fake data
|
||||||
*/
|
*/
|
||||||
public static StingSAMIterator queryReadIterator(int startingChr, int endingChr, int readCount, int unmappedReadCount) {
|
public static StingSAMIterator queryReadIterator(int startingChr, int endingChr, int readCount, int unmappedReadCount) {
|
||||||
|
|
@ -345,6 +333,7 @@ public class ArtificialSAMUtils {
|
||||||
* reads created that have readLen bases. Pairs are sampled from a gaussian distribution with mean insert
|
* reads created that have readLen bases. Pairs are sampled from a gaussian distribution with mean insert
|
||||||
* size of insertSize and variation of insertSize / 10. The first read will be in the pileup, and the second
|
* size of insertSize and variation of insertSize / 10. The first read will be in the pileup, and the second
|
||||||
* may be, depending on where this sampled insertSize puts it.
|
* may be, depending on where this sampled insertSize puts it.
|
||||||
|
*
|
||||||
* @param header
|
* @param header
|
||||||
* @param loc
|
* @param loc
|
||||||
* @param readLen
|
* @param readLen
|
||||||
|
|
@ -372,10 +361,10 @@ public class ArtificialSAMUtils {
|
||||||
final GATKSAMRecord left = pair.get(0);
|
final GATKSAMRecord left = pair.get(0);
|
||||||
final GATKSAMRecord right = pair.get(1);
|
final GATKSAMRecord right = pair.get(1);
|
||||||
|
|
||||||
pileupElements.add(new PileupElement(left, pos - leftStart));
|
pileupElements.add(new PileupElement(left, pos - leftStart, false));
|
||||||
|
|
||||||
if (pos >= right.getAlignmentStart() && pos <= right.getAlignmentEnd()) {
|
if (pos >= right.getAlignmentStart() && pos <= right.getAlignmentEnd()) {
|
||||||
pileupElements.add(new PileupElement(right, pos - rightStart));
|
pileupElements.add(new PileupElement(right, pos - rightStart, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,20 @@
|
||||||
package org.broadinstitute.sting;
|
package org.broadinstitute.sting;
|
||||||
|
|
||||||
import org.apache.log4j.*;
|
import org.apache.log4j.AppenderSkeleton;
|
||||||
|
import org.apache.log4j.Level;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.apache.log4j.PatternLayout;
|
||||||
import org.apache.log4j.spi.LoggingEvent;
|
import org.apache.log4j.spi.LoggingEvent;
|
||||||
import org.broadinstitute.sting.commandline.CommandLineUtils;
|
import org.broadinstitute.sting.commandline.CommandLineUtils;
|
||||||
import org.broadinstitute.sting.utils.exceptions.ReviewedStingException;
|
import org.broadinstitute.sting.utils.exceptions.ReviewedStingException;
|
||||||
import org.broadinstitute.sting.utils.io.IOUtils;
|
import org.broadinstitute.sting.utils.io.IOUtils;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.File;
|
||||||
import java.util.*;
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ public class UnifiedGenotyperIntegrationTest extends WalkerTest {
|
||||||
public void testMultiSamplePilot1() {
|
public void testMultiSamplePilot1() {
|
||||||
WalkerTest.WalkerTestSpec spec = new WalkerTest.WalkerTestSpec(
|
WalkerTest.WalkerTestSpec spec = new WalkerTest.WalkerTestSpec(
|
||||||
baseCommand + " -I " + validationDataLocation + "low_coverage_CEU.chr1.10k-11k.bam -o %s -L 1:10,022,000-10,025,000", 1,
|
baseCommand + " -I " + validationDataLocation + "low_coverage_CEU.chr1.10k-11k.bam -o %s -L 1:10,022,000-10,025,000", 1,
|
||||||
Arrays.asList("d61c7055bd09024abb8902bde6bd3960"));
|
Arrays.asList("653172b43b19003d9f7df6dab21f4b09"));
|
||||||
executeTest("test MultiSample Pilot1", spec);
|
executeTest("test MultiSample Pilot1", spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -227,7 +227,7 @@ public class UnifiedGenotyperIntegrationTest extends WalkerTest {
|
||||||
" -o %s" +
|
" -o %s" +
|
||||||
" -L 1:10,000,000-10,500,000",
|
" -L 1:10,000,000-10,500,000",
|
||||||
1,
|
1,
|
||||||
Arrays.asList("b11df6587e4e16cb819d76a900446946"));
|
Arrays.asList("bd9d3d50a1f49605d7cd592a0f446899"));
|
||||||
|
|
||||||
executeTest(String.format("test indel caller in SLX"), spec);
|
executeTest(String.format("test indel caller in SLX"), spec);
|
||||||
}
|
}
|
||||||
|
|
@ -255,7 +255,7 @@ public class UnifiedGenotyperIntegrationTest extends WalkerTest {
|
||||||
" -o %s" +
|
" -o %s" +
|
||||||
" -L 1:10,000,000-10,500,000",
|
" -L 1:10,000,000-10,500,000",
|
||||||
1,
|
1,
|
||||||
Arrays.asList("59068bc8888ad5f08790946066d76602"));
|
Arrays.asList("91cd6d2e3972b0b8e4064bb35a33241f"));
|
||||||
|
|
||||||
executeTest(String.format("test indel calling, multiple technologies"), spec);
|
executeTest(String.format("test indel calling, multiple technologies"), spec);
|
||||||
}
|
}
|
||||||
|
|
@ -294,7 +294,7 @@ public class UnifiedGenotyperIntegrationTest extends WalkerTest {
|
||||||
WalkerTest.WalkerTestSpec spec4 = new WalkerTest.WalkerTestSpec(
|
WalkerTest.WalkerTestSpec spec4 = new WalkerTest.WalkerTestSpec(
|
||||||
baseCommandIndelsb37 + " --genotyping_mode GENOTYPE_GIVEN_ALLELES -alleles " + validationDataLocation + "ALL.wgs.union_v2_chr20_100_110K.20101123.indels.sites.vcf -I " + validationDataLocation +
|
baseCommandIndelsb37 + " --genotyping_mode GENOTYPE_GIVEN_ALLELES -alleles " + validationDataLocation + "ALL.wgs.union_v2_chr20_100_110K.20101123.indels.sites.vcf -I " + validationDataLocation +
|
||||||
"phase1_GBR_realigned.chr20.100K-110K.bam -o %s -L 20:100,000-110,000", 1,
|
"phase1_GBR_realigned.chr20.100K-110K.bam -o %s -L 20:100,000-110,000", 1,
|
||||||
Arrays.asList("fcd590a55f5fec2a9b7e628187d6b8a8"));
|
Arrays.asList("877de5b0cc61dc54636062df6399b978"));
|
||||||
executeTest("test MultiSample Phase1 indels with complicated records", spec4);
|
executeTest("test MultiSample Phase1 indels with complicated records", spec4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,12 +42,12 @@ public class ReadUtilsUnitTest extends BaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReducedReadPileupElement() {
|
public void testReducedReadPileupElement() {
|
||||||
PileupElement readp = new PileupElement(read, 0);
|
PileupElement readp = new PileupElement(read, 0, false);
|
||||||
PileupElement reducedreadp = new PileupElement(reducedRead, 0);
|
PileupElement reducedreadp = new PileupElement(reducedRead, 0, false);
|
||||||
|
|
||||||
Assert.assertFalse(readp.isReducedRead());
|
Assert.assertFalse(readp.getRead().isReducedRead());
|
||||||
|
|
||||||
Assert.assertTrue(reducedreadp.isReducedRead());
|
Assert.assertTrue(reducedreadp.getRead().isReducedRead());
|
||||||
Assert.assertEquals(reducedreadp.getRepresentativeCount(), REDUCED_READ_COUNTS[0]);
|
Assert.assertEquals(reducedreadp.getRepresentativeCount(), REDUCED_READ_COUNTS[0]);
|
||||||
Assert.assertEquals(reducedreadp.getQual(), readp.getQual());
|
Assert.assertEquals(reducedreadp.getQual(), readp.getQual());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue