int maxExtFactor = Math.max(extFactor, Math.max(preExtFactor, postExtFactor));
int tolerance = (int) (windowSize * (Math.floor(maxExtFactor / windowSize) + 2));
consumer.setSortTolerance(tolerance);
AlignmentReader reader = null;
CloseableIterator<Alignment> iter = null;
String lastChr = "";
ReadCounter counter = null;
WigWriter wigWriter = null;
if (wigFile != null || writeStdOut) {
wigWriter = new WigWriter(wigFile, windowSize);
}
try {
if (queryInterval == null) {
reader = AlignmentReaderFactory.getReader(alignmentFile, false);
iter = reader.iterator();
} else {
reader = AlignmentReaderFactory.getReader(alignmentFile, true);
iter = reader.query(queryInterval.getChr(), queryInterval.getStart() - 1, queryInterval.getEnd(), false);
}
while (iter != null && iter.hasNext()) {
Alignment alignment = iter.next();
if (passFilter(alignment)) {
//Sort into the read strand or first-in-pair strand,
//depending on input flag. Note that this can
//be very unreliable depending on data
Strand strand;
if (firstInPair) {
strand = alignment.getFirstOfPairStrand();
} else if (secondInPair) {
strand = alignment.getSecondOfPairStrand();
} else {
strand = alignment.getReadStrand();
}
if (strand.equals(Strand.NONE)) {
//TODO move this into passFilter, or move passFilter here
continue;
}
boolean readNegStrand = alignment.isNegativeStrand();
totalCount++;
String alignmentChr = alignment.getChr();
// Close all counters with position < alignment.getStart()
if (alignmentChr.equals(lastChr)) {
if (counter != null) {
counter.closeBucketsBefore(alignment.getAlignmentStart() - tolerance, wigWriter);
}
} else { // New chromosome
if (counter != null) {
counter.closeBucketsBefore(Integer.MAX_VALUE, wigWriter);
}
counter = new ReadCounter(alignmentChr);
lastChr = alignmentChr;
}
AlignmentBlock[] blocks = alignment.getAlignmentBlocks();
if (blocks != null && !pairedCoverage) {
for (AlignmentBlock block : blocks) {
if (!block.isSoftClipped()) {
byte[] bases = block.getBases();
int blockStart = block.getStart();
int blockEnd = block.getEnd();
int adjustedStart = block.getStart();
int adjustedEnd = block.getEnd();
if (preExtFactor > 0) {
if (readNegStrand) {
adjustedEnd = blockEnd + preExtFactor;
} else {
adjustedStart = Math.max(0, blockStart - preExtFactor);
}
}
// If both postExtFactor and extFactor are specified, postExtFactor takes precedence
if (postExtFactor > 0) {
if (readNegStrand) {
adjustedStart = Math.max(0, blockEnd - postExtFactor);
} else {
adjustedEnd = blockStart + postExtFactor;
}
} else if (extFactor > 0) {
// Standard extension option -- extend read on 3' end
if (readNegStrand) {
adjustedStart = Math.max(0, adjustedStart - extFactor);
} else {
adjustedEnd += extFactor;
}
}
if (queryInterval != null) {
adjustedStart = Math.max(queryInterval.getStart() - 1, adjustedStart);
adjustedEnd = Math.min(queryInterval.getEnd(), adjustedEnd);
}
for (int pos = adjustedStart; pos < adjustedEnd; pos++) {
byte base = 0;
int baseIdx = pos - blockStart;
if (bases != null && baseIdx >= 0 && baseIdx < bases.length) {
base = bases[baseIdx];
}
//int idx = pos - blockStart;
//byte quality = (idx >= 0 && idx < block.qualities.length) ?
//block.qualities[pos - blockStart] : (byte) 0;
counter.incrementCount(pos, base, strand);
}
}
}
} else {
int adjustedStart = alignment.getAlignmentStart();
int adjustedEnd = pairedCoverage ?
adjustedStart + Math.abs(alignment.getInferredInsertSize()) :
alignment.getAlignmentEnd();
if (readNegStrand) {
adjustedStart = Math.max(0, adjustedStart - extFactor);
} else {
adjustedEnd += extFactor;
}
if (queryInterval != null) {
adjustedStart = Math.max(queryInterval.getStart() - 1, adjustedStart);
adjustedEnd = Math.min(queryInterval.getEnd(), adjustedEnd);
}
for (int pos = adjustedStart; pos < adjustedEnd; pos++) {
counter.incrementCount(pos, (byte) 'N', strand);
}
}
}
}
consumer.setAttribute("totalCount", String.valueOf(totalCount));
consumer.parsingComplete();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (counter != null) {
counter.closeBucketsBefore(Integer.MAX_VALUE, wigWriter);
}
if (iter != null) {
iter.close();
}
if (reader != null) {
reader.close();
}
if (wigWriter != null) {
wigWriter.close();
}