Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ultima develop code merge #1423

Merged
merged 27 commits into from
Dec 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
6a45dcd
gradle build
dror27 Apr 27, 2020
dfda37a
Gradle Build in workflows
dror27 Apr 27, 2020
e0ee8ba
delete workflow put in wrong place
dror27 Apr 27, 2020
d54fd84
igv_ug_30
dror27 Jan 2, 2022
c1f875c
Merge branch 'master' of https://github.com/igvteam/igv into update
dror27 Oct 27, 2022
61da8d0
Merge branch 'update' into ultima-develop
dror27 Oct 27, 2022
77c05c5
Merge with master, when on 2.15.1 (at least)
dror27 Oct 27, 2022
15a9488
Fix reference access to be case independent
dror27 Oct 31, 2022
819d991
token updated
dror27 May 16, 2023
175043b
genomeId conversion to relative protection
dror27 Jul 21, 2023
648a6e1
token update
dror27 Aug 16, 2023
ab45699
Remove explicit token
dror27 Aug 17, 2023
e0363c7
java 11.0.19 update
dror27 Oct 11, 2023
5b710cb
Merge remote-tracking branch 'igv-private/ultima-develop' into ultima…
dror27 Oct 28, 2023
d6664a9
flow renderer test/example file added. data around chr1:10000
dror27 Nov 11, 2023
871f834
Documentation added
ilyasoifer Nov 19, 2023
e0e9270
protect against "tp" tag not indicating flow
dror27 Nov 20, 2023
d11c776
Goto mate added
dror27 Nov 29, 2023
53e973d
show "goto mate" only for mated variants
dror27 Nov 29, 2023
07fe838
Revert "show "goto mate" only for mated variants"
dror27 Dec 5, 2023
60a675b
Revert "Goto mate added"
dror27 Dec 5, 2023
432f906
Extension framework removed
dror27 Dec 5, 2023
6de1d10
Merge branch 'master' into ultima-develop
dror27 Dec 5, 2023
71cde5a
add missing import
dror27 Dec 5, 2023
e507cc5
remove LoadMultipleTracks and Relative Genome resolve ignoring
dror27 Dec 6, 2023
aa40613
remove drawInsertions method
dror27 Dec 10, 2023
28ffbcc
doc deleted from source tree
dror27 Dec 10, 2023
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
34 changes: 0 additions & 34 deletions .github/workflows/gradle_test.yml

This file was deleted.

