picard.util.QuerySortedReadPairIteratorUtil Maven / Gradle / Ivy
package picard.util;
import htsjdk.samtools.SAMRecord;
import htsjdk.samtools.util.PeekableIterator;
/**
* A collection of helper utilities for iterating through reads that are in query-name sorted
* read order as pairs
*/
public class QuerySortedReadPairIteratorUtil {
public static class ReadPair {
public SAMRecord read1 = null;
public SAMRecord read2 = null;
}
/**
* Get the next read pair (where both have the same read name).
* If we encounter an unpaired read, the second read in the pair will be set to null.
*
* @param iterator iterator of reads
* @return ReadPair object holding the reads, or null if there are no more reads in the iterator
*/
public static ReadPair getNextReadPair(final PeekableIterator iterator) {
final ReadPair readPair = new ReadPair();
readPair.read1 = getNextUsableRead(iterator, false);
if (readPair.read1 == null) {
return null;
}
final SAMRecord peekedNextRead = getNextUsableRead(iterator, true);
if (peekedNextRead != null && peekedNextRead.getReadName().equals(readPair.read1.getReadName())) {
readPair.read2 = getNextUsableRead(iterator, false);
}
return readPair;
}
/**
* Return the next usable read in the iterator
*
* @param iterator the iterator to pull from
* @param justPeek if true, just peek the next usable read rather than pulling it (note: it may remove unusable reads from the iterator)
* @return the next read or null if none are left
*/
private static SAMRecord getNextUsableRead(final PeekableIterator iterator, final boolean justPeek) {
while (iterator.hasNext()) {
// trash the next read if it fails PF, is secondary, or is supplementary
final SAMRecord nextRead = iterator.peek();
if (nextRead.getReadFailsVendorQualityCheckFlag() || nextRead.isSecondaryOrSupplementary()) {
iterator.next();
}
// otherwise, return it
else {
return justPeek ? nextRead : iterator.next();
}
}
// no good reads left
return null;
}
}