int totalCount = 0;
if (alList == null || alList.size() == 0) return;
Range curRange = getAlignmentListRange(alList);
BucketCollection bucketCollection;
// Use dense buckets for < 10,000,000 bp windows sparse otherwise
int bpLength = curRange.getLength();
if (bpLength < tenMB) {
bucketCollection = new DenseBucketCollection(bpLength, curRange);
} else {
bucketCollection = new SparseBucketCollection(curRange);
}
int curRangeStart = curRange.getStart();
for (Alignment al : alList) {
if (al.isMapped()) {
Alignment alignment = al;
if (pairAlignments && al.isPaired() && al.getMate().isMapped() && al.getMate().getChr().equals(al.getChr())) {
String readName = al.getReadName();
PairedAlignment pair = pairs.get(readName);
if (pair == null) {
pair = new PairedAlignment(al);
pairs.put(readName, pair);
alignment = pair;
} else {
// Add second alignment to pair.
pair.setSecondAlignment(al);
pairs.remove(readName);
continue;
}
}
// Negative "bucketNumbers" can arise with soft clips at the left edge of the chromosome. Allocate
// these alignments to the first bucket.
int bucketNumber = Math.max(0, al.getStart() - curRangeStart);
if (bucketNumber < bucketCollection.getBucketCount()) {
PriorityQueue<Alignment> bucket = bucketCollection.get(bucketNumber);
if (bucket == null) {
bucket = new PriorityQueue<Alignment>(5, lengthComparator);
bucketCollection.set(bucketNumber, bucket);
}
bucket.add(alignment);
totalCount++;
} else {
log.debug("Alignment out of bounds. name: " + alignment.getReadName() + " startPos:" + alignment.getStart());
}
}
}
bucketCollection.finishedAdding();
// Now allocate alignments to rows.
long t0 = System.currentTimeMillis();
int allocatedCount = 0;
Row currentRow = new Row();
while (allocatedCount < totalCount) {
curRange = bucketCollection.getRange();
curRangeStart = curRange.getStart();
int nextStart = curRangeStart;
List<Integer> emptyBuckets = new ArrayList<Integer>(100);
while (true) {
int bucketNumber = nextStart - curRangeStart;
PriorityQueue<Alignment> bucket = bucketCollection.getNextBucket(bucketNumber, emptyBuckets);
// Pull the next alignment out of the bucket and add to the current row
if (bucket != null) {
Alignment alignment = bucket.remove();
currentRow.addAlignment(alignment);
allocatedCount++;
nextStart = alignment.getEnd() + MIN_ALIGNMENT_SPACING;
}
//Reached the end of this range, move to the next
if (bucket == null || nextStart > curRange.getEnd()) {
//Remove empty buckets. This has no affect on the dense implementation,
//they are removed on the fly, but is needed for the sparse implementation
bucketCollection.removeBuckets(emptyBuckets);
emptyBuckets.clear();
break;