1 change: 1 addition & 0 deletions src/main/java/org/broad/igv/prefs/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ private Constants() {
public static final String SAM_ALIGNMENT_SCORE_THRESHOLD = "SAM.ALIGNMENT_SCORE_THRESHOLD";
public static final String SAM_COMPUTE_ISIZES = "SAM.COMPUTE_ISIZES";
public static final String SAM_MAX_INSERT_SIZE_THRESHOLD = "SAM.INSERT_SIZE_THRESHOLD";
public static final String SAM_INSERT_QUAL_COLORING = "SAM.INSERT_QUAL_COLORING";
public static final String SAM_MIN_INSERT_SIZE_THRESHOLD = "SAM.MIN_INSERT_SIZE_THRESHOLD";
public static final String SAM_MAX_INSERT_SIZE_PERCENTILE = "SAM.ISIZE_MAX_PERCENTILE";
public static final String SAM_MIN_INSERT_SIZE_PERCENTILE = "SAM.MIN_ISIZE_MIN_PERCENTILE";
Expand Down
1 change: 1 addition & 0 deletions src/main/java/org/broad/igv/sam/AlignmentBlock.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,5 @@ default int getPadding() {

char getCigarOperator();

default int getIndexOnRead() { return 0; }
}
7 changes: 7 additions & 0 deletions src/main/java/org/broad/igv/sam/AlignmentBlockImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public class AlignmentBlockImpl implements AlignmentBlock {
private int pixelEnd;
private int padding = 0;
private char cigarOperator;
private int indexOnRead;

public AlignmentBlockImpl(int start, byte[] bases, byte[] qualities) {
this(start, bases, qualities, 0, bases.length, (char) 0);
Expand All @@ -57,6 +58,8 @@ public AlignmentBlockImpl(int start, byte[] bases, byte[] qualities, int offset,
// qualities are optional in a SAMRecord, we might get null or an array of zero
this.qualities = qualities == null || qualities.length == 0 ? EMPTY_ARRAY : new ByteSubarray(qualities, offset, nBases, (byte) 126);
this.cigarOperator = cigarOperator;

this.indexOnRead = offset;
}

@Override
Expand Down Expand Up @@ -177,4 +180,8 @@ public boolean hasBases() {
public void setPadding(int padding) {
this.padding = padding;
}

public int getIndexOnRead() {
return this.indexOnRead;
}
}
143 changes: 132 additions & 11 deletions src/main/java/org/broad/igv/sam/AlignmentRenderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import org.broad.igv.prefs.IGVPreferences;
import org.broad.igv.prefs.PreferencesManager;
import org.broad.igv.renderer.GraphicUtils;
import org.broad.igv.renderer.SequenceRenderer;
import org.broad.igv.sam.AlignmentTrack.ColorOption;
import org.broad.igv.sam.BisulfiteBaseInfo.DisplayStatus;
import org.broad.igv.sam.mods.BaseModificationRenderer;
Expand All @@ -48,6 +49,8 @@
import org.broad.igv.ui.color.GreyscaleColorTable;
import org.broad.igv.ui.color.HSLColorTable;
import org.broad.igv.ui.color.PaletteColorTable;
import org.broad.igv.ultima.render.ColorByTagValueList;
import org.broad.igv.ultima.render.FlowIndelRendering;
import org.broad.igv.util.ChromosomeColors;

import java.awt.*;
Expand Down Expand Up @@ -101,9 +104,9 @@ public class AlignmentRenderer {

// Indel colors
public static Color purple = new Color(118, 24, 220);
private static final Color deletionColor = Color.black;
private static final Color skippedColor = new Color(150, 184, 200);
private static final Color unknownGapColor = new Color(0, 150, 0);
public static Color deletionColor = Color.black;
private static Color skippedColor = new Color(150, 184, 200);
private static Color unknownGapColor = new Color(0, 150, 0);

// Bisulfite colors
private static final Color bisulfiteColorFw1 = new Color(195, 195, 195);
Expand Down Expand Up @@ -132,6 +135,9 @@ public class AlignmentRenderer {
private static ColorTable defaultTagColors;
public static HashMap<Character, Color> nucleotideColors;

final private static ColorByTagValueList colorByTagValueList = new ColorByTagValueList();
final private static FlowIndelRendering flowIndelRendering = new FlowIndelRendering();

private static void initializeTagTypes() {
// pre-seed from orientation colors

Expand Down Expand Up @@ -654,9 +660,16 @@ private void drawAlignment(
y,
h,
gapPxEnd - gapPxStart - 2,
context.translateX,
null,
alignment,
context);
}

// gap extensions
if ( flowIndelRendering.handlesAlignment(alignment) ) {
flowIndelRendering.renderDeletionGap(alignment, gap, y, h, gapPxStart, gapPxEnd - gapPxStart, context, renderOptions);
}
}
}

Expand Down Expand Up @@ -904,15 +917,21 @@ private void drawAlignment(
y,
h,
(int) pxWidthExact,
context.translateX,
aBlock,
context );
alignment,
context);
} else {
int pxWing = (h > 10 ? 2 : (h > 5) ? 1 : 0);
Graphics2D ig = context.getGraphics();
ig.setColor(purple);
ig.fillRect(x, y, 2, h);
ig.fillRect(x - pxWing, y, 2 + 2 * pxWing, 2);
ig.fillRect(x - pxWing, y + h - 2, 2 + 2 * pxWing, 2);
if ( flowIndelRendering.handlesAlignment(alignment) ) {
flowIndelRendering.renderSmallInsertion(alignment, aBlock, context, h, x, y, renderOptions);
} else {
ig.fillRect(x, y, 2, h);
ig.fillRect(x - pxWing, y, 2 + 2 * pxWing, 2);
ig.fillRect(x - pxWing, y + h - 2, 2 + 2 * pxWing, 2);
}

aBlock.setPixelRange(context.translateX + x - pxWing, context.translateX + x + 2 + pxWing);
}
Expand Down Expand Up @@ -1018,7 +1037,7 @@ private static void drawClippedEnds(final Graphics2D g, final int[] xPoly, final
}

private void drawLargeIndelLabel(Graphics2D g, boolean isInsertion, String labelText, int pxCenter,
int pxTop, int pxH, int pxWmax, AlignmentBlock insertionBlock, RenderContext context) {
int pxTop, int pxH, int pxWmax, int translateX, AlignmentBlock insertionBlock, Alignment alignment, RenderContext context) {

final int pxPad = 2; // text padding in the label
final int pxWing = (pxH > 10 ? 2 : 1); // width of the cursor "wing"
Expand All @@ -1043,8 +1062,12 @@ private void drawLargeIndelLabel(Graphics2D g, boolean isInsertion, String label
g.fillRect(pxLeft, pxTop, pxRight - pxLeft, pxH);

if (isInsertion && pxH > 5) {
g.fillRect(pxLeft - pxWing, pxTop, pxRight - pxLeft + 2 * pxWing, 2);
g.fillRect(pxLeft - pxWing, pxTop + pxH - 2, pxRight - pxLeft + 2 * pxWing, 2);
if ( flowIndelRendering.handlesAlignment(alignment) ) {
flowIndelRendering.renderSmallInsertionWings(alignment, insertionBlock, context, pxH, pxTop, pxRight, pxLeft, track.renderOptions);
} else {
g.fillRect(pxLeft - pxWing, pxTop, pxRight - pxLeft + 2 * pxWing, 2);
g.fillRect(pxLeft - pxWing, pxTop + pxH - 2, pxRight - pxLeft + 2 * pxWing, 2);
}
} // draw "wings" For insertions

if (doesTextFit) {
Expand All @@ -1057,6 +1080,104 @@ private void drawLargeIndelLabel(Graphics2D g, boolean isInsertion, String label
}
}

public void renderExpandedInsertion(InsertionMarker i,
List<Alignment> alignments,
RenderContext context,
Rectangle rect,
boolean leaveMargin) {
double origin = context.getOrigin();
double locScale = context.getScale();
if ((alignments != null) && (alignments.size() > 0)) {

Graphics2D g = context.getGraphics2D("INSERTIONS");
double dX = 1 / context.getScale();
int fontSize = (int) Math.min(dX, 12);
if (fontSize >= 8) {
Font f = FontManager.getFont(Font.BOLD, fontSize);
g.setFont(f);
}

for (Alignment alignment : alignments) {
if (alignment.getEnd() < i.position) continue;
if (alignment.getStart() > i.position) break;
AlignmentBlock insertion = alignment.getInsertionAt(i.position);
if (insertion != null) {

// Compute the start and dend of the alignment in pixels
double pixelStart = (insertion.getStart() - origin) / locScale;
double pixelEnd = (insertion.getEnd() - origin) / locScale;
int x = (int) pixelStart;

// If any any part of the feature fits in the track rectangle draw it
if (pixelEnd < rect.x || pixelStart > rect.getMaxX()) {
continue;
}

int bpWidth = insertion.getBasesLength();
double pxWidthExact = ((double) bpWidth) / locScale;
int h = (int) Math.max(1, rect.getHeight() - 2);
int y = (int) (rect.getY() + (rect.getHeight() - h) / 2) - 1;

if (!insertion.hasBases()) {
g.setColor(purple);
g.fillRect(x, y, (int) pxWidthExact, h);

} else {
drawExpandedInsertionBases(x, context, rect, insertion, leaveMargin);
}
}
}
}
}


private void drawExpandedInsertionBases(int pixelPosition,
RenderContext context,
Rectangle rect,
AlignmentBlock block,
boolean leaveMargin) {
Graphics2D g = context.getGraphics2D("INSERTIONS");
ByteSubarray bases = block.getBases();
int padding = block.getPadding();

double locScale = context.getScale();
double origin = context.getOrigin();

// Compute bounds
int pY = (int) rect.getY();
int dY = (int) rect.getHeight();
int dX = (int) Math.max(1, (1.0 / locScale));

final int size = bases.length + padding;
for (int p = 0; p < size; p++) {

char c = p < padding ? '-' : (char) bases.getByte(p - padding);

Color color = SequenceRenderer.nucleotideColors.get(c);
if (color == null) {
color = Color.black;
}

// If there is room for text draw the character, otherwise
// just draw a rectangle to represent the
int pX = (int) (pixelPosition + (p / locScale));

// Don't draw out of clipping rect
if (pX > rect.getMaxX()) {
break;
} else if (pX + dX < rect.getX()) {
continue;
}
BaseRenderer.drawBase(g, color, c, pX, pY, dX, dY - (leaveMargin ? 2 : 0), false, null);
}

int leftX = pixelPosition + context.translateX;
int rightX = leftX + rect.width;
block.setPixelRange(leftX, rightX);

}


private Color getAlignmentColor(Alignment alignment, AlignmentTrack track) {

// Set color used to draw the feature. Highlight features that intersect the
Expand Down Expand Up @@ -1205,7 +1326,7 @@ private Color getAlignmentColor(Alignment alignment, AlignmentTrack track) {
case TAG:
final String tag = renderOptions.getColorByTag();
if (tag != null) {
Object tagValue = alignment.getAttribute(tag);
Object tagValue = !colorByTagValueList.handlesTag(tag) ? alignment.getAttribute(tag) : colorByTagValueList.getValueForColorByTag(alignment, tag);
if (tagValue != null) {

ColorTable ctable;
Expand Down
10 changes: 9 additions & 1 deletion src/main/java/org/broad/igv/sam/AlignmentTrack.java
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ public static boolean isBisulfiteColorType(ColorOption o) {
private final Genome genome;
private ExperimentType experimentType;
private final AlignmentRenderer renderer;
private RenderOptions renderOptions;
RenderOptions renderOptions;

private boolean removed = false;
private boolean showGroupLine;
Expand Down Expand Up @@ -1211,6 +1211,7 @@ public static class RenderOptions implements Cloneable, Persistable {
private Boolean linkedReads;
private Boolean quickConsensusMode;
private Boolean showMismatches;
private Boolean insertQualColoring;
Boolean computeIsizes;
private Double minInsertSizePercentile;
private Double maxInsertSizePercentile;
Expand Down Expand Up @@ -1278,6 +1279,10 @@ public void setViewPairs(boolean viewPairs) {
this.viewPairs = viewPairs;
}

void setInsertQualColoring(boolean insertQualColoring) {
this.insertQualColoring = insertQualColoring;
}

void setComputeIsizes(boolean computeIsizes) {
this.computeIsizes = computeIsizes;
}
Expand Down Expand Up @@ -1396,6 +1401,9 @@ public boolean isViewPairs() {
return viewPairs;
}

public boolean isInsertQualColoring() {
return insertQualColoring == null ? getPreferences().getAsBoolean(SAM_INSERT_QUAL_COLORING) : insertQualColoring;
}
public boolean isComputeIsizes() {
return computeIsizes == null ? getPreferences().getAsBoolean(SAM_COMPUTE_ISIZES) : computeIsizes;
}
Expand Down
13 changes: 11 additions & 2 deletions src/main/java/org/broad/igv/sam/SAMAlignment.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import org.broad.igv.sam.mods.BaseModificationSet;
import org.broad.igv.sam.smrt.SMRTKinetics;
import org.broad.igv.ui.color.ColorUtilities;
import org.broad.igv.ultima.annotate.FlowBlockAnnotator;

import java.awt.*;
import java.util.*;
Expand Down Expand Up @@ -96,6 +97,8 @@ public class SAMAlignment implements Alignment {

private int flags;

final private static FlowBlockAnnotator flowBlockAnnotator = new FlowBlockAnnotator();

/**
* Picard object upon which this SAMAlignment is based
*/
Expand Down Expand Up @@ -771,6 +774,10 @@ public String getAlignmentValueString(double position, int mouseX, AlignmentTrac
buf.append("Insertion (" + bases.length + " bases): " + new String(bases.copyOfRange(0, 25)) + "..." +
new String(bases.copyOfRange(len - 25, len)) + "<br>");
}

// extended annotation?
if ( flowBlockAnnotator.handlesBlocks(block) )
flowBlockAnnotator.appendBlockQualityAnnotation(this, block, buf);
}
atInsertion = true;
}
Expand Down Expand Up @@ -962,8 +969,10 @@ public String getAlignmentValueString(double position, int mouseX, AlignmentTrac

byte quality = block.getQuality(offset);
buf.append("Location = " + getChr() + ":" + Globals.DECIMAL_FORMAT.format(1 + (long) position) + "<br>");
buf.append("Base = " + (char) base + " @ QV " + Globals.DECIMAL_FORMAT.format(quality) + "<br>");

buf.append("Base = " + (char) base + " @ QV " + Globals.DECIMAL_FORMAT.format(quality));
if ( flowBlockAnnotator.handlesBlocks(block) )
flowBlockAnnotator.appendBlockAttrAnnotation(this, block, offset, buf);
buf.append("<br>");
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,15 @@
import org.broad.igv.feature.genome.load.HubGenomeLoader;
import org.broad.igv.logging.*;
import org.broad.igv.feature.genome.GenomeManager;
import org.broad.igv.util.GoogleUtils;
import org.broad.igv.prefs.Constants;
import org.broad.igv.prefs.PreferencesManager;
import org.broad.igv.session.SessionReader;
import org.broad.igv.ui.IGV;
import org.broad.igv.ui.util.LoadFromURLDialog;
import org.broad.igv.ui.util.MessageUtils;
import org.broad.igv.util.*;
import org.broad.igv.ui.IGVMenuBar;

import javax.swing.*;
import java.awt.*;
Expand Down Expand Up @@ -205,7 +209,6 @@ private void checkAWSAccessbility(String url) {
AmazonUtils.s3ObjectAccessResult res = isObjectAccessible(bucket, key);
if (!res.isObjectAvailable()) {
MessageUtils.showErrorMessage(res.getErrorReason(), null);
return;
}
}
} catch (NullPointerException npe) {
Expand Down
Loading