private void paint(RenderContext context, Rectangle rect, AlignmentCounts alignmentCounts) {
Color color = getColor();
Graphics2D graphics = context.getGraphic2DForColor(color);
DataRange range = getDataRange();
double maxRange = range.isLog() ? Math.log10(range.getMaximum() + 1) : range.getMaximum();
final double rectX = rect.getX();
final double rectMaxX = rect.getMaxX();
final double rectY = rect.getY();
final double rectMaxY = rect.getMaxY();
final double rectHeight = rect.getHeight();
final double origin = context.getOrigin();
final double colorScaleMax = getColorScale().getMaximum();
final double scale = context.getScale();
boolean bisulfiteMode = dataManager.getExperimentType() == AlignmentTrack.ExperimentType.BISULFITE;
// First pass, coverage
int lastpX = -1;
//for (AlignmentCounts alignmentCounts : countList) {
int start = alignmentCounts.getStart();
int nPoints = alignmentCounts.getNumberOfPoints();
boolean isSparse = alignmentCounts instanceof SparseAlignmentCounts;
for (int idx = 0; idx < nPoints; idx++) {
int pos = isSparse ? ((SparseAlignmentCounts) alignmentCounts).getPosition(idx) : start + idx;
int pX = (int) (rectX + (pos - origin) / scale);
if (pX > rectMaxX) {
break; // We're done, data is position sorted so we're beyond the right-side of the view
}
int dX = (int) (rectX + (pos + 1 - origin) / scale) - pX;
dX = dX < 1 ? 1 : dX;
if (pX + dX > lastpX) {
int pY = (int) rectMaxY - 1;
int totalCount = alignmentCounts.getTotalCount(pos);
double tmp = range.isLog() ? Math.log10(totalCount + 1) / maxRange : totalCount / maxRange;
int height = (int) (tmp * rectHeight);
height = Math.min(height, rect.height - 1);
int topY = (pY - height);
if (dX > 3) {
dX--; // Create a little space between bars when there is room.
}
if (height > 0) {
graphics.fillRect(pX, topY, dX, height);
}
lastpX = pX + dX;
}
}
//}
// Second pass - mark mismatches
lastpX = -1;
//for (AlignmentCounts alignmentCounts : countList) {
BisulfiteCounts bisulfiteCounts = alignmentCounts.getBisulfiteCounts();
final int intervalEnd = alignmentCounts.getEnd();
final int intervalStart = alignmentCounts.getStart();
byte[] refBases = null;
// Dont try to compute mismatches for intervals > 10 MB
if ((intervalEnd - intervalStart) < TEN_MB) {
refBases = genome.getSequence(context.getChr(), intervalStart, intervalEnd);
}
start = alignmentCounts.getStart();
nPoints = alignmentCounts.getNumberOfPoints();
isSparse = alignmentCounts instanceof SparseAlignmentCounts;
for (int idx = 0; idx < nPoints; idx++) {
int pos = isSparse ? ((SparseAlignmentCounts) alignmentCounts).getPosition(idx) : start + idx;
BisulfiteCounts.Count bc = null;
if (bisulfiteMode && bisulfiteCounts != null) {
bc = bisulfiteCounts.getCount(pos);
}
int pX = (int) (rectX + (pos - origin) / scale);
if (pX > rectMaxX) {
break; // We're done, data is position sorted so we're beyond the right-side of the view
}
int dX = (int) (rectX + (pos + 1 - origin) / scale) - pX;
dX = dX < 1 ? 1 : dX;
if (pX + dX > lastpX) {
// Test to see if any single nucleotide mismatch (nucleotide other than the reference)
// has a quality weight > 20% of the total
// Skip this test if the position is in the list of known snps or if the reference is unknown
boolean mismatch = false;
if (refBases != null) {
int refIdx = pos - intervalStart;
if (refIdx >= 0 && refIdx < refBases.length) {
if (bisulfiteMode) {
mismatch = (bc != null && (bc.methylatedCount + bc.unmethylatedCount) > 0);
} else {
byte ref = refBases[refIdx];
mismatch = alignmentCounts.isMismatch(pos, ref, context.getChr(), snpThreshold);
}
}
}
if (!mismatch) {
continue;
}
int pY = (int) rectMaxY - 1;
int totalCount = alignmentCounts.getTotalCount(pos);
double tmp = range.isLog() ? Math.log10(totalCount + 1) / maxRange : totalCount / maxRange;
int height = (int) (tmp * rectHeight);
height = Math.min(height, rect.height - 1);
if (dX > 3) {
dX--; // Create a little space between bars when there is room.
}
if (height > 0) {
if (bisulfiteMode) {
if (bc != null) {
drawBarBisulfite(context, pos, rect, totalCount, maxRange,
pY, pX, dX, bc, range.isLog());
}
} else {
drawBar(context, pos, rect, totalCount, maxRange,
pY, pX, dX, alignmentCounts, range.isLog());
}
}
lastpX = pX + dX;
}