ObjectArrayList<AlignmentBlock> blocks = new ObjectArrayList<AlignmentBlock>();
ObjectArrayList<AlignmentBlock> insertionBlocks = new ObjectArrayList<AlignmentBlock>();
int start = alignmentEntry.getPosition();
ByteArrayList bases = new ByteArrayList();
ByteArrayList scores = new ByteArrayList();
int readLength = alignmentEntry.getQueryLength();
byte[] readBases = new byte[readLength];
byte[] readQual = new byte[readLength];
Arrays.fill(readBases, (byte) '=');
if (alignmentEntry.hasReadQualityScores()) {
readQual = alignmentEntry.getReadQualityScores().toByteArray();
} else {
Arrays.fill(readQual, (byte) 40);
}
int j = 0;
int insertedBases = 0;
int deletedBases = 0;
final int leftPadding = alignmentEntry.getQueryPosition();
boolean showSoftClipped = PreferenceManager.getInstance().getAsBoolean(PreferenceManager.SAM_SHOW_SOFT_CLIPPED);
if (showSoftClipped && entry.hasSoftClippedBasesLeft()) {
int clipLength = entry.getSoftClippedBasesLeft().length();
addSoftClipBlock(blocks, Math.max(0,
entry.getPosition() - clipLength),
entry.getSoftClippedBasesLeft(), readQual,
entry.hasSoftClippedQualityLeft(),
entry.getSoftClippedQualityLeft().toByteArray(),
0);
}
for (Alignments.SequenceVariation var : alignmentEntry.getSequenceVariationsList()) {
final String from = var.getFrom();
final int fromLength = from.length();
final String to = var.getTo();
final int toLength = from.length();
final int sequenceVariationLength = Math.max(fromLength, toLength);
final ByteString toQuality = var.getToQuality();
if (hasReadInsertion(from)) {
bases.clear();
scores.clear();
for (int i = 0; i < sequenceVariationLength; i++) {
final char toChar = i >= toLength ? '-' : to.charAt(i);
int size = toQuality.size();
final byte qual = size > 0 && i < size ? toQuality.byteAt(i) : 40;
bases.add((byte) toChar);
scores.add(qual);
deletedBases++;
}
addBlock(insertionBlocks, alignmentEntry.getPosition() + var.getPosition(), bases, scores);
bases.clear();
scores.clear();
} else if (!to.contains("-")) {
for (int i = 0; i < toLength; i++) {
final int offset = j + var.getPosition() + i - 1 + leftPadding - insertedBases;
if (offset > 0 && offset < readBases.length) {
readBases[offset] = (byte) to.charAt(i);
if (i < toQuality.size()) {
readQual[offset] = toQuality.byteAt(i);
}
}
}
} else {
// has read deletion:
insertedBases++;
}
}
int pos = start;
int matchLength = alignmentEntry.getQueryAlignedLength() - deletedBases;
int endAlignmentRefPosition = matchLength + start;
bases.clear();
scores.clear();
int maxIndex = Math.min(readBases.length, readQual.length);
while (pos < endAlignmentRefPosition) {
final int index = pos - start + leftPadding;
if (index < maxIndex) {
bases.add(readBases[index]);
scores.add(readQual[index]);
} else {
break;
}
++pos;
}