Skip to content

Commit

Permalink
Improve SMRT kinetics view
Browse files Browse the repository at this point in the history
Correctly handle frame counts larger than signed short max and
add another color transition ot the frame count color scheme to
visually distinguish extreme stalling events.
  • Loading branch information
ctsa committed Sep 7, 2022
1 parent ca12c88 commit c233013
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 12 deletions.
37 changes: 29 additions & 8 deletions src/main/java/org/broad/igv/sam/AlignmentRenderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -1009,20 +1009,41 @@ private static Color blendColors(Color c1, Color c2, float c2Frac) {
blendColorValue(c1.getBlue(), c2.getBlue(), c2Frac));
}

private static Color getSmrtFrameCountColor(short frameCount) {
final int transition1FrameCount = 127; // Red with Alpha 0->255
final int transition2FrameCount = 511; // Red->Yellow
/**
* Set base color for SMRT sequencing frame count
*
* This color scheme uses multiple transitions to help visually distinguish a large range of time intervals.
*
* Color scheme:
* The color starts out as transparent at a frame count of 0.
* - Color transition 1 goes from transparent to opaque red
* - Color transition 2 goes from red to yellow
* - Color transition 3 goes from yellow to cyan
*
* Transition 3 will mostly be visible when uncompressed frame counts are used. It helps to visually distinguish
* exceptional polymerase stalling events.
*/
private static Color getSmrtFrameCountColor(short shortFrameCount) {
final int transition1MaxFrameCount = 100;
final int transition2MaxFrameCount = 600;
final int transition3MaxFrameCount = 6000;
final Color color1 = Color.red;
final Color color2 = Color.yellow;
int alpha = Math.min(255, (frameCount*255)/transition1FrameCount);
final Color color3 = Color.cyan;

final int frameCount = Short.toUnsignedInt(shortFrameCount);
final int alpha = Math.min(255, (frameCount*255)/transition1MaxFrameCount);
Color blendedColor;
if (frameCount <= transition1FrameCount) {
if (frameCount <= transition1MaxFrameCount) {
blendedColor = color1;
} else if (frameCount <= transition2FrameCount) {
float color2Fraction = (frameCount-transition1FrameCount)/((float) (transition2FrameCount-transition1FrameCount));
} else if (frameCount <= transition2MaxFrameCount) {
float color2Fraction = (frameCount-transition1MaxFrameCount)/((float) (transition2MaxFrameCount-transition1MaxFrameCount));
blendedColor = blendColors(color1, color2, color2Fraction);
} else if (frameCount <= transition3MaxFrameCount) {
float color3Fraction = (frameCount-transition2MaxFrameCount)/((float) (transition3MaxFrameCount-transition2MaxFrameCount));
blendedColor = blendColors(color2, color3, color3Fraction);
} else {
blendedColor = color2;
blendedColor = color3;
}
return new Color(blendedColor.getRed(), blendedColor.getGreen(), blendedColor.getBlue(), alpha);
}
Expand Down
9 changes: 5 additions & 4 deletions src/main/java/org/broad/igv/sam/SAMAlignment.java
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,7 @@ private short[] parseSmrtKineticByteCodes(byte[] smrtKineticByteCodes, boolean r
* - Initialize the processed frame count array and copy values into it
* - Reverse frame count sequence if reverseSequence is true
* - If the read has a leading hard-clip, remove all frame counts from the hard-clipped region
* - Reduce max value to fit into a signed int16
*
* Returns the processed frame count array
*/
Expand Down Expand Up @@ -783,26 +784,26 @@ public String getAlignmentValueString(double position, int mouseX, AlignmentTrac
if (colorOption == AlignmentTrack.ColorOption.SMRT_SUBREAD_IPD) {
short[] ipdVals = getSmrtSubreadIpd();
if (ipdVals != null) {
return "Subread IPD: " + ipdVals[readIndex] + " Frames";
return "Subread IPD: " + Short.toUnsignedInt(ipdVals[readIndex]) + " Frames";
}
} else if (colorOption == AlignmentTrack.ColorOption.SMRT_SUBREAD_PW) {
short[] pwVals = getSmrtSubreadPw();
if (pwVals != null) {
return "Subread PW: " + pwVals[readIndex] + " Frames";
return "Subread PW: " + Short.toUnsignedInt(pwVals[readIndex]) + " Frames";
}
} else if (colorOption == AlignmentTrack.ColorOption.SMRT_CCS_FWD_IPD || colorOption == AlignmentTrack.ColorOption.SMRT_CCS_REV_IPD) {
final boolean isForwardStrand = (colorOption == AlignmentTrack.ColorOption.SMRT_CCS_FWD_IPD);
short[] ipdVals = getSmrtCcsIpd(isForwardStrand);
if (ipdVals != null) {
final String strand = (isForwardStrand ? "fwd" : "rev");
return "CCS " + strand + "-strand aligned IPD: " + ipdVals[readIndex] + " Frames";
return "CCS " + strand + "-strand aligned IPD: " + Short.toUnsignedInt(ipdVals[readIndex]) + " Frames";
}
} else {
final boolean isForwardStrand = (colorOption == AlignmentTrack.ColorOption.SMRT_CCS_FWD_PW);
short[] pwVals = getSmrtCcsPw(isForwardStrand);
if (pwVals != null) {
final String strand = (isForwardStrand ? "fwd" : "rev");
return "CCS " + strand + "-strand aligned PW: " + pwVals[readIndex] + " Frames";
return "CCS " + strand + "-strand aligned PW: " + Short.toUnsignedInt(pwVals[readIndex]) + " Frames";
}
}
}
Expand Down

0 comments on commit c233013

Please sign in to comment.