Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/org/broad/igv/PreferenceManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.broad.igv.ui.color.PaletteColorTable;
import org.broad.igv.ui.util.PropertyManager;
import org.broad.igv.util.HttpUtils;
import org.broad.igv.sam.AlignmentTrack.ShadeBasesOption;

import java.awt.*;
import java.io.File;
Expand Down Expand Up @@ -68,7 +69,7 @@ public class PreferenceManager implements PropertyManager {
public static final String SAM_SHOW_CENTER_LINE = "SAM.SHOW_CENTER_LINE";
public static final String SAM_SHOW_REF_SEQ = "SAM.SHOW_REF_SEQ";
public static final String SAM_SHOW_COV_TRACK = "SAM.SHOW_COV_TRACK";
public static final String SAM_SHADE_BASE_QUALITY = "SAM.SHADE_BASE_QUALITY";
public static final String SAM_SHADE_BASES = "SAM.SHADE_BASE_QUALITY";
public static final String SAM_BASE_QUALITY_MIN = "SAM.BASE_QUALITY_MIN";
public static final String SAM_BASE_QUALITY_MAX = "SAM.BASE_QUALITY_MAX";
public static final String SAM_FILTER_ALIGNMENTS = "SAM.FILTER_ALIGNMENTS";
Expand Down Expand Up @@ -939,7 +940,7 @@ private void initDefaultValues() {
defaultValues.put(SAM_SHOW_REF_SEQ, "false");
defaultValues.put(SAM_SHOW_CENTER_LINE, "true");
defaultValues.put(SAM_SHOW_COV_TRACK, "true");
defaultValues.put(SAM_SHADE_BASE_QUALITY, "true");
defaultValues.put(SAM_SHADE_BASES, ShadeBasesOption.QUALITY.toString());
defaultValues.put(SAM_FILTER_ALIGNMENTS, "false");
defaultValues.put(SAM_FILTER_FAILED_READS, "true");
defaultValues.put(SAM_DOWNSAMPLE_READS, "true");
Expand Down
16 changes: 9 additions & 7 deletions src/org/broad/igv/sam/AbstractAlignment.java
Original file line number Diff line number Diff line change
Expand Up @@ -121,26 +121,28 @@ public byte getPhred(double position) {
}
return 0;
}

private void bufAppendFlowSignals(AlignmentBlock block, StringBuffer buf, int offset) {
if (block.hasFlowSignals()) {
// flow signals
int i, j, n = 0;
short[][] flowSignalContext = block.getFlowSignalContext(offset);
if (null != flowSignalContext) {
FlowSignalSubContext f = block.getFlowSignalSubContext(offset);
if (null != f && null != f.signals && null != f.bases) {
buf.append("FZ = ");
for (i=0;i<flowSignalContext.length;i++) {
if (null != flowSignalContext[i] && 0 < flowSignalContext[i].length) {
for (i=0;i<f.signals.length;i++) {
if (null != f.signals[i] && 0 < f.signals[i].length) {
if (1 == i) {
if (0 < n) {
buf.append(",");
}
buf.append("[");
}
for (j=0;j<flowSignalContext[i].length;j++) {
for (j=0;j<f.signals[i].length;j++) {
if (1 != i && 0 < n) {
buf.append(",");
}
buf.append(flowSignalContext[i][j]);
buf.append(f.bases[i][j]);
buf.append(f.signals[i][j]);
n++;
}
if (1 == i) {
Expand Down Expand Up @@ -178,7 +180,7 @@ public String getValueString(double position, WindowFunction windowFunction) {
for (offset=0;offset<block.getBases().length;offset++) {
byte base = block.getBase(offset);
buf.append((char)base + ": ");
bufAppendFlowSignals(block, buf, offset); // TODO: add in all blocks
bufAppendFlowSignals(block, buf, offset);
}
buf.append("----------------------"); // NB: no <br> required
return buf.toString();
Expand Down
6 changes: 3 additions & 3 deletions src/org/broad/igv/sam/AlignmentBlock.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ public static AlignmentBlock getInstance(int start, byte[] bases, byte[] qualiti
return new AlignmentBlock(start, bases, qualities, baseAlignment);
}

public static AlignmentBlock getInstance(int start, byte[] bases, byte[] qualities, short[][][] flowSignals, Alignment baseAlignment) {
return new AlignmentBlockFS(start, bases, qualities, flowSignals, baseAlignment);
public static AlignmentBlock getInstance(int start, byte[] bases, byte[] qualities, FlowSignalContext fContext, Alignment baseAlignment) {
return new AlignmentBlockFS(start, bases, qualities, fContext, baseAlignment);
}

protected AlignmentBlock(int start, byte[] bases, byte[] qualities, Alignment baseAlignment) {
Expand Down Expand Up @@ -103,7 +103,7 @@ public boolean hasFlowSignals() {
}

// Default implementation -- to be overriden
public short[][] getFlowSignalContext(int offset) {
public FlowSignalSubContext getFlowSignalSubContext(int offset) {
return null;
}

Expand Down
18 changes: 10 additions & 8 deletions src/org/broad/igv/sam/AlignmentBlockFS.java
Original file line number Diff line number Diff line change
@@ -1,28 +1,30 @@
package org.broad.igv.sam;

import java.util.Arrays;

/**
* Represents an alignment block which contains flow signals. Added to suppor IonTorrent alignments.
* Represents an alignment block which contains flow signals. Added to support IonTorrent alignments.
*
* @author Jim Robinson
* @date 3/19/12
*/
public class AlignmentBlockFS extends AlignmentBlock {

public short[][][] flowSignals = null;
public FlowSignalContext fContext = null;

protected AlignmentBlockFS(int start, byte[] bases, byte[] qualities, short[][][] flowSignals, Alignment baseAlignment) {
protected AlignmentBlockFS(int start, byte[] bases, byte[] qualities, FlowSignalContext fContext, Alignment baseAlignment) {
super(start, bases, qualities, baseAlignment);
if (flowSignals != null && flowSignals.length == bases.length) {
this.flowSignals = flowSignals;
if (fContext != null && fContext.signals.length == bases.length) {
this.fContext = fContext;
}
}

public short[][] getFlowSignalContext(int offset) {
return this.flowSignals[offset];
public FlowSignalSubContext getFlowSignalSubContext(int offset) {
return new FlowSignalSubContext(this.fContext.signals[offset], this.fContext.bases[offset]);
}


public boolean hasFlowSignals() {
return (null != this.flowSignals);
return (null != this.fContext);
}
}
2 changes: 1 addition & 1 deletion src/org/broad/igv/sam/AlignmentInterval.java
Original file line number Diff line number Diff line change
Expand Up @@ -477,4 +477,4 @@ public void remove() {
// ignore
}
}
}
}
63 changes: 59 additions & 4 deletions src/org/broad/igv/sam/AlignmentRenderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.broad.igv.feature.genome.GenomeManager;
import org.broad.igv.renderer.ContinuousColorScale;
import org.broad.igv.renderer.GraphicUtils;
import org.broad.igv.sam.AlignmentTrack.ShadeBasesOption;
import org.broad.igv.sam.AlignmentTrack.ColorOption;
import org.broad.igv.sam.AlignmentTrack.RenderOptions;
import org.broad.igv.sam.BisulfiteBaseInfo.DisplayStatus;
Expand Down Expand Up @@ -635,7 +636,7 @@ private void drawAlignment(

/**
* Draw bases for an alignment block. The bases are "overlaid" on the block with a transparency value (alpha)
* that is proportional to the base quality score.
* that is proportional to the base quality score, or flow signal deviation, whichever is selected.
*
* @param context
* @param rect
Expand All @@ -650,7 +651,7 @@ private void drawBases(RenderContext context,
RenderOptions renderOptions) {


boolean shadeBases = renderOptions.shadeBases;
ShadeBasesOption shadeBasesOption = renderOptions.shadeBasesOption;
ColorOption colorOption = renderOptions.getColorOption();

// Disable showAllBases in bisulfite mode
Expand Down Expand Up @@ -731,10 +732,64 @@ private void drawBases(RenderContext context,
color = Color.black;
}

if (shadeBases) {
if (ShadeBasesOption.QUALITY == shadeBasesOption) {
byte qual = block.qualities[loc - start];
color = getShadedColor(qual, color, alignmentColor, prefs);
}
} else if (ShadeBasesOption.FLOW_SIGNAL_DEVIATION_READ == shadeBasesOption || ShadeBasesOption.FLOW_SIGNAL_DEVIATION_REFERENCE == shadeBasesOption) {
if (block.hasFlowSignals()) {
int flowSignal = (int)block.getFlowSignalSubContext(loc - start).signals[1][0];
int expectedFlowSignal;
if (ShadeBasesOption.FLOW_SIGNAL_DEVIATION_READ == shadeBasesOption) {
expectedFlowSignal = 100 * (short)((flowSignal + 50.0) / 100.0);
} else {
// NB: this may estimate the reference homopolymer length incorrect in some cases, especially when we have
// an overcall/undercall situation. Proper estimation of the reads observed versus expected homopolymer
// length should use flow signal alignment (SamToFlowspace): https://github.com/iontorrent/Ion-Variant-Hunter
if (!misMatch) {
final byte readbase = read[idx];
byte refbase = reference[idx];
int pos; // zero based
expectedFlowSignal = 100;

// Count HP length
pos = start + idx - 1;
while (0 <= pos && genome.getReference(chr, pos) == refbase) {
pos--;
expectedFlowSignal += 100;
}
pos = start + idx + 1;
while (pos < genome.getChromosome(chr).getLength() && genome.getReference(chr, pos) == refbase) {
pos++;
expectedFlowSignal += 100;
}
} else {
expectedFlowSignal = 0;
}
}
int flowSignalDiff = (expectedFlowSignal < flowSignal) ? (flowSignal - expectedFlowSignal) : (expectedFlowSignal - flowSignal);
// NB: this next section is some mangling to use the base quality color preferences...
if (flowSignalDiff <= 0) {
flowSignalDiff = 0;
} else if (50 < flowSignalDiff) {
flowSignalDiff = 50;
}
flowSignalDiff = 50 - flowSignalDiff; // higher is better
int minQ = prefs.getAsInt(PreferenceManager.SAM_BASE_QUALITY_MIN);
int maxQ = prefs.getAsInt(PreferenceManager.SAM_BASE_QUALITY_MAX);
flowSignalDiff = flowSignalDiff * (maxQ - minQ) / 50;
byte qual;
int pos = start + idx;
if (Byte.MAX_VALUE < flowSignalDiff) {
qual = Byte.MAX_VALUE;
} else if (flowSignalDiff < Byte.MIN_VALUE) {
qual = Byte.MIN_VALUE;
} else {
qual = (byte)flowSignalDiff;
}
// Finally, get the color
color = getShadedColor(qual, color, alignmentColor, prefs);
}
}

double bisulfiteXaxisShift = (bisulfiteMode) ? bisinfo.getXaxisShift(idx) : 0;

Expand Down
Loading