diff --git a/AnnotationSymbols.java b/AnnotationSymbols.java index ce51917..0da8dbd 100644 --- a/AnnotationSymbols.java +++ b/AnnotationSymbols.java @@ -1098,12 +1098,6 @@ private SymbolExtensionInfo drawBlock(SymbolDef symdef, GraphicsContext gc, doub } ArrayList lstBlocks = new ArrayList<>(); - if(entry.source.equals("PAR-clip")) - System.out.println("strseg es demasiado grande comparado con utrsite"); - - if(entry.source.equals("UTRsite")) - System.out.println("Ver porqué todo 0s"); - int endseg; double x, width; double mult = viewer.getViewType(viewer.getClass().toString()).equals(ViewAnnotation.Views.PROTEIN)? 3.0 : 1.0; @@ -1114,7 +1108,7 @@ private SymbolExtensionInfo drawBlock(SymbolDef symdef, GraphicsContext gc, doub boolean done = false; SymbolExtensionInfo sei = new SymbolExtensionInfo(0, 0, 0, 0); for(SeqAlign.Position pos : posList) { - if((!done && strseg >= pos.start && strseg <= pos.end)){ // || entry.source.equals("PAR-clip")) { + if((!done && strseg >= pos.start && strseg <= pos.end)){ done = true; endseg = endpos; if(endpos > pos.end) { diff --git a/SubTabBase.java b/SubTabBase.java index 4960214..888966e 100644 --- a/SubTabBase.java +++ b/SubTabBase.java @@ -816,6 +816,7 @@ protected void setupTableSearch(TableView tbl) { subTabInfo.lstSearchTables.add(tbl); } }; + // remove use one below! protected void setTableSearchActive(TableView tbl, boolean value) { if(value) { @@ -825,7 +826,7 @@ protected void setTableSearchActive(TableView tbl, boolean value) { } else { tbl.getStyleClass().removeAll("search-active"); - tbl.setStyle("-fx-background-color: #FFFFF;"); + tbl.setStyle("-fx-background-color: #FFFFF0;"); } } protected void setTableFiltered(TableView tbl, boolean filtered) { diff --git a/Tappas.java b/Tappas.java index 61e3945..b84b5fa 100644 --- a/Tappas.java +++ b/Tappas.java @@ -30,6 +30,7 @@ public class Tappas extends Application { // on the same project with multiple apps (could mess up the project data) // I think in the new Java 9 release there might be some relevant functionality // + // // The app will check if APP_LOCK_FILE exists: // a) if it does, it will get the port number from the file and try to lock it // (just in case the app aborted and did not delete the file) diff --git a/ViewAnnotation_copia.java.txt b/ViewAnnotation_copia.java.txt deleted file mode 100644 index 52ae404..0000000 --- a/ViewAnnotation_copia.java.txt +++ /dev/null @@ -1,2012 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package tappas; - -// todo: review each IS view.trans or not !!! - -import javafx.geometry.Orientation; -import javafx.scene.Cursor; -import javafx.scene.Node; -import javafx.scene.Scene; -import javafx.scene.SnapshotParameters; -import javafx.scene.canvas.Canvas; -import javafx.scene.canvas.GraphicsContext; -import javafx.scene.control.ScrollBar; -import javafx.scene.control.ScrollPane; -import javafx.scene.control.Tooltip; -import javafx.scene.image.PixelWriter; -import javafx.scene.image.WritableImage; -import javafx.scene.input.MouseEvent; -import javafx.scene.paint.Color; -import javafx.scene.text.Font; -import javafx.scene.text.TextAlignment; -import tappas.DataAnnotation.AnnotFeature; - -import java.awt.geom.Point2D; -import java.awt.geom.Rectangle2D; -import java.text.NumberFormat; -import java.util.*; - - -/** - * - * @author Hector del Risco - hdelrisco@ufl.edu & Pedro Salguero - psalguero@cipf.es - */ - -public class ViewAnnotation extends AppObject { - static public enum SortBy { - ID, LENGTH, EXPLEVEL, PROVEAN - } - public enum Views { TRANS, PROTEIN, GENOMIC }; - - // application objects - protected SubTabBase subTabBase; - protected TabBase tabBase; - - // class data - protected Canvas canvas; - protected ScrollPane canvasPane; - protected Font titleFont; - protected Color titleColor; - protected Font defaultFont; - protected Font verySmallFont; - protected Font smallFont; - protected Color defaultColor; - protected Font subFont; - protected Color subColor; - protected Font copyrightFont; - protected Color copyrightColor; - protected Font legendFont; - protected Color legendColor; - protected AnnotationEntry geneEntry = null; - protected final ArrayList annotationList = new ArrayList<>(); - protected final ArrayList proveanList = new ArrayList<>(); - protected final ArrayList tipsList = new ArrayList<>(); - protected final Tooltip tip = new Tooltip(""); - protected AnnotationEntry tipEntry = null; - protected final double levelOffset = 7; - protected double zoomPPB = 0; - protected double scale = 1; - protected double widthFactor = 1; - protected int maxExpLevel = 0; - protected AnnotationSymbols symbols; - protected final int maxCaptionLength = 45; // max number of chars to display for legend, etc. - protected final int maxTitleLength = 80; // max number of chars to display for title - protected String filterCaption = ""; - protected String lastGene = ""; - protected int rows = 0; - protected boolean displayed = false; - protected boolean lastAlignment = false; - protected boolean limitExceeded = false; - protected SortBy lastSortBy = SortBy.ID; - protected boolean lastSortDescending = false; - protected SeqAlign seqAlign = new SeqAlign(); - protected HashMap geneIsoformsExpression = new HashMap<>(); - protected HashMap geneIsoformsDEResults = new HashMap<>(); - protected final List annotationLines = new ArrayList<>(); - protected final List transcriptDisplayOrder = new ArrayList<>(); - protected HashMap>> hmFeatureIDs = new HashMap<>(); - protected HashMap>> hmGeneDiversity = null; - protected HashMap>> hmProteinGeneDiversity = null; - protected HashMap>>> hmTransAFIdPos = null; - - public ViewAnnotation(Project project) { - super(project, null); - } - public boolean initialize(SubTabBase subTabBase, Canvas canvas, ScrollPane canvasPane, String filterCaption) { - /*defaultFont = Font.font("Arial", 10); - smallFont = Font.font("Arial", 9); - verySmallFont = Font.font("Arial", 7); - defaultColor = Color.BLACK; - titleFont = Font.font("Arial", 16); - titleColor = Color.STEELBLUE; - subFont = Font.font("Arial", 13); - subColor = Color.STEELBLUE; - copyrightFont = Font.font("Arial", 10); - copyrightColor = Color.DARKGREY; - legendFont = Font.font("Arial", 10); - legendColor = Color.BLACK;*/ - - defaultFont = Font.font("Arial", 12); - smallFont = Font.font("Arial", 11); - verySmallFont = Font.font("Arial", 9); - defaultColor = Color.BLACK; - titleFont = Font.font("Arial", 18); - titleColor = Color.STEELBLUE; - subFont = Font.font("Arial", 15); - subColor = Color.STEELBLUE; - copyrightFont = Font.font("Arial", 12); - copyrightColor = Color.DARKGREY; - legendFont = Font.font("Arial", 12); - legendColor = Color.BLACK; - - this.subTabBase = subTabBase; - this.tabBase = subTabBase.tabBase; - this.canvas = canvas; - this.canvasPane = canvasPane; - this.filterCaption = filterCaption; - symbols = new AnnotationSymbols(project, null, this); - symbols.initialize(project.data.getAFStats()); - return true; - } - protected void addFeatureID(AnnotationEntry entry) { - if(!hmFeatureIDs.containsKey(entry.source)) { - HashMap> hmFeatures = new HashMap<>(); - HashMap hmIDs = new HashMap<>(); - hmIDs.put(entry.featureId, null); - hmFeatures.put(entry.feature, hmIDs); - hmFeatureIDs.put(entry.source, hmFeatures); - } - else { - HashMap> hmFeatures = hmFeatureIDs.get(entry.source); - if(!hmFeatures.containsKey(entry.feature)) { - HashMap hmIDs = new HashMap<>(); - hmIDs.put(entry.featureId, null); - hmFeatures.put(entry.feature, hmIDs); - } - else { - HashMap hmIDs = hmFeatures.get(entry.feature); - if(!hmIDs.containsKey(entry.featureId)) - hmIDs.put(entry.featureId, null); - } - } - } - protected boolean isDisplayableFeatureId(AnnotationEntry entry, Prefs prefs) { - boolean result = false; - - // check if feature not in the exclusion list - if(!prefs.isNotFeatureID(entry.source, entry.feature, entry.featureId)) { - // check if we are only including varying feature - if(prefs.showVaryingOnly) { - HashMap hmTrans = project.data.getGeneTrans(lastGene); - if(hmTransAFIdPos == null) { - ArrayList lstTrans = new ArrayList(); - for(String id : hmTrans.keySet()) - lstTrans.add(id); - hmTransAFIdPos = project.data.loadTransAFIdPos(lstTrans); - } - HashMap>> hmGD; - HashMap> hmGeneTrans = new HashMap(); - // we want to get all the features just once - user can change features filter anytime - HashMap> hmFeatures = new HashMap<>(); - for(String source : hmFeatureIDs.keySet()) { - HashMap hm = new HashMap<>(); - HashMap> hmTypes = hmFeatureIDs.get(source); - for(String type : hmTypes.keySet()) - hm.put(type, null); - hmFeatures.put(source, hm); - } - - Views view = getViewType(this.getClass().toString()); - if(view.equals(Views.PROTEIN)) { - // see if we don't have the varying information - if(hmProteinGeneDiversity == null) { - HashMap hmProteins = new HashMap<>(); - for(String trans : hmTrans.keySet()) { - if(project.data.isTransCoding(trans)) - hmProteins.put(trans, null); - } - hmGeneTrans.put(lastGene, hmProteins); - hmProteinGeneDiversity = project.data.getDiverseFeaturesUsingGenomicPositionExons(hmGeneTrans, hmFeatures, true, hmTransAFIdPos); - } - hmGD = hmProteinGeneDiversity; - } - else { - // see if we don't have the varying information - if(hmGeneDiversity == null) { - hmGeneTrans.put(lastGene, hmTrans); - hmGeneDiversity = project.data.getDiverseFeaturesUsingGenomicPositionExons(hmGeneTrans, hmFeatures, true, hmTransAFIdPos); - } - hmGD = hmGeneDiversity; - } - - if(hmGD != null) { - String fields[]; - for(String info : hmGD.keySet()) { - fields = info.split("\t"); - if(fields.length == 4) { - if(fields[0].equals(entry.source)) { - if(fields[1].equals(entry.feature)) { - if(fields[2].equals(entry.featureId)) { - HashMap> hmGenes = hmGD.get(info); - if(hmGenes.containsKey(geneEntry.id)) { - HashMap hmGDTrans = hmGenes.get(geneEntry.id); - if(hmGDTrans.containsKey(entry.id)) { // && (!protein || project.data.isTransCoding(entry.id))) { - DataAnnotation.IdPosition idpos = (DataAnnotation.IdPosition) hmGDTrans.get(entry.id); - if(idpos.pos.start == entry.strpos && idpos.pos.end == entry.endpos) { - result = true; - break; - } - } - } - } - } - } - } - } - } - } - else - result = true; - } - return result; - } - public void handleMouseClickAction(MouseEvent event) { - // override - } - public WritableImage getImage() { - WritableImage wi; - SnapshotParameters sp = new SnapshotParameters(); - wi = canvas.snapshot(sp, null); - PixelWriter pw = wi.getPixelWriter(); - return wi; - } - public double getZoomPPB() { return zoomPPB; } - public boolean hasBeenDisplayed() { return displayed; } - - // - // Mouse event handlers - // - public void onMouseMoved(MouseEvent event) { - double x = event.getX(); - double y = event.getY(); - boolean setHandCursor = false; - ArrayList fndtips = new ArrayList<>(); - Scene scene = canvas.getScene(); - Point2D.Double p = new Point2D.Double(x/scale, y/scale); - for(ToolTipPoints tips : tipsList) { - if(tips.rect.contains(p)) { - if(tips.setHandCursor) - setHandCursor = true; - fndtips.add(tips); - } - } - scene.setCursor(setHandCursor? Cursor.HAND : Cursor.DEFAULT); - if(fndtips.isEmpty()) { - tip.hide(); - tipEntry = null; - } - else { - String tooltip = ""; - for(ToolTipPoints tip : fndtips) { - tipEntry = tip.entry; - if(!tip.tooltip.isEmpty()) { - if(!tooltip.isEmpty()) - tooltip += "\n\n"; - if(tipEntry != null && lastAlignment) - tooltip += tip.tooltip + tip.entry.tooltipAligned; - else - tooltip += tip.tooltip; - } - } - if(!tooltip.isEmpty()) { - tip.setText(tooltip); - tip.setX(event.getScreenX()); - tip.setY(event.getScreenY() + 10); - tip.show(canvas.getScene().getWindow()); - } - else - tip.hide(); - } - } - public void onMouseExited(MouseEvent event) { - tip.hide(); - tipEntry = null; - //Scene scene = canvas.getScene(); - //scene.setCursor(Cursor.DEFAULT); - } - protected void onGeneChanged(String gene) { - // Override - } - - public void update(String gene, ArrayList data, Prefs prefs) { - boolean update = false; - if(!lastGene.equals(gene)) { - limitExceeded = false; - update = true; - } - if(update) { - limitExceeded = false; - if(project.data.analysis != null) { - double max = 0; - Views view = getViewType(this.getClass().toString()); - if(view.equals(Views.PROTEIN)) { - maxExpLevel = 0; - geneIsoformsDEResults = project.data.analysis.getGeneProteinsDEFlags(gene); - geneIsoformsExpression = project.data.getGeneProtsExpLevels(gene, null); - for(DataProject.TransExpLevels el : geneIsoformsExpression.values()) { - if(el.X1_mean > max) - max = el.X1_mean; - if(el.X2_mean > max) - max = el.X2_mean; - } - if(max > 0) - maxExpLevel = (int) Math.round(max + 1); - } - else { - maxExpLevel = 0; - geneIsoformsDEResults = project.data.analysis.getGeneIsoformsDEFlags(gene); - geneIsoformsExpression = project.data.getGeneIsosExpLevels(gene, null); - for(DataProject.TransExpLevels el : geneIsoformsExpression.values()) { - if(el.X1_mean > max) - max = el.X1_mean; - if(el.X2_mean > max) - max = el.X2_mean; - } - if(max > 0) - maxExpLevel = (int) Math.round(max + 1); - } - } - onGeneChanged(gene); - } - if(!lastGene.equals(gene) || lastAlignment != prefs.alignment || lastSortBy != prefs.sortBy || lastSortDescending != prefs.sortDescending) - getAnnotationData(gene, data, prefs); - - long tstart = System.nanoTime(); - System.out.println("Updating viewer. Canvas scrollPane w,h: " + canvasPane.getWidth() + ", " + canvasPane.getHeight()); - this.scale = prefs.scale; - this.widthFactor = prefs.widthFactor; - double cw = canvasPane.getWidth() - 2; - double ch = canvasPane.getHeight() - 2; - // don't bother with initial calls where size hasn't been set yet - if(cw > 100 && ch > 100) { - double sbHeight = 0.0; - double sbWidth = 0.0; - Set nodes = canvasPane.lookupAll(".scroll-bar"); - for (final Node node : nodes) { - if (node instanceof ScrollBar) { - ScrollBar sb = (ScrollBar) node; - if (sb.getOrientation() == Orientation.HORIZONTAL) // && sb.isVisible()) - sbHeight = sb.getHeight(); - else if (sb.getOrientation() == Orientation.VERTICAL) // && sb.isVisible()) - sbWidth = sb.getWidth(); - } - } - if(sbHeight > 0) - ch -= sbHeight; - if(sbWidth > 0) - cw -= sbWidth; - canvas.setWidth(cw / scale); - canvas.setHeight(ch); - GraphicsContext gc = canvas.getGraphicsContext2D(); - gc.save(); - gc.scale(scale, scale); - displayed = true; - DrawArgs args = new DrawArgs(prefs, 1, 50, false); - draw(gc, args); - gc.restore(); - } - long tend = System.nanoTime(); - long duration = (tend - tstart)/1000000; - System.out.println("Drawing time: " + duration + " ms"); - } - protected void draw(GraphicsContext gc, DrawArgs args) { - // override - } - protected void drawTrackSymbol(AnnotationEntry entry, AnnotationEntry geneEntry, AnnotationEntry seqEntry, - ArrayList tgexonsList, - ArrayList cdsList, ArrayList> seqList, - GraphicsContext gc, double x, double y, double ppb, - boolean negStrand, boolean genomic, boolean alignment, SeqAlign.WithinRegion within) { - if(entry.symbol == null || entry.symbol.symbolDef == null) - return; - - // assign the arrows to the bottom by default - AnnotationFileDefs defs = project.data.getAnnotationFileDefs(); - AnnotationSymbols.SymbolDef symdef = entry.symbol.symbolDef; - boolean bottom = (symdef.shape == AnnotationSymbols.Shape.ARROW); - boolean bottomOnly = false; - boolean blockFeature = AnnotationSymbols.isBlockSymbol(symdef); - double w; - double h = (symdef.shape != AnnotationSymbols.Shape.DROP && symdef.shape != AnnotationSymbols.Shape.NONE)? symdef.height : symdef.value; - boolean extended = false; - if(!defs.isDomain(seqEntry.source, seqEntry.feature) && !blockFeature) { - double sp = entry.dspstrpos * ppb; - double dp = entry.dsppos * ppb; - double sw = dp - AnnotationSymbols.MaxSymbolWidth/2 - 2; - if(sw > sp) { - double rw = (entry.endpos - entry.strpos + 1); // * ppb; - double rwd = rw * ppb; - double rx = x + (entry.dspstrpos - geneEntry.strpos + 1); // * ppb; - double rxd = x + (entry.dspstrpos - geneEntry.strpos + 1) * ppb; - int level = -1; - for(AnnotationEntry cds : cdsList) { - // do not allow adding on top if CDS section, can crowd splice junctions - if(entry.dsppos > (cds.strpos - rw/2) && entry.dsppos < (cds.endpos + rw/2)) { - bottom = true; - bottomOnly = true; - // will also not try to add to seqList(1) since it can cause display issues (think Tetris) - while(seqList.size() < 3) - seqList.add(new ArrayList<>()); - break; - } - } - if(!bottomOnly) { - // check to see if there is room, top or botom - if(bottom) { - if(IsThereRoom(seqList.get(1), symdef, rx, rw, rxd, rwd)) - level = 1; //!bottomOnly && - else if(IsThereRoom(seqList.get(0), symdef, rx, rw, rxd, rwd)) { - level = 0; - bottom = false; - } - } - else { - if(IsThereRoom(seqList.get(0), symdef, rx, rw, rxd, rwd)) - level = 0; - else if(IsThereRoom(seqList.get(1), symdef, rx, rw, rxd, rwd)) { - level = 1; - bottom = true; - } - } - } - if(level == -1) { - // only add new rows to bottom - int cnt = seqList.size(); - for(int i = 2; i < cnt; i++) { - if(IsThereRoom(seqList.get(i), symdef, rx, rw, rxd, rwd)) { - level = i; - break; - } - } - if(level == -1) { - level = seqList.size(); - // do not allow intron symbols to get out of control - may want to refine later (add + symbol)!!! -//figure out why this is -> return !!! did I decide to only allow 5 rows? i don't think so, look into SeqAlign.WithinRegion.YES - if(!within.equals(SeqAlign.WithinRegion.YES)) { - if(level > 5) - return; - } - seqList.add(new ArrayList<>()); - //System.out.println("Added new level, " + level + ", for " + "x: " + entry.strpos); - } - bottom = true; - y += (level - 1) * levelOffset; - } - seqList.get(level).add(new UsedPoints(rx, rw, rxd, rwd)); - //dbg: System.out.println("Adding to seqList: " + rxd + ", " + rwd + ", entry: " + entry.strpos + ", " + entry.endpos); - y += bottom? 2 : -(h + 2); - //System.out.println("sym cdslist: " + cdsList.size() + ", y: " + y); - - // call proper drawing function based on alignment option value - if(alignment) { - // get min/max to set tool tip - AnnotationSymbols.SymbolExtensionInfo sei = symbols.drawSymbolExtension(gc, x, y, Math.max(symdef.height, symdef.value), ppb, - AnnotationSymbols.getFillColor(symdef.colorsIdx), tgexonsList, seqAlign, entry, geneEntry); - boolean reverse = (negStrand && genomic); - String pos = String.format("%s%s", NumberFormat.getInstance().format(reverse? entry.endpos : entry.strpos), - (entry.strpos == entry.endpos)? "" : String.format(" - %s", NumberFormat.getInstance().format(reverse? entry.strpos : entry.endpos))); - tipsList.add(new ToolTipPoints(entry, sei.minX, y, (sei.maxX - sei.minX + 1), Math.max(symdef.height, symdef.value), - String.format("%s\nPosition: %s", entry.tooltip, pos), true)); - // if symbol extension spanned across introns, need to reserve full area - if(sei.segments > 1) { - System.out.println("Symbol extension spanned across intron, updating seqList with " + sei.minX + ", " + (sei.maxX - sei.minX + 1) + ", entry: " + entry.strpos + ", " + entry.endpos); - seqList.get(level).add(new UsedPoints(sei.minX, (sei.maxX - sei.minX + 1), sei.minX, (sei.maxX - sei.minX + 1))); - } - } - else { - symbols.drawSymbolExtension(gc, rxd, y, rwd, Math.max(symdef.height, symdef.value), AnnotationSymbols.getFillColor(symdef.colorsIdx)); - boolean reverse = (negStrand && genomic); - String pos = String.format("%s%s", NumberFormat.getInstance().format(reverse? entry.endpos : entry.strpos), - (entry.strpos == entry.endpos)? "" : String.format(" - %s", NumberFormat.getInstance().format(reverse? entry.strpos : entry.endpos))); - tipsList.add(new ToolTipPoints(entry, rxd, y, rwd, Math.max(symdef.height, symdef.value), - String.format("%s\nPosition: %s", entry.tooltip, pos), true)); - } - extended = true; - } - } - else { - // set the block width if block feature - if(blockFeature) - entry.symbol.wBlock = (entry.dspendpos - entry.dspstrpos + 1); - } - - // check if doing a block feature, set x and w accordingly - double xt, xd, wd; - if(blockFeature) { - w = entry.symbol.wBlock; - wd = entry.symbol.wBlock * ppb; - entry.symbol.wBlock = wd; - xd = x; - if(!alignment) - xd += ((entry.dspstrpos - geneEntry.strpos + 1) * ppb); - xt = x; - x += (entry.dspstrpos - geneEntry.strpos + 1); // * ppb; - xt += ((entry.dspstrpos - geneEntry.strpos + 1) * ppb); - } - else { - w = symdef.width; - wd = symdef.width; - xd = x; - x += (entry.dsppos - geneEntry.strpos + 1); // * ppb; - x -= w/2; - xd += (entry.dsppos - geneEntry.strpos + 1) * ppb; - xd -= w/2; - xt = xd; - } - int level = -1; - if(!extended) { - for(AnnotationEntry cds : cdsList) { - // do not allow adding on top if CDS section, can crowd splice junctions - if(entry.dsppos > (cds.strpos - w/2) && entry.dsppos < (cds.endpos + w/2)) { - bottom = true; - bottomOnly = true; - // will also not try to add to seqList(1) since it can cause display issues (think Tetris) - while(seqList.size() < 3) - seqList.add(new ArrayList<>()); - break; - } - } - if(!bottomOnly) { - // check to see if there is room, top or bottom - if(bottom) { - if(IsThereRoom(seqList.get(1), symdef, x, w, xt, wd)) - level = 1; //!bottomOnly && - else if(IsThereRoom(seqList.get(0), symdef, x, w, xt, wd)) { - level = 0; - bottom = false; - } - } - else { - if(IsThereRoom(seqList.get(0), symdef, x, w, xt, wd)) - level = 0; - else if(IsThereRoom(seqList.get(1), symdef, x, w, xt, wd)) { - level = 1; - bottom = true; - } - } - } - if(level == -1) { - // only add new rows to bottom - int cnt = seqList.size(); - for(int i = 2; i < cnt; i++) { - if(IsThereRoom(seqList.get(i), symdef, x, w, xt, wd)) { - level = i; - break; - } - } - if(level == -1) { - level = seqList.size(); - // do not allow intron symbols to get out of control - may want to refine later (add + symbol)!!! -//figure out why this is -> return !!! did I decide to only allow 5 rows? i don't think so, look into SeqAlign.WithinRegion.YES - if(!within.equals(SeqAlign.WithinRegion.YES)) { - if(level > 5) - return; - } - seqList.add(new ArrayList<>()); - //System.out.println("Added new level, " + level + ", for " + "x: " + entry.strpos); - } - bottom = true; - y += (level - 1) * levelOffset; - } - seqList.get(level).add(new UsedPoints(x, w, xt, wd)); - //dbg: System.out.println("Adding to seqList: " + xt + ", " + wd + ", entry: " + entry.strpos + ", " + entry.endpos); - y += bottom? 2 : -(h + 2); - //System.out.println("sym cdslist: " + cdsList.size() + ", y: " + y); - boolean reverse = (negStrand && genomic); - String pos = String.format("%s%s", NumberFormat.getInstance().format(reverse? entry.endpos : entry.strpos), - (entry.strpos == entry.endpos)? "" : String.format(" - %s", NumberFormat.getInstance().format(reverse? entry.strpos : entry.endpos))); - tipsList.add(new ToolTipPoints(entry, xt, y, wd, Math.max(symdef.height, symdef.value), - String.format("%s\nPosition: %s", entry.tooltip, pos), true)); - //(entry.tooltip.isEmpty()? "" : String.format("\n\n%s", entry.tooltip))))); - } - - // draw actual feature symbol - // Note that when drawing block symbols xd = the original x passed which is just the offset to start if alignment is on - // this is done since block symbols need to handle being split into chunks to avoid introns (when alignment is on) - // the offset to y below is just for looks - centering the block in its lane since it has a smaller than normal height - if(blockFeature && level != -1) { - if(level == 0) - y -= 1; - else - y += 1; - - if(entry.source.equals("UTRsite")) - System.out.println("Estamos donde toca"); - - if(entry.source.equals("PAR-clip")) - System.out.println("Estamos donde toca"); - - AnnotationSymbols.SymbolExtensionInfo sei = symbols.draw(entry.symbol, gc, xd, y, ppb, bottom, within, tgexonsList, (alignment? seqAlign : null), entry, geneEntry); - if(alignment && sei != null && sei.segments > 1) { - // if block spanned across introns, need to reserve full area - System.out.println("Block feature spanned across intron, updating seqList with " + sei.minX + ", " + (sei.maxX - sei.minX + 1) + ", entry: " + entry.strpos + ", " + entry.endpos); - seqList.get(level).add(new UsedPoints(sei.minX, (sei.maxX - sei.minX + 1), sei.minX, (sei.maxX - sei.minX + 1))); - } - } - else - symbols.draw(entry.symbol, gc, xd, y, ppb, bottom, within, tgexonsList, (alignment? seqAlign : null), entry, geneEntry); - } - // Note: strpos and endpos denot the lowest and highest positions of the genomic display - protected double drawGenomicTracks(HashMap> hmAnnots, - GraphicsContext gc, double x, double y, double ppb, double strpos, double endpos, boolean negStrand) { - double newy = y; - for(String key : hmAnnots.keySet()) { - ArrayList lst = hmAnnots.get(key); - String[] fields = key.split("\t"); - gc.setFont(verySmallFont); - gc.setFill(Color.BLACK); - gc.setTextAlign(TextAlignment.RIGHT); - gc.fillText(fields[0], x - 5, newy); - gc.fillText(fields[1], x - 5, newy+10); - double dspx; - double dspy; - double refpos = negStrand? endpos : strpos; - for(AnnotationEntry ae : lst) { - dspx = adjustX(x + Math.abs((negStrand? ae.endpos : ae.strpos) - refpos) * ppb); - dspy = adjustY(newy - (AnnotationSymbols.CDSblockHeight/2)); - double width = Math.max((Math.abs(ae.endpos - ae.strpos) + 1), 2) * ppb; - symbols.drawGenomicSymbol(gc, dspx, dspy, width); - AnnotationEntry ttae = ae; - if(negStrand) - ttae = new AnnotationEntry(ae.id, ae.source, ae.feature, ae.featureId, ae.caption, ae.strand, ae.endpos, ae.strpos, ae.attrs, ae.tooltip, ae.urlValue); - addToolTipToList(ttae, dspx - 1, dspy, Math.abs(ae.endpos - ae.strpos) * ppb + 2, AnnotationSymbols.CDSblockHeight, false); - } - newy += AnnotationSymbols.CDSblockHeight + 10; - } - return newy; - } - public Views getViewType(String className) { - Views view = Views.TRANS; - if(className.contains("ViewProtein")) - view = Views.PROTEIN; - if(className.contains("ViewGenomic")) - view = Views.GENOMIC; - return view; - } - - protected void getAnnotationData(String gene, ArrayList data, Prefs prefs) { - long tstart = System.nanoTime(); - lastGene = gene; - lastAlignment = prefs.alignment; - lastSortBy = prefs.sortBy; - lastSortDescending = prefs.sortDescending; - seqAlign.clearData(); - annotationList.clear(); - proveanList.clear(); - transcriptDisplayOrder.clear(); - Views view = getViewType(this.getClass().toString()); - //System.out.println("getAnnotationData for " + view.name()); - - // build list of gene transcripts and provean data - List transcripts = new ArrayList<>(); - AnnotationFileDefs defs = project.data.getAnnotationFileDefs(); - for(String[] fields : data) { - String source = fields[1]; - String type = fields[2]; - if(project.data.getRsvdAnnotFeature(source, type).equals(AnnotFeature.TRANSCRIPT)) - transcripts.add(fields[0]); - else if(fields[1].equals(defs.pScore.source) && fields[2].equals(defs.pScore.feature)) - proveanList.add(new ProveanData(fields[0], fields[8])); - } - if(prefs.sortBy == SortBy.EXPLEVEL) { - List lst = new ArrayList<>(); - for(String trans : transcripts) { - double level = 0.0; - if(view.equals(Views.PROTEIN)) { - String prot = project.data.getTransProtein(trans); - if(geneIsoformsExpression.containsKey(prot)) { - DataProject.TransExpLevels el = geneIsoformsExpression.get(prot); - level = (el.X1_mean + el.X2_mean) / 2; - } - } - else { - if(geneIsoformsExpression.containsKey(trans)) { - DataProject.TransExpLevels el = geneIsoformsExpression.get(trans); - level = (el.X1_mean + el.X2_mean) / 2; - } - } - lst.add(new TranscriptSortEntry(level, trans)); - } - Collections.sort(lst); - Collections.reverse(lst); - if(prefs.sortDescending) - Collections.reverse(lst); - transcripts.clear(); - for(TranscriptSortEntry tse : lst) - transcripts.add(tse.id); - } - else if(prefs.sortBy == SortBy.LENGTH) { - List lst = new ArrayList<>(); - for(String trans : transcripts) { - if(view.equals(Views.TRANS)) - lst.add(new TranscriptSortEntry(project.data.getTransLength(trans), trans)); - else if(view.equals(Views.GENOMIC)) - lst.add(new TranscriptSortEntry(project.data.getTransGenomicLength(trans), trans)); - else - lst.add(new TranscriptSortEntry(project.data.getTransProteinLength(trans), trans)); - } - Collections.sort(lst); - if(prefs.sortDescending) - Collections.reverse(lst); - transcripts.clear(); - for(TranscriptSortEntry tse : lst) - transcripts.add(tse.id); - } - else if(prefs.sortBy == SortBy.PROVEAN) { - Collections.sort(proveanList); - if(prefs.sortDescending) - Collections.reverse(proveanList); - - // it is possible that all transcripts are not in provean list - List tmp = transcripts; - transcripts = new ArrayList<>(); - for(ProveanData pd : proveanList) - transcripts.add(pd.trans); - for(String trans : tmp) { - if(!transcripts.contains(trans)) - transcripts.add(trans); - } - } - else { - Collections.sort(transcripts, String.CASE_INSENSITIVE_ORDER); - if(prefs.sortDescending) - Collections.reverse(transcripts); - } - - // get annotations for each transcript in the list - // get gene description and largest size of all transcript - // sort transcript annotations based on type and size - chosen convention for display - String geneName = gene; - String geneAttrs = ""; - int largest = 0; - ArrayList gtlst = new ArrayList<>(); - //System.out.println("Transcripts:"); - for(String rsid : transcripts) { - ArrayList alst = new ArrayList<>(); - getRSAnnotationData(rsid, data, alst); - for(AnnotationEntry a : alst) { - if(project.data.getRsvdAnnotFeature(a.source, a.feature).equals(view.equals(Views.PROTEIN)? AnnotFeature.PROTEIN : AnnotFeature.TRANSCRIPT)) { - ViewAnnotationEntry gta = new ViewAnnotationEntry(a.id, Math.abs(a.endpos - a.strpos) + 1, alst); - gtlst.add(gta); - if(gta.size > largest) - largest = gta.size; - } - else if(project.data.getRsvdAnnotFeature(a.source, a.feature).equals(AnnotFeature.GENE)) { - if(geneAttrs.isEmpty()) { - HashMap attrs = DataAnnotation.getAttributes(a.attrs); - if(attrs.containsKey(project.data.getAnnotationFileDefs().attrName)) - geneName = attrs.get(project.data.getAnnotationFileDefs().attrName); - geneAttrs = a.attrs; - } - break; - } - } - } - //System.out.println("Largest size: " + largest); - - // process the individual transcript annotations - boolean chkStrand = false; - boolean negStrand = false; - String strand; - boolean warnlen = true; - ArrayList ntexonsList = new ArrayList<>(); - ArrayList ntcdsList = new ArrayList<>(); - for(ViewAnnotationEntry gta : gtlst) { - ArrayList al = new ArrayList<>(); - - // save order - transcriptDisplayOrder.add(gta.id); - - // check if using alignment - int addit = 1; - boolean warnStrand = true; - AnnotationEntry cds = null; - AnnotationEntry trans = null; - AnnotationEntry ntexon = null; - - // right now only the exon entries have the strand set - // we need it in the transcript entry for display purposes - strand = ""; - for(AnnotationEntry a : gta.alst) { - if(!a.strand.isEmpty() && !a.strand.equals(".")) { - strand = a.strand; - break; - } - } - negStrand = strand.equals("-"); - if(prefs.alignment) { - addit = 0; - for(AnnotationEntry a : gta.alst) { - if(project.data.getRsvdAnnotFeature(a.source, a.feature).equals(AnnotFeature.TRANSCRIPT)) { - trans = a; - cds = null; - ntexon = null; - ntexonsList = new ArrayList<>(); - } - if(project.data.getRsvdAnnotFeature(a.source, a.feature).equals(AnnotFeature.CDS)) - cds = a; - - // only add transcript if we have alignment data - if(project.data.getRsvdAnnotFeature(a.source, a.feature).equals(AnnotFeature.EXON)) { - // build alignment exons data for gap calculations - addit |= 1; - if(ntexon == null) - ntexon = a; - boolean ns = a.strand.equals("-"); - if(chkStrand) { - if(negStrand != ns) { - //System.out.println("addit: " + addit); - if(warnStrand) { - warnStrand = false; - logger.logWarning("Gene, " + gene + ", contains transcripts on both strands. Only showing alignment for " + (negStrand? "negative" : "positive") + " strand."); - } - addit = 0; - } - } - else - chkStrand = true; - } - } - } - if(addit == 1) { - // add all annotations, except exons, for this transcript to annotation list - for(AnnotationEntry a : gta.alst) { - if(!project.data.getRsvdAnnotFeature(a.source, a.feature).equals(AnnotFeature.EXON)) - al.add(a); - } - - // add all annotations for this transcript to annotation list - ArrayList tmpList = new ArrayList<>(); - for(AnnotationEntry a : gta.alst) { - // exons must be in order: asc for + strand and desc for - strand - if(project.data.getRsvdAnnotFeature(a.source, a.feature).equals(AnnotFeature.EXON)) { - int idx = 0; - boolean append = true; - for(AnnotationEntry ta : tmpList) { - if(negStrand) { - if(a.strpos > ta.strpos) { - tmpList.add(idx, a); - append = false; - break; - } - } - else { - if(a.strpos < ta.strpos) { - tmpList.add(idx, a); - append = false; - break; - } - } - idx++; - } - if(append) - tmpList.add(a); - } - } - int sortidx = 0; - AnnotationEntry ea; - AnnotationEntry lastExon = null; - AnnotationEntry firstExon = null; - for(AnnotationEntry a : gta.alst) { - // exons must be in order - asc for + strand and desc for - strand - if(project.data.getRsvdAnnotFeature(a.source, a.feature).equals(AnnotFeature.EXON)) { - ea = tmpList.get(sortidx++); - ntexonsList.add(new SeqAlign.Position(ea.strpos, ea.endpos)); - seqAlign.updGeneExonsList(ea.strpos, ea.endpos); - al.add(ea); - //System.out.println("Adding sorted exon: " + ea.strpos + " - " + ea.endpos); - if(lastExon == null || ea.endpos > lastExon.endpos) - lastExon = ea; - if(firstExon == null || ea.strpos < lastExon.strpos) - firstExon = ea; - } - } - //System.out.println("SeqAlign exons: " + seqAlign.getGeneExonsString()); - - // check if alignment and CDS - if(prefs.alignment && cds != null && trans != null) { - // generate internal CDS values - Collections.sort(ntexonsList); - //System.out.println("ntexonslist:"); - int translen = trans.endpos - trans.strpos + 1; - int exonlen = 0; - for(SeqAlign.Position pos : ntexonsList) { - exonlen += Math.abs(pos.end - pos.start) + 1; - //System.out.println(pos.start + ".." + pos.end); - } - int strpos; - int diff = Math.abs(translen - exonlen); - if(translen > exonlen) { - // make msg strand sensitive - if(negStrand) { - firstExon.strpos -= diff; - firstExon.ostrpos = firstExon.strpos; - ntexonsList.get(0).start -= diff; - } - else { - lastExon.endpos += diff; - lastExon.oendpos = lastExon.endpos; - ntexonsList.get(ntexonsList.size()-1).end += diff; - } - if(warnlen) { - warnlen = false; - logger.logWarning("The transcript length and the sum of the exon lengths are different. Alignment may not be accurate."); - } - logger.logInfo("Transcript " + trans.id + " length is longer, " + diff + "nt, than the sum of the exon lengths. Alignment may not be accurate."); - } - else if(translen < exonlen) { - // make msg strand sensitive - if(negStrand) { - int lastlen = firstExon.endpos - firstExon.strpos + 1; - if(lastlen > diff) { - firstExon.strpos += diff; - firstExon.ostrpos = firstExon.strpos; - ntexonsList.get(0).start += diff; - } - else { -//DO now!!! - when removing an exon just chg to ~ignore~ type and ignore it in the display - // must go back until proper exon found, and adjust that entry - // in addition, must delete extra exons entries at the end!!! - // not very clean - leave out until I get the new tsv file - } - } - else { - int lastlen = lastExon.endpos - lastExon.strpos + 1; - if(lastlen > diff) { - lastExon.endpos -= diff; - lastExon.oendpos = lastExon.endpos; - ntexonsList.get(ntexonsList.size()-1).end -= diff; - } - else { -//DO now!!! - when removing an exon just chg to ~ignore~ type and ignore it in the display - // must go back until proper exon found, and adjust that entry - // in addition, must delete extra exons entries at the end!!! - // not very clean - leave out until I get the new tsv file - } - } - if(warnlen) { - warnlen = false; - logger.logWarning("The transcript length and the sum of the exon lengths are different. Alignment may not be accurate."); - } - logger.logInfo("Transcript " + trans.id + " length is shorter, " + diff + "nt, than the sum of the exon lengths. Alignment may not be accurate."); - } - //System.out.println("Trans: " + trans.strpos + " to " + trans.endpos + ", (" + strpos + ", " + endpos + ")"); - int cdslen = cds.endpos - cds.strpos + 1; - int cdsstrpos = cds.strpos; - int cdsendpos = cds.endpos; - if(negStrand) { - cdsstrpos = (trans.endpos - cds.endpos + 1); - cdsendpos = cdsstrpos + cdslen - 1; - strpos = (int) seqAlign.getGenomicPos((double) cdsstrpos, ntexonsList); - } - else { - strpos = (int) SeqAlign.getGenomicPos((double) cds.strpos, ntexonsList); - } - // generate 5/3 internal UTR genomic start and end values, only one entry which can span multiple exons - // will be split up properly later on at display time... - int lendpos, rstrpos, rendpos; - int lstrpos = (int) SeqAlign.getGenomicPos((double) trans.strpos, ntexonsList); - // the transcript length and the length computed by exons does not match often, go with trans length - rendpos = (int) SeqAlign.getGenomicPos((double) trans.endpos, ntexonsList); //ntexonsList.get(ntexonsList.size()-1).end; - if(negStrand) { - if(cds.strpos > 1) { - rstrpos = (int) SeqAlign.getGenomicPos((double) (trans.endpos - cds.strpos + 2), ntexonsList); - AnnotationEntry autr = new AnnotationEntry(ntexon.id, DataAnnotation.INTDB, DataAnnotation.INTCAT_5UTR, "", "", "", rstrpos, rendpos, ".", "", ""); - if(view.equals(Views.TRANS)) - al.add(autr); - //System.out.println("Calc neg strand 5'UTR for " + ntexon.id + ": " + rstrpos + " to " + rendpos); - } - if(cds.endpos < trans.endpos) { - lendpos = (int) SeqAlign.getGenomicPos((double) (trans.endpos - (cds.endpos + 1) + 1), ntexonsList); - AnnotationEntry autr = new AnnotationEntry(ntexon.id, DataAnnotation.INTDB, DataAnnotation.INTCAT_3UTR, "", "", "", lstrpos, lendpos, ".", "", ""); - if(view.equals(Views.TRANS)) - al.add(autr); - //System.out.println("Calc neg strand 3'UTR for " + ntexon.id + ": " + lstrpos + " to " + lendpos); - } - } - else { - if(cds.strpos > 1) { - lendpos = (int) SeqAlign.getGenomicPos((double) (cds.strpos - 1), ntexonsList); - AnnotationEntry autr = new AnnotationEntry(ntexon.id, DataAnnotation.INTDB, DataAnnotation.INTCAT_5UTR, "", "", "", lstrpos, lendpos, ".", "", ""); - if(view.equals(Views.TRANS)) - al.add(autr); - //System.out.println("Calc pos strand 5'UTR for " + ntexon.id + ": " + lstrpos + " to " + lendpos); - } - if(cds.endpos < trans.endpos) { - rstrpos = (int) SeqAlign.getGenomicPos((double) (cds.endpos + 1), ntexonsList); - AnnotationEntry autr = new AnnotationEntry(ntexon.id, DataAnnotation.INTDB, DataAnnotation.INTCAT_3UTR, "", "", "", rstrpos, rendpos, ".", "", ""); - if(view.equals(Views.TRANS)) - al.add(autr); - //System.out.println("Calc pos strand 3'UTR for " + ntexon.id + ": " + rstrpos + " to " + rendpos); - } - } - - // generate CDS exons using given exon entries which are already in ascending order - boolean strfnd = false; - strpos = (int) seqAlign.getGenomicPos((double) cdsstrpos, ntexonsList); - //System.out.println("CDS start width: " + cdslen); - //System.out.println("CDS genomic pos: " + strpos + " to " + endpos); - tmpList.clear(); - for(SeqAlign.Position pos : ntexonsList) { - if(strfnd) { - // add exon partial or full based on cdslen left - int cnt = pos.end - pos.start + 1; - int end = pos.end; - if(cnt > cdslen) { - end = pos.start + cdslen - 1; - cdslen = 0; - } - else - cdslen -= cnt; - ntcdsList.add(new SeqAlign.Position(pos.start, end)); - AnnotationEntry acds = new AnnotationEntry(ntexon.id, DataAnnotation.INTDB, DataAnnotation.INTCAT_CDS, "", "", "", pos.start, end, ".", "", ""); - tmpList.add(acds); - } - else { - // find exon where left position falls in - if(strpos >= pos.start && strpos <= pos.end) { - strfnd = true; - int cnt = pos.end - strpos + 1; - int end = pos.end; - if(cnt > cdslen) { - end = strpos + cdslen - 1; - cdslen = 0; - } - else - cdslen -= cnt; - ntcdsList.add(new SeqAlign.Position(strpos, end)); - AnnotationEntry acds = new AnnotationEntry(ntexon.id, DataAnnotation.INTDB, DataAnnotation.INTCAT_CDS, "", "", "", strpos, end, ".", "", ""); - tmpList.add(acds); - } - } - if(cdslen <= 0) - break; - } - //for(SeqAlign.Position pos : ntcdsList) - // System.out.println("cds_exon: " + pos.start + " to " + pos.end); - if(negStrand) { - if(!tmpList.isEmpty()) { - for(int idx = tmpList.size() - 1; idx >= 0; idx--) - al.add(tmpList.get(idx)); - } - } - else { - for(AnnotationEntry ta : tmpList) - al.add(ta); - } - } - if(!view.equals(Views.TRANS) && !view.equals(Views.GENOMIC)) { - ArrayList alst = new ArrayList<>(); - for(AnnotationEntry a : al) - alst.add(a); - al.clear(); - for(AnnotationEntry a : alst) { - if(!project.data.getRsvdAnnotFeature(a.source, a.feature).equals(AnnotFeature.TRANSCRIPT)) - al.add(a); - } - } - } - else { - // there is no alignment data for this transcript - // add basic data and append a display line for 'no alignment data' - for(AnnotationEntry a : gta.alst) { - if(project.data.getRsvdAnnotFeature(a.source, a.feature).equals(view.equals(Views.PROTEIN)? AnnotFeature.PROTEIN : AnnotFeature.TRANSCRIPT) - || project.data.getRsvdAnnotFeature(a.source, a.feature).equals(AnnotFeature.GENE)) - al.add(a); - if(view.equals(Views.GENOMIC)) { - if(project.data.getRsvdAnnotFeature(a.source, a.feature).equals(AnnotFeature.GENOMIC)) - al.add(a); - } - } - al.add(new AnnotationEntry("NoAlignmentData", DataAnnotation.INTDB, DataAnnotation.INTCAT_NODATA, "", "", "", 0, 0, "", "", "")); - } - // if the transcript does not have any annotation symbols, we need to flush out the exon alignment data - if(prefs.alignment) - al.add(new AnnotationEntry("FlushAlignmentData", DataAnnotation.INTDB, DataAnnotation.INTCAT_FLUSHDATA, "", "", "", 0, 0, "", "", "")); - - for(AnnotationEntry a : al) { - if(project.data.getRsvdAnnotFeature(a.source, a.feature).equals(view.equals(Views.PROTEIN)? AnnotFeature.PROTEIN : AnnotFeature.TRANSCRIPT)) { - if(a.strand.isEmpty() || a.strand.equals(".")) - a.strand = strand; - annotationList.add(a); - break; - } - } - if(view.equals(Views.GENOMIC)) { - for(AnnotationEntry a : al) { - if(project.data.getRsvdAnnotFeature(a.source, a.feature).equals(AnnotFeature.GENOMIC)) { - al.add(a); - break; - } - } - } - for(AnnotationEntry a : al) { - if(project.data.getRsvdAnnotFeature(a.source, a.feature).equals(AnnotFeature.GENE)) { - annotationList.add(a); - break; - } - } - for(AnnotationEntry a : al) { - if(project.data.getRsvdAnnotFeature(a.source, a.feature).equals(AnnotFeature.CDS)) { - annotationList.add(a); - break; - } - } - for(AnnotationEntry a : al) { - if(a.feature.equals(DataAnnotation.INTCAT_5UTR) || a.feature.equals(DataAnnotation.INTCAT_3UTR)) - annotationList.add(a); - } - for(AnnotationEntry a : al) { - if(project.data.getRsvdAnnotFeature(a.source, a.feature).equals(AnnotFeature.EXON)) { - annotationList.add(a); - // add copy so that it can be modified, if negative strand, w/o affecting the original - AnnotationEntry ane = new AnnotationEntry(a.id, DataAnnotation.INTDB, DataAnnotation.INTCAT_EXON, "", "", "", a.strpos, a.endpos, ".", "", ""); - annotationList.add(ane); - } - else if(a.feature.equals(DataAnnotation.INTCAT_CDS)) - annotationList.add(a); - } - for(AnnotationEntry a : al) { - if(project.data.getRsvdAnnotFeature(a.source, a.feature).equals(AnnotFeature.SPLICEJUNCTION)) { - annotationList.add(a); - // add copy so that it can be modified, if negative strand, w/o affecting the original - AnnotationEntry ane = new AnnotationEntry(a.id, DataAnnotation.INTDB, DataAnnotation.INTCAT_SPLICEJUNCTION, "", "", "", a.strpos, a.endpos, ".", "", ""); - annotationList.add(ane); - } - } - for(AnnotationEntry a : al) { - if(a.feature.equals(DataAnnotation.INTCAT_FLUSHDATA) || a.feature.equals(DataAnnotation.INTCAT_NODATA)) - annotationList.add(a); - } - for(AnnotationEntry a : al) { - if(!project.data.getRsvdAnnotFeature(a.source, a.feature).equals(AnnotFeature.TRANSCRIPT) && - !project.data.getRsvdAnnotFeature(a.source, a.feature).equals(AnnotFeature.PROTEIN) && - !project.data.getRsvdAnnotFeature(a.source, a.feature).equals(AnnotFeature.GENE) && - !project.data.getRsvdAnnotFeature(a.source, a.feature).equals(AnnotFeature.CDS) && - !project.data.getRsvdAnnotFeature(a.source, a.feature).equals(AnnotFeature.EXON) && - !project.data.getRsvdAnnotFeature(a.source, a.feature).equals(AnnotFeature.SPLICEJUNCTION) - && !project.data.isInternalFeature(a.source, a.feature)) - - if(a.source.equals("PAR-clip")) - System.out.println("Estamos donde toca"); - - annotationList.add(a); - } - } - - // check if using alignment - do additional processing if so - if(prefs.alignment && !ntexonsList.isEmpty()) { - if(view.equals(Views.PROTEIN)) { //!!!? - seqAlign.clearData(); - for(SeqAlign.Position pos : ntcdsList) - seqAlign.updGeneExonsList(pos.start, pos.end); - } - // calculate size, start and end position for gene display - // exons from all transcripts count toward the total size - largest = seqAlign.getGeneExonsSize(); - if(view.equals(Views.PROTEIN)) - largest = largest / 3; - //System.out.println("Gene Alignment: " + 1 + ".." + largest); - // reverse positions if negative strand - if(negStrand) { - // calculate lowest and highest genome position values for all isoforms, and then - // reverse values for lstGeneExons and sort - required for proper alignment - SeqAlign.Position pos = seqAlign.getGeneExonsRange(); - int end = pos.end; - // WARNING: this function changes seqAlign values from genomic to 1 based - // this was an easy way to deal with the negative strand but it has a drawback - must keep in mind - seqAlign.reverseGeneExons(); - - // reverse values for all internal annotations - for(AnnotationEntry a : annotationList) { - if(project.data.isInternalFeature(a.source, a.feature)) { - a.strpos = end - a.oendpos + 1; - a.endpos = end - a.ostrpos + 1; - if(a.feature.equals(DataAnnotation.INTCAT_SPLICEJUNCTION)) { - // SJs position is located in the intron, adjust for display - a.strpos--; - a.endpos++; - System.out.println(a.feature + ": " + a.ostrpos + ".." + a.oendpos + " to " + a.strpos + ".." + a.endpos); - } - } - } - } - else { - for(AnnotationEntry a : annotationList) { - if(a.feature.equals(DataAnnotation.INTCAT_SPLICEJUNCTION)) { - a.strpos--; - a.endpos++; - } - } - } - } - // handle length of 0 - if(largest < 1) - largest = 1; - String tooltip = geneName + "\n"; - String urlValue = ""; - if(!geneAttrs.isEmpty()) { - HashMap attrs = DataAnnotation.getAttributes(geneAttrs); - if(attrs.containsKey(project.data.getAnnotationFileDefs().attrId)) { - urlValue = attrs.get(project.data.getAnnotationFileDefs().attrId); - tooltip += "ID: " + urlValue + "\n"; - } - if(attrs.containsKey(project.data.getAnnotationFileDefs().attrDesc)) - tooltip += attrs.get(project.data.getAnnotationFileDefs().attrDesc) + "\n"; - } - DataAnnotation.AnnotFeatureDef dbcdef = project.data.getRsvdAnnotFeatureDef(AnnotFeature.GENE); - geneEntry = new AnnotationEntry(geneName, dbcdef.source, dbcdef.feature, "", "", "", 1, largest, geneAttrs, tooltip, urlValue); - - long tend = System.nanoTime(); - long duration = (tend - tstart)/1000000; - System.out.println("Get gene '" + gene + "' annotation, largest: " + largest + ", time: " + duration + " ms"); - } - protected void getRSAnnotationData(String rsid, ArrayList lines, ArrayList alst) { - // override - } - - // should we change starting number to 1 (need to adjust first interval width)?!!! - protected void drawRuler(GraphicsContext gc, double x, double y, double rgnWidth, double rgnHeight, - double ppb, double strpos, double endpos, double dspOffset, boolean incflg) { - double range = endpos - strpos + 1; - double intervalBases = 1; - while(range/(intervalBases * 10) > 1) - intervalBases *= 10; - int count = (int) (range / intervalBases); - if((range % intervalBases) > 0) - count++; - if(count < 5 || count > 12) { - int idx = 0; - double ib = intervalBases; - double[] factors = {2,4,5,10}; - if(count < 5) { - //System.out.println("Small count: " + count + ", intBases: " + intervalBases); - while(count < 5 && idx < factors.length) { - ib = intervalBases / factors[idx++]; - count = (int) (range / ib); - if((range % ib) > 0) - count++; - } - intervalBases = ib; - } - else { - //System.out.println("Large count: " + count + ", inBases: " + intervalBases); - while(count > 10 && idx < factors.length) { - ib = intervalBases * factors[idx++]; - count = (int) (range / ib); - if((range % ib) > 0) - count++; - } - intervalBases = ib; - } - } - int height = 7; - double interval = intervalBases * ppb; - double xoffset = 0; - if((strpos % intervalBases) > 1) { - xoffset = (intervalBases - (strpos % intervalBases))/intervalBases * interval; - count -= 1; - } - - // draw main horizontal line and large unit ticks - gc.setFont(defaultFont); - gc.setStroke(Color.GRAY); - gc.setFill(Color.GRAY); - gc.setLineWidth(1.0); - gc.strokeLine(x, y, x+ rgnWidth, y); - gc.setTextAlign(TextAlignment.CENTER); - String label; - for(int i = 0; i < count; i++) { - gc.setLineWidth(0.5); - gc.setStroke(Color.valueOf("#D0D0D0")); - gc.strokeLine(adjustX(i * interval + x + xoffset), y + 1, i * interval + x + xoffset, y + rgnHeight - 5); - gc.setLineWidth(1.0); - gc.setStroke(Color.GRAY); - double xc = adjustX(i * interval + x + xoffset); - gc.strokeLine(xc, y + 1, xc, y + height - 1); - if(incflg) - label = getRegionXLabel(((Math.floor((strpos + i * intervalBases)/intervalBases) + (xoffset == 0? 0 : 1)) * intervalBases) + dspOffset); - else - label = getRegionXLabel(dspOffset - ((Math.floor((strpos + i * intervalBases)/intervalBases) + (xoffset == 0? 0 : 1)) * intervalBases)); - gc.fillText(label, i * interval + x + xoffset, y - 5); - } - - int subCount = 0; - int cmpval = -1; - double subInterval = 1; - double subIntervalBases = intervalBases; - if(interval > 100) { - cmpval = 5; - subCount = 10; - subInterval = interval / subCount; - subIntervalBases = intervalBases / subCount; - } - else if(interval > 50) { - cmpval = -1; - subCount = 5; - subInterval = interval / subCount; - subIntervalBases = intervalBases / subCount; - } - else if(interval > 10) { - cmpval = -1; - subCount = 2; - subInterval = interval / subCount; - subIntervalBases = intervalBases / subCount; - } - double xadjusted = x; - double yoffset = 5; - if(xoffset != 0) { - xadjusted += xoffset - interval; - count += 1; - } - for(int i = 0; i < count; i++) { - for(int j = 0; j < subCount; j++) { - if(j > 0) { - if((i == 0 && (j * subIntervalBases) < strpos) || - (i == (count - 1) && (i * intervalBases + j * subIntervalBases) > endpos)) { - //System.out.println("Skipping " + (i * intervalBases + j * subIntervalBases)); - continue; - } - gc.setLineWidth(0.25); - gc.setStroke(Color.valueOf("#E0E0E0")); - gc.strokeLine(i * interval + j * subInterval + xadjusted, y + yoffset, i * interval + j * subInterval + xadjusted, y + rgnHeight - yoffset); - gc.setLineWidth(1.0); - gc.setStroke(Color.GRAY); - double xc = adjustX(i * interval + j * subInterval + xadjusted); - if(j == cmpval) { - gc.strokeLine(xc, y + height - yoffset, xc, y + height); - } - else - gc.strokeLine(xc, y + yoffset, xc, y + height - yoffset); - } - } - } - } - protected void displayExons(String trans, GraphicsContext gc, double xoffset, double leftPadding, double ymain, double ppb, - boolean negStrand, ArrayList genoexonsList, - ArrayList tgexonsList, ArrayList tgcdsList, - ArrayList genoSpliceJuncList, ArrayList spliceJuncList, - ArrayList cdsList, - AnnotationEntry seqEntry, AnnotationEntry align5utr, AnnotationEntry align3utr, boolean nmd) { - // determine starting and ending exon positions for transcript - // and draw dashed line for full length - Collections.sort(tgexonsList); - Collections.sort(genoexonsList); - int min = 0; - int max = 0; - for(SeqAlign.Position ptg : tgexonsList) { - if(ptg.start < min || min == 0) - min = ptg.start; - if(ptg.end > max) - max = ptg.end; - } - gc.setLineWidth(0.25); - double x = xoffset + leftPadding + seqAlign.getXlatedPos(min) * ppb; - x = adjustX(x); - double ddw = seqAlign.getXlatedPos(max) - seqAlign.getXlatedPos(min); - symbols.drawDashedLine(gc, x, ymain, x + (ddw * ppb), defaultColor); - gc.setLineWidth(1.0); - - //System.out.println("DSPEXONS " + seqAlign.getXlatedPos(min) + ".." + seqAlign.getXlatedPos(max) + " --------------------------------"); - - // add aligned position to transcript tooltip - double ttstr = seqAlign.getAlignedPos(seqEntry.strpos, tgexonsList); - double ttend = seqAlign.getAlignedPos(seqEntry.endpos, tgexonsList); - String fmtpos = String.format("%s%s", NumberFormat.getInstance().format(ttstr), - (ttstr == ttend)? "" : String.format(" - %s", NumberFormat.getInstance().format(ttend))); - seqEntry.tooltipAligned = String.format("\nAligned: %s", fmtpos); - //System.out.println(String.format("\nTrans Aligned: %s", fmtpos)); - - // take into account gaps and alignment to get actual utr and cds segments to display - ArrayList utr5List = new ArrayList<>(); - if(align5utr != null) - utr5List = seqAlign.getUtrSegments(align5utr.strpos, align5utr.endpos, tgexonsList); - //System.out.println("dspexon xoff: " + xoffset + ", leftpad: " + leftPadding); -// for negstrand all values are not genomic - the relative values are already off here so we can not match the SJ below! - for(SeqAlign.SegmentDisplay sd : utr5List) - dspUTR(gc, xoffset + leftPadding, ymain, ppb, sd, true); - ArrayList utr3List = new ArrayList<>(); - if(align3utr != null) { - utr3List = seqAlign.getUtrSegments(align3utr.strpos, align3utr.endpos, tgexonsList); - //System.out.println("au3: " + align3utr.strpos + " to " + align3utr.endpos); - } - - for(SeqAlign.SegmentDisplay sd : utr3List) { - //System.out.println("dspu3: " + sd.start + ", to " + sd.end); - dspUTR(gc, xoffset + leftPadding, ymain, ppb, sd, false); - } - boolean cdsflg = !tgcdsList.isEmpty(); - ArrayList segList = seqAlign.getCdsSegments(cdsflg? tgcdsList : tgexonsList, tgexonsList); - for(SeqAlign.SegmentDisplay sd : segList) { - AnnotationEntry ae = new AnnotationEntry("", "", "", "", "", "", (int)seqAlign.getXlatedPos(sd.start), (int)seqAlign.getXlatedPos(sd.end), "", "", ""); - // only add if displaying CDS otherwise symbols will be displayed as if there was a thick CDS box... - if(cdsflg) - cdsList.add(ae); - //System.out.println("CDSLISTADD: " + sd.start + ".." + sd.end + ", " + ae.strpos + ".." + ae.endpos); - dspCDS(gc, xoffset + leftPadding, ymain, ppb, sd, cdsflg, nmd); - } - - // add exon tool tip - int idx = 0; - int genoidx = genoexonsList.size() - 1; - double height = 6; - double y = ymain; - int genostart, genoend; - String tooltip; - ArrayList lstExonsPos = new ArrayList<>(); - for(SeqAlign.Position ptg : tgexonsList) { - double pos = seqAlign.getXlatedPos(ptg.start); - x = adjustX(xoffset + leftPadding + pos * ppb); - if(negStrand) { - if(genoidx >= 0) { - genostart = genoexonsList.get(genoidx).end; - genoend = genoexonsList.get(genoidx).start; - } - else { - genostart = 0; - genoend = 0; - } - } - else { - genostart = ptg.start; - genoend = ptg.end; - } - lstExonsPos.add(new ExonPos(genostart, pos)); - tooltip = String.format("Exon %d\nGenome: %s - %s (%s bases)\nAligned: %s - %s", - (idx + 1), - NumberFormat.getInstance().format(genostart), NumberFormat.getInstance().format(genoend), - NumberFormat.getInstance().format(Math.abs(ptg.end - ptg.start) + 1), - NumberFormat.getInstance().format(seqAlign.getXlatedPos(ptg.start)), - NumberFormat.getInstance().format(seqAlign.getXlatedPos(ptg.end))); - AnnotationEntry blk = new AnnotationEntry("", "", "", "", "", "", 0, 0, "", "", ""); - tipsList.add(new ToolTipPoints(blk, x, adjustY(y - (height/2)), - (Math.abs(ptg.end - ptg.start) + 1) * ppb, adjustValue(6), tooltip, false)); - idx++; - genoidx--; - } - if(spliceJuncList != null && !spliceJuncList.isEmpty() && genoSpliceJuncList != null && !genoSpliceJuncList.isEmpty() && - spliceJuncList.size() == genoSpliceJuncList.size()) { - int num = 1; - Collections.sort(spliceJuncList); - Collections.sort(genoSpliceJuncList); - if(negStrand) - genoidx = genoSpliceJuncList.size() - 1; - else - genoidx = 0; - double apos[] = new double[2]; - double ax[] = new double[2]; - //System.out.println("ppb splice: " + ppb); - //System.out.println("splice xoff: " + xoffset + ", leftpad: " + leftPadding); - AnnotationFileDefs defs = project.data.getAnnotationFileDefs(); - for(SeqAlign.Position ptg : spliceJuncList) { - SpliceJuncData sjd = genoSpliceJuncList.get(genoidx); - apos[0] = seqAlign.getXlatedPos(ptg.start); - boolean found = false; - int sjgenostart = negStrand? sjd.donor : ptg.start; - for(ExonPos ep : lstExonsPos) { - if(sjgenostart == ep.genomic) { - apos[0] = ep.xlated; - found = true; - break; - } - } - if(!found) { - for(SeqAlign.SegmentDisplay sd : segList) { - if(ptg.start == sd.start) { - apos[0] = sd.x; - found = true; - break; - } - else if(ptg.start == sd.end) { - apos[0] = sd.x + sd.width; - found = true; - break; - } - } - if(!found) { - for(SeqAlign.SegmentDisplay sd : utr5List) { - if(ptg.start == sd.start) { - apos[0] = sd.x; - found = true; - break; - } - else if(ptg.start == sd.end) { - apos[0] = sd.x + sd.width; - found = true; - break; - } - } - if(!found) { - for(SeqAlign.SegmentDisplay sd : utr3List) { - if(ptg.start == sd.start) { - apos[0] = sd.x; - found = true; - break; - } - else if(ptg.start == sd.end) { - apos[0] = sd.x + sd.width; - found = true; - break; - } - } - } - } - } - ax[0] = adjustX(xoffset + leftPadding + apos[0] * ppb); - apos[1] = seqAlign.getXlatedPos(ptg.end); - int sjgenoend = negStrand? sjd.acceptor : ptg.end; - for(ExonPos ep : lstExonsPos) { - if(sjgenoend == ep.genomic) { - apos[1] = ep.xlated; - found = true; - break; - } - } - if(!found) { - for(SeqAlign.SegmentDisplay sd : segList) { - if(ptg.end == sd.start) { - apos[1] = sd.x; - found = true; - break; - } - else if(ptg.end == sd.end) { - apos[1] = sd.x + sd.width; - found = true; - break; - } - } - if(!found) { - for(SeqAlign.SegmentDisplay sd : utr5List) { - if(ptg.end == sd.start) { - apos[1] = sd.x; - found = true; - break; - } - else if(ptg.end == sd.end) { - apos[1] = sd.x + sd.width; - found = true; - break; - } - } - if(!found) { - for(SeqAlign.SegmentDisplay sd : utr3List) { - if(ptg.end == sd.start) { - apos[1] = sd.x; - found = true; - break; - } - else if(ptg.end == sd.end) { - apos[1] = sd.x + sd.width; - found = true; - break; - } - } - } - } - } - ax[1] = (xoffset + leftPadding + apos[1] * ppb); //adjustX - // depending on the zooming, the values in ax will differ by more - // even if next to each other - use apos which is not affected by resolution - //boolean combined = Math.abs(ax[1] - ax[0]) < 2; -// there is no way to tell the difference between an SJ that is across a 1 nt gap -// and an SJ that is continous not across a visual gap (alignment) since they are both 1 apart -// would need to flag gapped vs non-gapped somehow or just ignore it since it is rare and fairly insignificant - boolean combined = Math.abs(apos[1] - apos[0]) < 2; - if(combined) - ax[0] = ax[1]; - for(int i = 0; i < 2; i++) { - // display splice junction line - // Note: using the ID to determine if it is a novel junction (if it has the word "novel" in it) bad decision! - symbols.drawSpliceJunction(gc, ax[i], ymain, AnnotationSymbols.CDSblockHeight + 9, sjd.id.contains(defs.valSJ), (combined? 3 : i+1)); - // setup tooltip - if(negStrand) { - if(genoidx >= 0) { - genostart = genoSpliceJuncList.get(genoidx).pos.end; - genoend = genoSpliceJuncList.get(genoidx).pos.start; - } - else { - genostart = 0; - genoend = 0; - } - } - else { - genostart = ptg.start; - genoend = ptg.end; - } - int tipidx = i; - if(sjd.name.isEmpty()) - tooltip = String.format("Splice Junction %d\nID: %s", num, sjd.id); - else - tooltip = String.format("Splice Junction %d\nID: %s\nName: %s", num, sjd.id, sjd.name); - tooltip += String.format("\nGenome " + (i==0? "Donor" : "Acceptor") + ": %s\nAligned " + (i==0? "Donor" : "Acceptor") + ": %s", - NumberFormat.getInstance().format(i==0? (negStrand? (genostart-1) : (genostart+1)) : (negStrand? (genoend+1) : (genoend-1))), - NumberFormat.getInstance().format(apos[i])); - // if there is no significant separation, consolidate into just one symbol with tooltip for both donor/acceptor - if(combined && i == 0) { - tooltip += String.format("\nGenome Acceptor: %s\nAligned Acceptor: %s", - NumberFormat.getInstance().format(negStrand? (genoend+1) : (genoend-1)), - NumberFormat.getInstance().format(apos[1])); - i++; - } - AnnotationEntry blk = new AnnotationEntry("", "", "", "", "", "", 0, 0, "", "", ""); - tipsList.add(new ToolTipPoints(blk, ax[tipidx]-2.5, adjustY(ymain - ((AnnotationSymbols.CDSblockHeight+9+4)/2)), 5, (AnnotationSymbols.CDSblockHeight+6), tooltip, false)); - } - num++; - if(negStrand) - genoidx--; - else - genoidx++; - } - } - } - protected void dspUTR(GraphicsContext gc, double x, double y, double ppb, SeqAlign.SegmentDisplay sd, boolean utr5flg) { - String type = utr5flg? "5'UTR" : "3'UTR"; - x = adjustX(x + sd.x * ppb); - y = adjustY(y - (AnnotationSymbols.RNAblockHeight/2)); - symbols.drawRNAblock(gc, x, y, sd.width * ppb); - AnnotationEntry utr = new AnnotationEntry("", "", "", "", "", "", 0, 0, "", "", ""); - String fmtpos = String.format("%s%s", NumberFormat.getInstance().format(sd.xRelative), - String.format(" - %s", NumberFormat.getInstance().format(sd.xRelative+sd.width-1))); - tipsList.add(new ToolTipPoints(utr, x, y + 1, sd.width * ppb, adjustValue(AnnotationSymbols.RNAblockHeight), - String.format("%s\nPosition: %s", type, fmtpos), false)); - double ttstr = sd.x; - double ttend = sd.x+sd.width-1; - fmtpos = String.format("%s%s", NumberFormat.getInstance().format(ttstr), - (ttstr == ttend)? "" : String.format(" - %s", NumberFormat.getInstance().format(ttend))); - utr.tooltipAligned = String.format("\nAligned: %s", fmtpos); - } - // Note: Since we display the CDS in blocks the tooltip can be misleading in cases where the blocks are very close together. - // When you mouse over one part of the CDS you may think the tool-tip range shown is for the whole CDS since it looks like one block - // It won't be clear until you zoom-in real close, PB.1403.3 is an example - protected void dspCDS(GraphicsContext gc, double x, double y, double ppb, SeqAlign.SegmentDisplay sd, boolean cdsflg, boolean nmd) { - String type = cdsflg? "CDS" : "RNA"; - double height = cdsflg? AnnotationSymbols.CDSblockHeight : AnnotationSymbols.RNAblockHeight; - x = adjustX(x + sd.x * ppb); - y = adjustY(y - (height/2)); - if(cdsflg) - symbols.drawCDSblock(gc, x, y, sd.width * ppb, nmd); // add nullstring because is a param to color NMD CDS!!! - else - symbols.drawRNAblock(gc, x, y, sd.width * ppb); - AnnotationEntry blk = new AnnotationEntry("", "", "", "", "", "", 0, 0, "", "", ""); - String fmtpos = String.format("%s%s", NumberFormat.getInstance().format(sd.xRelative), - String.format(" - %s", NumberFormat.getInstance().format(sd.xRelative+sd.width-1))); - tipsList.add(new ToolTipPoints(blk, x, y + 1, sd.width * ppb, adjustValue(height), - String.format("%s\nPosition: %s", type, fmtpos), false)); - double ttstr = sd.x; - double ttend = sd.x+sd.width-1; - fmtpos = String.format("%s%s", NumberFormat.getInstance().format(ttstr), - (ttstr == ttend)? "" : String.format(" - %s", NumberFormat.getInstance().format(ttend))); - blk.tooltipAligned = String.format("\nAligned: %s", fmtpos); - } - // this does not take into account the 'ppb' so when the ppb is really low, it is possible to end up with stacked/hidden symbols - private boolean IsThereRoom(ArrayList seqList, AnnotationSymbols.SymbolDef symdef, - double str, double width, double strd, double widthd) { - boolean result = true; - double xs = strd; - double xe = strd + widthd; - for(UsedPoints up : seqList) { - if((xs >= up.xd && xs <= (up.xd + up.widthd)) || (xe >= up.xd && xe <= (up.xd + up.widthd)) || - (xs < up.xd && xe > (up.xd + up.widthd))) { - //System.out.println("No room: " + xs + ":" + xe); - result = false; - break; - } - } - return result; - } - public double adjustX(double x) { - if(scale != 1) - { - double i = x * scale; - i = Math.floor(i) + 0.5; - x = i / scale; - } - else - x = Math.floor(x) + 0.5; - return x; - } - public double adjustY(double y) { - if(scale != 1) - { - double i = y * scale; - i = Math.floor(i) + 0.5; - y = i / scale; - } - else - y = Math.floor(y) + 0.5; - return y; - } - public double adjustValue(double value) { - if(scale != 1) - return (Math.round(value * scale)/scale); - return value; - } - - public void addToolTipToList(AnnotationEntry entry, double x, double y, double width, double height, boolean setHandCursor) { - String fmtpos = String.format("%s%s", NumberFormat.getInstance().format(entry.strpos), - (entry.strpos == entry.endpos)? "" : String.format(" - %s", NumberFormat.getInstance().format(entry.endpos))); - tipsList.add(new ToolTipPoints(entry, x, y, width, height, - String.format("%s\nPosition: %s", entry.tooltip, fmtpos), setHandCursor)); - } - public void addToolTipToList(String tip, double x, double y, double width, double height, boolean setHandCursor) { - tipsList.add(new ToolTipPoints(null, x, y, width, height, tip, setHandCursor)); - } - static public String getRegionXLabel(double pos) { - double divisor = 1; - int[] factors = {1, 1000, 1000000, 1000000000}; - for(int idx = 0; idx < factors.length; idx++) { - divisor = factors[idx]; - if(pos/divisor < 1000) - break; - } - - String lbl; - String units = getUnits(divisor); - if(pos >= 1000000000) - lbl = String.format("%.7f", (pos/divisor)); - else if(pos >= 1000000) - lbl = String.format("%.4f", (pos/divisor)); - else - lbl = String.format("%.2f", (pos/divisor)); - while(lbl.endsWith("0")) - lbl = lbl.substring(0, lbl.length() - 1); - if(lbl.endsWith(".")) - lbl = lbl.substring(0, lbl.length() - 1); - return lbl + units; - } - static public String getUnits(double value) { - String units = ""; - if(value >= 1000000000) - units = "G"; - else if(value >= 1000000) - units = "M"; - else if(value >= 1000) - units = "K"; - return units; - } - - // - // Data Classes - // - // - protected class DrawArgs { - public Prefs prefs; - public int redrawCount; - public double hRegion; - public boolean singleColumn; - public DrawArgs(Prefs prefs, int redrawCount, double hRegion, boolean singleColumn) { - this.prefs = prefs; - this.redrawCount = redrawCount; - this.hRegion = hRegion; - this.singleColumn = singleColumn; - } - } - public class AnnotationEntry { - public String id; - public String source; - public AnnotationSymbols.SymbolAssignment symbol; - public String feature; - public String featureId; - public String caption; - public String strand; - public int strpos, endpos; - public int ostrpos, oendpos; - public double dsppos, dspstrpos, dspendpos; - public String attrs; // optional attributes in form of key1=value1;key2=value2 - public String parent; - public int offset; - public String tooltip; - public String tooltipAligned; - public String urlValue; - - public AnnotationEntry(String id, String source, String feature, String featureId, String caption, String strand, int strpos, int endpos, - String attrs, String tooltip, String urlValue) { - this.id = id; - this.source = source; - this.feature = feature; - this.featureId = featureId; - this.caption = caption; - if(strpos == 0 || endpos == 0 || feature.equals("") || project.data.isRsvdFeature(source, feature)) { - this.symbol = null; - } - else { - String subId = ""; - AnnotationFileDefs defs = project.data.getAnnotationFileDefs(); - if(defs.isDomain(source, feature)) - subId = caption; - this.symbol = symbols.getSymbolAssignment(source, feature, caption, subId); - } - this.strand = strand; - this.strpos = strpos; - this.ostrpos = strpos; - this.endpos = endpos; - this.oendpos = endpos; - this.dsppos = strpos; - this.dspstrpos = strpos; - this.dspendpos = endpos; - if(strpos != endpos) - this.dsppos = strpos + (endpos - strpos + 1)/2; - //this.algdsppos = this.dsppos; - this.attrs = attrs; - this.parent = ""; - this.offset = 0; - this.tooltip = tooltip; - this.urlValue = urlValue; - this.tooltipAligned = ""; - } - } - public class ProveanData implements Comparable { - public String trans; - public String id; - public String score; - public double pscore = 0; - public ProveanData(String trans, String attrsField) { - this.trans = trans; - this.id = "'"; - this.score = ""; - if(!attrsField.trim().isEmpty()) { - AnnotationFileDefs defs = project.data.getAnnotationFileDefs(); - HashMap attrs = DataAnnotation.getAttributes(attrsField); - if(attrs.containsKey(defs.attrPScore)) { - score = attrs.get(defs.attrPScore); - try { - if(score.equals(DataAnnotation.PROVEAN_EXACT)) - pscore = DataAnnotation.PEXACT_SCORE; - else - pscore = Double.parseDouble(score); - } - catch(Exception e) { System.out.println("Provean score processing exception: " + e.getMessage());} - //System.out.println("PS(" + trans + "): " + pscore); - } - if(attrs.containsKey(defs.attrId)) - id = attrs.get(defs.attrId); - } - } - @Override - public int compareTo(ProveanData pd) { - return ((pscore > pd.pscore)? 1 : (pscore < pd.pscore)? -1 : 0); - } - } - public class SpliceJuncData implements Comparable { - public SeqAlign.Position pos; - public int donor, acceptor; - public String id; - public String name; - public SpliceJuncData(boolean negStrand, SeqAlign.Position pos, String attrsField) { - this.pos = pos; - this.donor = negStrand? pos.end : pos.start; - this.acceptor = negStrand? pos.start : pos.end; - this.id = ""; - this.name = ""; - if(!attrsField.trim().isEmpty()) { - HashMap attrs = DataAnnotation.getAttributes(attrsField); - if(attrs.containsKey(project.data.getAnnotationFileDefs().attrId)) - id = attrs.get(project.data.getAnnotationFileDefs().attrId); - if(attrs.containsKey(project.data.getAnnotationFileDefs().attrName)) - name = attrs.get(project.data.getAnnotationFileDefs().attrName); - } - } - @Override - public int compareTo(SpliceJuncData sjd) { - return ((pos.start > sjd.pos.start)? 1 : (pos.start < sjd.pos.start)? -1 : 0); - } - } - public class ToolTipPoints { - public AnnotationEntry entry; - public double x; - public double y; - public double width; - public double height; - public Rectangle2D.Double rect; - public String tooltip; - public boolean setHandCursor; - public ToolTipPoints(AnnotationEntry entry, double x, double y, double width, double height, String tooltip, boolean setHandCursor) { - this.entry = entry; - this.x = x; - this.y = y; - this.width = width; - this.height = height; - this.rect = new Rectangle2D.Double(this.x, this.y, width, height); - this.tooltip = tooltip; - this.setHandCursor = setHandCursor; - } - } - public class UsedPoints { - public double x, xd; - public double width, widthd; - public UsedPoints(double x, double width, double xd, double widthd) { - this.x = x; - this.width = width; - this.xd = xd; - this.widthd = widthd; - } - } - public class ViewAnnotationEntry implements Comparable{ - public String id; - public int size; - ArrayList alst; - public ViewAnnotationEntry(String id, int size, ArrayList alst) { - this.id = id; - this.size = size; - this.alst = alst; - } - @Override - public int compareTo(ViewAnnotationEntry gta) { - int lastCmp = id.compareTo(gta.id); - if (id.substring(0,2).equals(gta.id.substring(0, 2))) - return ((size > gta.size)? 1 : (size < gta.size)? -1 : 0); - else - return (lastCmp != 0 ? lastCmp : ((size > gta.size)? 1 : (size < gta.size)? -1 : 0)); - } - } - public static class Prefs { - public boolean ruler; - public boolean details; - public double scale; // must be >= 1 and <= 2 - public double widthFactor; // must be >= 1 and <= 4 - public boolean provean; - public boolean alignment; - public boolean spliceJuncs; - public boolean structSubClass; - public boolean sortDescending; - public ViewAnnotation.SortBy sortBy; - public boolean showVaryingOnly; - public HashMap>> hmNotFeatureIDs; - public Prefs(boolean ruler, double scale, double widthFactor, boolean provean, boolean alignment, - boolean spliceJuncs, boolean structSubClass, boolean details, - boolean sortDescending, ViewAnnotation.SortBy sortBy) { - this.ruler = ruler; - this.scale = scale; - this.widthFactor = widthFactor; - this.provean = provean; - this.alignment = alignment; - this.spliceJuncs = spliceJuncs; - this.structSubClass = structSubClass; - this.details = details; - this.sortDescending = sortDescending; - this.sortBy = sortBy; - // annotation features filter - this.showVaryingOnly = false; - this.hmNotFeatureIDs = new HashMap<>(); - } - public boolean isNotFeatureID(String source, String feature, String id) { - boolean result = false; - if(hmNotFeatureIDs != null) { - if(hmNotFeatureIDs.containsKey(source)) { - HashMap> hmNotFeatures = hmNotFeatureIDs.get(source); - if(hmNotFeatures.isEmpty()) - result = true; - else { - if(hmNotFeatures.containsKey(feature)) { - HashMap hmNotIDs = hmNotFeatures.get(feature); - if(hmNotIDs.isEmpty()) - result = true; - else { - if(hmNotIDs.containsKey(id)) - result = true; - } - } - } - } - } - return result; - } - } - public class TranscriptSortEntry implements Comparable{ - public String id; - public double val; - public TranscriptSortEntry(double val, String id) { - this.id = id; - this.val = val; - } - @Override - public int compareTo(TranscriptSortEntry tse) { - int result = ((val > tse.val)? 1 : (val < tse.val)? -1 : 0); - if(result == 0) - result = id.compareTo(tse.id); - return result; - } - } - public class ExonPos { - public int genomic; - public double xlated; - public ExonPos(int genomic, double xlated) { - this.genomic = genomic; - this.xlated = xlated; - } - } -} diff --git a/ViewProtein.java b/ViewProtein.java index 7997145..5254b99 100644 --- a/ViewProtein.java +++ b/ViewProtein.java @@ -140,14 +140,7 @@ public void handleMouseClickAction(MouseEvent event) { } if(!url.isEmpty()) Tappas.getHost().showDocument(url); - - /* - switch(tipEntry.source) { - case "RefSeq": - url = "http://www.ncbi.nlm.nih.gov/protein/" + tipEntry.urlValue; - Tappas.getHost().showDocument(url); - break; - }*/ + } } @Override diff --git a/ViewTranscript.java b/ViewTranscript.java index 6da91be..29c3fbb 100644 --- a/ViewTranscript.java +++ b/ViewTranscript.java @@ -114,25 +114,6 @@ else if(id.startsWith("NM_") || id.startsWith("NR_") || id.startsWith("XM_") || if(!url.isEmpty()) Tappas.getHost().showDocument(url); - /* - switch(tipEntry.source) { - /* don't rely on db/cat names!!! - case "RefSeq": - if(tipEntry.type.equals("gene")) - url = "http://www.ncbi.nlm.nih.gov/gene/" + tipEntry.urlValue; - else - url = "http://www.ncbi.nlm.nih.gov/refseq/?term=" + tipEntry.urlValue; - Tappas.getHost().showDocument(url); - break; - case "UTRdb": - url = "http://utrsite.ba.itb.cnr.it/index.php/UTRSite%20signal/Signal/action/view/frmUTRSiteID/" + tipEntry.urlValue; - Tappas.getHost().showDocument(url); - break; - case "RptMasker": - url = "http://www.repeatmasker.org/cgi-bin/ViewRepeat?id=" + tipEntry.urlValue; - Tappas.getHost().showDocument(url); - break;*/ - //} } } @Override diff --git a/ViewTranscript_copia.java.txt b/ViewTranscript_copia.java.txt deleted file mode 100644 index 60f7419..0000000 --- a/ViewTranscript_copia.java.txt +++ /dev/null @@ -1,784 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ - -package tappas; - -import javafx.scene.canvas.Canvas; -import javafx.scene.canvas.GraphicsContext; -import javafx.scene.control.Alert; -import javafx.scene.control.ScrollPane; -import javafx.scene.input.MouseButton; -import javafx.scene.input.MouseEvent; -import javafx.scene.paint.Color; -import javafx.scene.text.Font; -import javafx.scene.text.TextAlignment; -import tappas.DataAnnotation.AnnotFeature; - -import java.awt.geom.Point2D; -import java.awt.geom.Rectangle2D; -import java.text.NumberFormat; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -import static tappas.DataAnnotation.STRUCTURAL_SOURCE; - - -/** - * - * @author Hector del Risco - hdelrisco@ufl.edu & Pedro Salguero - psalguero@cipf.es - */ - -// add a sort menu selection - by trans len, trans name alpha, cds len, 5utr len, 3utr len? -// add a show - coding/noncoding, expressed, exp filtered, select specific ones, all (annotated) - display showing... -// add separator to option menu - have single menu for trans/protein? - - -public class ViewTranscript extends ViewAnnotation { - public ViewTranscript(Project project) { - super(project); - } - - public List getTranscriptDisplayOrder() { - return transcriptDisplayOrder; - } - public String getGeneTitle() { - return geneEntry.id; - } - public AnnotationEntry getGeneEntry() { - return geneEntry; - } - - // Initialization - @Override - public boolean initialize(SubTabBase subTabBase, Canvas canvasViewer, ScrollPane canvasScrollPane, String filterCaption) { - return super.initialize(subTabBase, canvasViewer, canvasScrollPane, filterCaption); - } - - @Override - public void handleMouseClickAction(MouseEvent event) { - if(event.getClickCount() == 2) { - HashMap hm = new HashMap<>(); - if(app.ctlr.fxdc.isShiftKeyDown()) - hm.put("zoomOut", TabGeneDataViz.Views.TRANS); - else - hm.put("zoomIn", TabGeneDataViz.Views.TRANS); - subTabBase.processRequest(hm); - } - if(tipEntry != null && event.getButton() == MouseButton.PRIMARY) { - String url = ""; - AnnotFeature dbcatid = project.data.getRsvdAnnotFeature(tipEntry.source, tipEntry.feature); - String species = project.data.getGenus() + "_" + project.data.getSpecies(); - DataApp.RefType rt = project.data.getRefType(); - if(species.equals("Homo_sapiens") || species.equals("Mus_musculus")) { - switch(dbcatid) { - case GENE: - if(rt.equals(DataApp.RefType.Ensembl)) - url = "http://www.ensembl.org/" + species + "/Gene/Summary?g=" + tipEntry.id; - else { //if(rt.equals(DataApp.RefType.Demo)) { // chg to MMDemo to allow other demos?! - String id = app.data.getNCBIGeneId(species, tipEntry.id); - if(!id.isEmpty()) - url = "https://www.ncbi.nlm.nih.gov/gene/" + id; - else - app.ctls.alertInformation("Gene Online Reference", "Unable to determine what online references to use for this gene."); - } - break; - case TRANSCRIPT: - if(rt.equals(DataApp.RefType.Ensembl)) - url = "http://www.ensembl.org/" + species + "/Transcript/Summary?t=" + tipEntry.id; - else { //if(rt.equals(DataApp.RefType.Demo)) { // chg to MMDemo to allow other demos?! - // our demo uses the PacBio transcript as the Id - String id = tipEntry.id; - if(rt.equals(DataApp.RefType.Demo)) - id = tipEntry.featureId; - - if(id.isEmpty()) - app.ctls.alertInformation("Transcript Online Reference", "There are no online references for this transcript."); - else { - if(id.startsWith("ENSMUST")) - url = "http://www.ensembl.org/" + species + "/Gene/Summary?g=" + id; - else if(id.startsWith("NM_") || id.startsWith("NR_") || id.startsWith("XM_") || id.startsWith("XR_")) - url = "https://www.ncbi.nlm.nih.gov/nuccore/" + id; - else - app.ctls.alertInformation("Transcript Online Reference", "Unable to determine what online references to use for this transcript."); - } - } - break; - - // Note: proteins are handled in the ViewProtein class - } - } - if(!url.isEmpty()) - Tappas.getHost().showDocument(url); - - /* - switch(tipEntry.source) { - /* don't rely on db/cat names!!! - case "RefSeq": - if(tipEntry.type.equals("gene")) - url = "http://www.ncbi.nlm.nih.gov/gene/" + tipEntry.urlValue; - else - url = "http://www.ncbi.nlm.nih.gov/refseq/?term=" + tipEntry.urlValue; - Tappas.getHost().showDocument(url); - break; - case "UTRdb": - url = "http://utrsite.ba.itb.cnr.it/index.php/UTRSite%20signal/Signal/action/view/frmUTRSiteID/" + tipEntry.urlValue; - Tappas.getHost().showDocument(url); - break; - case "RptMasker": - url = "http://www.repeatmasker.org/cgi-bin/ViewRepeat?id=" + tipEntry.urlValue; - Tappas.getHost().showDocument(url); - break;*/ - //} - } - } - @Override - protected void draw(GraphicsContext gc, DrawArgs args) { - ArrayList cdsList = new ArrayList<>(); - //ArrayList emptyList = new ArrayList<>(); - ArrayList genoexonsList = new ArrayList<>(); - ArrayList genoSpliceJuncList = new ArrayList<>(); - ArrayList spliceJuncList = new ArrayList<>(); - ArrayList tgexonsList = new ArrayList<>(); - ArrayList tgcdsList = new ArrayList<>(); - AnnotationEntry align5utr = null; - AnnotationEntry align3utr = null; - AnnotationEntry seqEntry = null; - - //System.out.println("draw at " + args.prefs.scale + ", " + args.redrawCount + ", align: " + args.prefs.alignment); - gc.setFill(Color.valueOf("white")); - gc.fillRect(0, 0, canvas.getWidth(), canvas.getHeight()); - double opacity = limitExceeded? 0.10 : 1.0; - gc.setFill(Color.web(limitExceeded? "darkorange" : ((args.prefs.hmNotFeatureIDs.isEmpty() && !args.prefs.showVaryingOnly)? "white" : "#FFFFF0"), opacity)); - if(annotationList.isEmpty() || geneEntry == null) { - double cwo = canvas.getWidth(); - double cyo = canvas.getHeight(); - canvas.setWidth(canvas.getWidth() * scale); - gc.fillRect(0, 0, canvas.getWidth(), canvas.getHeight()); - gc.setGlobalAlpha(0.75); - gc.setFill(Color.LIGHTGRAY); - gc.setTextAlign(TextAlignment.CENTER); - gc.fillText("No Transcript Information Available", cwo/2, cyo/scale/2); - gc.setGlobalAlpha(1.0); - return; - } - gc.fillRect(0, 0, canvas.getWidth(), canvas.getHeight()); - - // note that the first time this function is called, redrawCount = 1, - // the canvas width has been set to ((canvasPane.getWidth() - 2) / scale) - // this allows the proper expansion of the width when scaled - // otherwise you always end up having (width * scale) and horizontal scroll bar - double ch = canvas.getHeight(); - double chs = ch / scale; - double cw = canvas.getWidth(); - double cws = cw / scale; - if(args.redrawCount > 1) { - ch = chs; - cw = cws; - } - - // initially allow for one level of symbols on top and one on bottom - // if there is no room, add levels on bottom - ArrayList symbolsList = new ArrayList<>(); - ArrayList> seqList = new ArrayList<>(); - seqList.add(new ArrayList<>()); // top, 1st level - seqList.add(new ArrayList<>()); // bottom, 1st level - - // display title - tipsList.clear(); - double ytitle = 20; - double ysubtitle = 40; - gc.setFont(titleFont); - gc.setFill(titleColor); - gc.setTextAlign(TextAlignment.CENTER); - // set gene display title - name plus description if available - String title = geneEntry.id; - if(!geneEntry.attrs.isEmpty()) { - HashMap attrs = DataAnnotation.getAttributes(geneEntry.attrs); - if(attrs.containsKey(project.data.getAnnotationFileDefs().attrDesc)) { - String desc = attrs.get(project.data.getAnnotationFileDefs().attrDesc); - if(!desc.isEmpty()) - title += " - " + desc.substring(0,1).toUpperCase() + desc.substring(1); - if(title.length() > maxTitleLength) - title = title.substring(0, maxTitleLength) + "..."; - } - } - gc.fillText(title, (cw/2), ytitle); - double width = com.sun.javafx.tk.Toolkit.getToolkit().getFontLoader().computeStringWidth(title, gc.getFont()); - tipsList.add(new ToolTipPoints(geneEntry, (cw/2 - width/2), ytitle - 10, width, 16, - String.format("%s\n", geneEntry.tooltip), true)); - - // display subtitle - gc.setFont(subFont); - gc.setFill(subColor); - gc.fillText("Transcripts View - " + (args.prefs.alignment? "Aligned" : "Unaligned"), (cw/2), ysubtitle); - //gc.fillText("Transcripts View - " + (args.prefs.alignment? "Aligned" : "Unaligned") + (filterCaption.isEmpty()? "" : (" for " + filterCaption)), (cw/2), ysubtitle); - - double yoffset = ysubtitle + 20; - if(args.prefs.ruler) - yoffset += 30; - double xoffset = 12; - double rightPadding = 60; - double leftPadding = 60; - double htop = 20; - double hbottom = 17; - double seqHeight = 40; - double yRegion = yoffset - 20; - double ymain = yoffset + htop; - double wRegion = (cw - 2 * xoffset - rightPadding - leftPadding); - double bases = geneEntry.endpos - geneEntry.strpos + 1; - if(bases <= 0) - bases = 1; - SeqAlign.Position cdspos = new SeqAlign.Position(0,0); - SeqAlign.Position utr5pos = new SeqAlign.Position(0,0); - SeqAlign.Position utr3pos = new SeqAlign.Position(0,0); - double dspsizeX = 0; - double dspsizeY = 0; - double ppb = wRegion / bases; - zoomPPB = ppb; - //System.out.println("Bases: " + bases + ", ppb: " + ppb); - - double rw = AnnotationSymbols.CDSblockHeight; - double rws = adjustValue(rw); - String trans = ""; - String fmtpos, str1; - double x, y, ttstr, ttend; - boolean dspExons = false; - boolean negStrand = false; - double wExpLevel = leftPadding - 10; - double expLevelPpb = (maxExpLevel == 0)? 0 : wExpLevel / maxExpLevel; - boolean genomic = false; - boolean intronLegend = false; - boolean inexLegend = false; - - //System.out.println("wRgn: " + wRegion + ", bases: " + bases + ", ppb: " + ppb); - if(args.prefs.ruler) - drawRuler(gc, xoffset + leftPadding, yoffset - 20, wRegion, args.hRegion, ppb, geneEntry.strpos, geneEntry.endpos, 0, true); - - // process all gene annotations - //int fkcnt = 0; - //if(args.prefs.alignment) - // System.out.println("Alignment ON **************************"); - int transCount = 0; - boolean endloop = false; - - // Create a list with NMD transcripts for colored with other color - String[] gene_transcripts = geneIsoformsExpression.keySet().toArray(new String[geneIsoformsExpression.size()]); - ArrayList transNMD = new ArrayList(); - for(int i=0;i 0) - transNMD.add(gene_transcripts[i]); - } - - for(AnnotationEntry entry : annotationList) { - if(entry.source.equals(STRUCTURAL_SOURCE)) - continue; - - if(entry.source.equals("PAR-clip")) - System.out.println("Estamos donde toca"); - - - AnnotFeature dbcatid = project.data.getRsvdAnnotFeature(entry.source, entry.feature); - if(seqEntry == null && dbcatid != AnnotFeature.TRANSCRIPT) { - logger.logError("Gene transcript annotations must have 'transcript' as first entry. Entry: " + entry.feature); - return; - } - gc.setStroke(defaultColor); - gc.setFill(defaultColor); - gc.setFont(defaultFont); - String cat = project.data.getTransAlignmentCategory(entry.id); - boolean nmd = false; - - //used in CDS switch but now the code doesn't enter - if(transNMD.contains(entry.id)) - nmd = true; - - //System.out.println("Trans ALoop Entry: " + entry.type); - switch(dbcatid) { - case TRANSCRIPT: - if(transCount >= TabGeneDataViz.MAX_GENE_TRANS && !limitExceeded) { - if(args.redrawCount == 1) - Utils.showAlertLater(Alert.AlertType.WARNING, "Gene Transcripts Limit Exceeded", "The selected gene contains too many isoforms,\nshowing only the first " + TabGeneDataViz.MAX_GENE_TRANS + "."); - limitExceeded = true; - endloop = true; - break; - } - genomic = false; - if(seqEntry == null) { - gc.setFont(smallFont); - x = xoffset + leftPadding - 5; - y = yoffset - 10; - gc.setFill(Color.PLUM); - gc.setTextAlign(TextAlignment.RIGHT); - gc.fillText("5' UTR", x, y); - x = cw - xoffset - rightPadding + 5; - gc.setTextAlign(TextAlignment.LEFT); - gc.fillText("3' UTR", x, y); - //System.out.println("Starting transcript: " + entry.id); - gc.setFont(defaultFont); - } - else { - cdsList.clear(); - genoexonsList.clear(); - genoSpliceJuncList.clear(); - spliceJuncList.clear(); - tgexonsList.clear(); - tgcdsList.clear(); - dspExons = false; - align5utr = null; - align3utr = null; - cdspos.start = 0; cdspos.end = 0; - utr5pos.start = 0; utr5pos.end = 0; - utr3pos.start = 0; utr3pos.end = 0; - - // clear all used points from last sequence - int cnt = seqList.size(); - for(int i = seqList.size() - 1; i >= 0; i--) - { - if(i < 2) - seqList.get(i).clear(); - else - seqList.remove(i); - } - // adjust starting 'y' position, taking into account additional levels (if any) - ymain += adjustY(seqHeight + (cnt - 2) * levelOffset); - } - seqEntry = entry; - negStrand = entry.strand.equals("-"); - - // display transcript ID - gc.setFill(Color.MAROON); - gc.setTextAlign(TextAlignment.LEFT); - String rsid = ""; - HashMap attrs = DataAnnotation.getAttributes(entry.attrs); - if(attrs.containsKey(project.data.getAnnotationFileDefs().attrId)) { - String tid = attrs.get(project.data.getAnnotationFileDefs().attrId); - if(!tid.equals(entry.id)) - rsid = " " + tid; - } - trans = entry.id; - String dsptransid = entry.id + " (" + entry.strand + ")" + rsid; - gc.fillText(dsptransid, xoffset, ymain - 4); - double wtxt = com.sun.javafx.tk.Toolkit.getToolkit().getFontLoader().computeStringWidth(dsptransid, gc.getFont()); -// if(!cat.isEmpty()) { -// String dspid = ""; -// if(args.prefs.structSubClass) { -// if(attrs.containsKey(project.data.getAnnotationFileDefs().attrSecClass)) -// dspid = " (" + attrs.get(project.data.getAnnotationFileDefs().attrSecClass).replaceAll("[,]", ", ") + ")"; -// } -// gc.setFill(Color.STEELBLUE); -// gc.fillText(cat + dspid, xoffset + wtxt + 10, ymain - 4); -// } - - // display expression levels if not time series and available - if(project.data.isCaseControlExpType() && geneIsoformsExpression.containsKey(seqEntry.id)) { - Font f = gc.getFont(); - DataProject.TransExpLevels el = geneIsoformsExpression.get(seqEntry.id); - //System.out.println("maxEL: " + maxExpLevel + ", wEL: " + wExpLevel + ", ppb: " + expLevelPpb + "x1: " + el.X1_mean + ", x2: " + el.X2_mean); - double xc = xoffset; - double fy = adjustY(hbottom + ymain - (AnnotationSymbols.RNAblockHeight/2) - 2); - gc.setFill(Color.ORANGE); - double wexp1 = adjustX(el.X1_mean * expLevelPpb); - gc.fillRect(xc + 0.5, fy - 2, wexp1, 4); - double wexp2 = adjustX(el.X2_mean * expLevelPpb); - gc.setFill(Color.ORANGERED); - gc.fillRect(xc + 0.5, fy + 3, wexp2, 4); - gc.setFill(Color.BLACK); - gc.fillRect(xc, fy - 4, 0.5, 12); - gc.fillRect(xc, fy + 8.5, wExpLevel, 0.5); - gc.setTextAlign(TextAlignment.RIGHT); - gc.setFont(new Font(8)); // some font sizes will create a gap between digits, e.g. 7 - gc.setFill(Color.GRAY); - gc.fillText(NumberFormat.getInstance().format(maxExpLevel), xc + wExpLevel, fy + 17); - String dea = ""; - if(project.data.analysis.hasDEAData(DataApp.DataType.TRANS)) { - String der = "(not included in analysis)"; - if(geneIsoformsDEResults.containsKey(seqEntry.id)) { - der = geneIsoformsDEResults.get(seqEntry.id)? "DE" : "Not DE"; - gc.setTextAlign(TextAlignment.LEFT); - gc.setFont(new Font(8)); - gc.setFill(Color.CHOCOLATE); - gc.fillText(der, xc + 1, fy-5); - } - dea = "DEA Result: " + der + "\n"; - } - double el1 = Double.parseDouble(String.format("%.2f", ((double)Math.round(el.X1_mean*100)/100.0))); - double el2 = Double.parseDouble(String.format("%.2f", ((double)Math.round(el.X2_mean*100)/100.0))); - String[] names = project.data.getExpTypeGroupNames(); - String ttip = String.format("Isoform Expression Level (normalized mean)\n" + dea + - names[0] + " ExpLevel: %s (top line)\n" + - names[1] + " ExpLevel: %s (bottom line)", - NumberFormat.getInstance().format(el1), NumberFormat.getInstance().format(el2)); - addToolTipToList(ttip, xc, fy - 10, wExpLevel, 25, false); - gc.setTextAlign(TextAlignment.LEFT); - gc.setFont(f); - } - - width = com.sun.javafx.tk.Toolkit.getToolkit().getFontLoader().computeStringWidth(dsptransid, gc.getFont()); - addToolTipToList(entry, xoffset, ymain - 12, width, 10, true); - ymain += hbottom; - ymain = adjustY(ymain); - - x = xoffset + leftPadding + (entry.strpos - geneEntry.strpos) * ppb; - gc.setFill(defaultColor); - gc.setStroke(defaultColor); - x = adjustX(x); - int dspstr = entry.strpos; - int dspend = entry.endpos; - if(args.prefs.alignment) { - dspstr = geneEntry.strpos; - dspend = geneEntry.endpos; - } - double dw = dspend - dspstr + 1; - if(dw > 1) { - if(!args.prefs.alignment) { - y = adjustY(ymain - (AnnotationSymbols.RNAblockHeight/2)); - symbols.drawRNAblock(gc, x, y, (dw * ppb)); - gc.setFill(Color.DARKGRAY); - x = xoffset + leftPadding + 5 + dw * ppb; - str1 = NumberFormat.getInstance().format(entry.endpos-entry.strpos+1); - gc.fillText(str1 + "nt", x, ymain + 4); - } - else { - dspsizeX = xoffset + leftPadding + 5 + dw * ppb; - dspsizeY = ymain + 4; - } - } - transCount++; - break; - case GENOMIC: - // genomic section is always the last section within a transcript - genomic = true; - break; - case EXON: - genoexonsList.add(new SeqAlign.Position(entry.strpos, entry.endpos)); - //System.out.println("added genome pos exon: " + entry.strpos + " to " + entry.endpos); - break; - case SPLICEJUNCTION: - if(args.prefs.alignment && args.prefs.spliceJuncs) { - // annotation file positions junctions at the start of the intron - // move to the exon part for display purposes - adjust based on strand - int start = negStrand? entry.strpos - 1 : entry.strpos - 1; - int end = negStrand? entry.endpos + 1 : entry.endpos + 1; - genoSpliceJuncList.add(new SpliceJuncData(negStrand, new SeqAlign.Position(start, end), entry.attrs)); - //System.out.println("added genome pos SJ: " + entry.strpos + " to " + entry.endpos); - } - break; - case CDS: - //now the code not enter here!!! - cdspos = new SeqAlign.Position(entry.strpos, entry.endpos); - if(!args.prefs.alignment) { - cdsList.add(entry); - x = adjustX(xoffset + leftPadding + (entry.strpos - geneEntry.strpos) * ppb); - y = adjustY(ymain - (rw/2)); - //gc.setGlobalAlpha(0.9); - symbols.drawCDSblock(gc, x, y, (entry.endpos - entry.strpos + 1) * ppb, nmd); - addToolTipToList(entry, x, y, (entry.endpos - entry.strpos + 1) * ppb, rws, false); - } - break; - case GENE: - break; - default: - switch(entry.feature) { - case DataAnnotation.INTCAT_EXON: - if(args.prefs.alignment) { - dspExons = true; - tgexonsList.add(new SeqAlign.Position(entry.strpos, entry.endpos)); - //System.out.println("added exon: " + entry.strpos + " to " + entry.endpos); - } - break; - case DataAnnotation.INTCAT_SPLICEJUNCTION: - if(args.prefs.alignment && args.prefs.spliceJuncs) { - // annotation file positions junctions at the start of the intron - // move to the exon part for display purposes - adjust based on strand - //int start = negStrand? entry.strpos + 1 : entry.strpos - 1; - //int end = negStrand? entry.endpos - 1 : entry.endpos + 1; - //spliceJuncList.add(new SeqAlign.Position(start, end)); - spliceJuncList.add(new SeqAlign.Position(entry.strpos, entry.endpos)); - //System.out.println("added aligned pos SJ: " + entry.strpos + " to " + entry.endpos); - } - break; - case DataAnnotation.INTCAT_CDS: - if(args.prefs.alignment) { - tgcdsList.add(new SeqAlign.Position(entry.strpos, entry.endpos)); - } - break; - case DataAnnotation.INTCAT_NODATA: - gc.setFill(Color.DARKGREY); - x = xoffset + leftPadding; - gc.fillText("No alignment data available...", x, ymain + 4); - break; - case DataAnnotation.INTCAT_5UTR: - align5utr = entry; - utr5pos = new SeqAlign.Position(entry.strpos, entry.endpos); - //System.out.println("5utr: " + entry.strpos + ".." + entry.endpos); - break; - case DataAnnotation.INTCAT_3UTR: - align3utr = entry; - utr3pos = new SeqAlign.Position(entry.strpos, entry.endpos); - //System.out.println("3utr: " + entry.strpos + ".." + entry.endpos); - break; - default: - //System.out.println("Entry type: " + entry.type); - if(!project.data.isInternalFeature(entry.source, entry.feature) || entry.feature.equals(DataAnnotation.INTCAT_FLUSHDATA)) { - double dsppos = entry.strpos + Math.abs((entry.endpos - entry.strpos + 1)/2); - if(args.prefs.alignment) { - if(dspExons){ - //do it once for each nmd - if(transNMD.contains(trans)){ - transNMD.remove(trans); - nmd=true; - } - dspExons = false; - double exsize = SeqAlign.getTotalExonsSize(tgexonsList); - gc.setFill(Color.DARKGRAY); - str1 = NumberFormat.getInstance().format(exsize); - gc.fillText(str1 + "nt", dspsizeX, dspsizeY); - displayExons(trans, gc, xoffset, leftPadding, ymain, ppb, negStrand, genoexonsList, - tgexonsList, tgcdsList, genoSpliceJuncList, spliceJuncList, cdsList, seqEntry, align5utr, align3utr, nmd); - } - // check if we just wanted to make sure exon data was flushed - if(entry.feature.equals(DataAnnotation.INTCAT_FLUSHDATA)) - break; - - if(!genomic) { // temp? - entry.dspstrpos = seqAlign.getAlignedPos(entry.strpos, tgexonsList); - entry.dspendpos = seqAlign.getAlignedPos(entry.endpos, tgexonsList); - fmtpos = String.format("%s%s", NumberFormat.getInstance().format(entry.dspstrpos), - (entry.dspstrpos == entry.dspendpos)? "" : String.format(" - %s", NumberFormat.getInstance().format(entry.dspendpos))); - entry.tooltipAligned = String.format("\nAligned: %s", fmtpos); - } - } - else { - entry.dspstrpos = entry.strpos; - entry.dspendpos = entry.endpos; - } - entry.dsppos = entry.dspstrpos + (entry.dspendpos - entry.dspstrpos + 1)/2; - - // check for genomic display - need to handle differently based on whether it is contained - // in a region that is being displayed or not - SeqAlign.WithinRegion within = SeqAlign.WithinRegion.YES; - if(genomic) { - SeqAlign.Position chkpos = new SeqAlign.Position(entry.strpos, entry.endpos); - within = SeqAlign.isWithinExonsRegion(chkpos, genoexonsList); -// is this right? - - if(args.prefs.alignment) { - entry.dsppos = seqAlign.getGenomicXlatedPos(dsppos, negStrand); - entry.dspstrpos = seqAlign.getGenomicXlatedPos(entry.strpos, negStrand); - entry.dspendpos = seqAlign.getGenomicXlatedPos(entry.endpos, negStrand); - } - else { - entry.dsppos = SeqAlign.getGenomicXlatedPos(dsppos, negStrand, genoexonsList); - entry.dspstrpos = SeqAlign.getGenomicXlatedPos(entry.strpos, negStrand, genoexonsList); - entry.dspendpos = SeqAlign.getGenomicXlatedPos(entry.endpos, negStrand, genoexonsList); - } - } - if(within.equals( SeqAlign.WithinRegion.NO)) - intronLegend = true; - else if(within.equals( SeqAlign.WithinRegion.PARTIALLY)) - inexLegend = true; - addFeatureID(entry); - if(isDisplayableFeatureId(entry, args.prefs)) - drawTrackSymbol(entry, geneEntry, seqEntry, tgexonsList, cdsList, seqList, gc, xoffset + leftPadding, ymain, ppb, negStrand, genomic, args.prefs.alignment, within); - if(symbolsList.indexOf(entry.feature) == -1) { - symbolsList.add(entry.feature); - } - } - break; - } - break; - } - if(endloop) - break; - } - - // draw legend - int cnt = seqList.size(); - y = ymain + seqHeight + (cnt - 2) * levelOffset; - args.hRegion = y - yRegion; - //Rectangle2D.Double rc = new Rectangle2D.Double(xoffset, y, (cw - 2 * xoffset), 0); - Rectangle2D.Double rc = new Rectangle2D.Double(xoffset, y, (cw - 2 * xoffset), 0); - //System.out.println("Calling with y: " + rc.y + ", cnt: " + cnt); - if(args.redrawCount == 1) - args.singleColumn = symbols.isSingleColumnLegend(gc, legendFont, rc); - Point2D.Double pmax = symbols.drawLegend(gc, legendColor, legendFont, rc, TextAlignment.CENTER, true, args.singleColumn, true, intronLegend, inexLegend); - y = pmax.y; - - // adjust size accordingly if needed - y += 30/scale; - double crh = 0; - boolean redraw = false; - double reqHeight = (y + crh) * scale; - System.out.println("Required canvas height (" + y + "): " + ((y + crh) * scale) + ", current canvas height: " + ch); - if(args.redrawCount == 1) { - if(ch < ((y + crh) * scale)) { - System.out.println("Setting canvas height to: " + ((y + crh) * scale)); - canvas.setHeight(reqHeight); - redraw = true; - } - - double sbHeight = 0.0; - double sbWidth = 0.0; - double xadd = 0; - if(redraw) - xadd -= sbWidth; - // note: the sb width is reported wrong initially, 20, if window is resized then it goes to 15 - System.out.println("Setting canvas width to: " + ((cw * scale + xadd) * widthFactor) + ", sbw: " + sbWidth); - canvas.setWidth((cw * scale + xadd) * widthFactor); - if(scale != 1) { - if(pmax.x > cw) - System.out.println("Legend exceeded canvas width, " + pmax.x); - - // check if we have a vertical bar and adjust if so - if(widthFactor > 1) - canvas.setHeight(canvas.getHeight() - sbHeight); - redraw = true; - } - else if(widthFactor > 1) { - canvas.setHeight(canvas.getHeight() - sbHeight); - redraw = true; - } - else if(args.prefs.ruler) - redraw = true; - - if(redraw) { - args.redrawCount++; - draw(gc, args); - } - } - else { - double setHeight = canvas.getHeight(); - System.out.println("Canvas height after recalc: " + setHeight + ", redrawcnt: " + args.redrawCount); - if(args.redrawCount < 3 && Math.abs(setHeight - reqHeight) > 10) { - canvas.setHeight(reqHeight); - args.redrawCount++; - draw(gc, args); - } - } - } - @Override - protected void getRSAnnotationData(String rsid, ArrayList lines, ArrayList alst) { - ArrayList al = new ArrayList<>(); - try { - boolean process = false; - boolean genomic = false; - int strpos, endpos; - HashMap attrs; - for(String[] fields : lines) { - if(fields[0].equals(rsid)) { - String source = fields[1]; - String type = fields[2]; - if(project.data.getRsvdAnnotFeature(source, type).equals(AnnotFeature.TRANSCRIPT)) - process = true; - else if(project.data.getRsvdAnnotFeature(source, type).equals(AnnotFeature.PROTEIN)) - process = false; - else if(project.data.getRsvdAnnotFeature(source, type).equals(AnnotFeature.GENOMIC)) { - process = true; - genomic = true; - } - if(process) { - // skip past non-positional annotations - if(fields[3].isEmpty() || fields[3].equals(".") || fields[4].isEmpty() || fields[4].equals(".")) - continue; - String id = ""; - String name = ""; - String desc; - String caption = type; - attrs = DataAnnotation.getAttributes(fields[8]); - if(attrs.containsKey(project.data.getAnnotationFileDefs().attrId)) - id = attrs.get(project.data.getAnnotationFileDefs().attrId); - if(attrs.containsKey(project.data.getAnnotationFileDefs().attrName)) - name = attrs.get(project.data.getAnnotationFileDefs().attrName); - String tooltip = "Source: " + source + "\nFeature: " + type; - if(!id.isEmpty()) { - caption = id; - tooltip += "\nID: " + id; - } - if(!name.isEmpty() && !name.toLowerCase().equals(id.toLowerCase()) - && !name.toLowerCase().equals(type.toLowerCase())) { - if(id.isEmpty()) - caption = name; - tooltip += "\nName: " + name; - } - if(attrs.containsKey(project.data.getAnnotationFileDefs().attrDesc)) { - desc = attrs.get(project.data.getAnnotationFileDefs().attrDesc); - if(!desc.isEmpty() && !desc.toLowerCase().equals(id.toLowerCase()) - && !desc.toLowerCase().equals(name.toLowerCase()) - && !desc.toLowerCase().equals(type.toLowerCase())) - tooltip += "\nDescription: " + desc; - } - if(project.data.getRsvdAnnotFeature(source, type).equals(AnnotFeature.TRANSCRIPT)) { - String strid = id; - if(id.equals(fields[0])) - strid = ""; - tooltip = "Transcript " + fields[0]; - tooltip += "\nStrand: " + (fields[6].trim().equals("-")? "Negative" : "Positive"); - if(!strid.isEmpty()) - tooltip += "\nRefID: " + id; - if(attrs.containsKey("Alias")) - tooltip += " (" + attrs.get("Alias") + ")"; - } - - String urlValue = ""; - strpos = Integer.parseInt(fields[3]); - endpos = Integer.parseInt(fields[4]); - if(endpos < strpos) { - int tmp = endpos; - endpos = strpos; - strpos = tmp; - } - - String idval = id.isEmpty()? name : id; - al.add(new AnnotationEntry(fields[0],source,type,idval,caption,fields[6],strpos,endpos,fields[8], tooltip, urlValue)); - } - } - } - } - catch (Exception ex) { - logger.logError("Unable to process annotation data for transcript " + rsid + ": " + ex.getMessage()); - al.clear(); - } - - // must add in proper order for processing at drawing time - // these values come from the annotation file, there are no internal categories - for(AnnotationEntry a : al) { - if(project.data.getRsvdAnnotFeature(a.source, a.feature).equals(AnnotFeature.TRANSCRIPT)) { - alst.add(a); - break; - } - } - for(AnnotationEntry a : al) { - if(project.data.getRsvdAnnotFeature(a.source, a.feature).equals(AnnotFeature.GENE)) { - alst.add(a); - break; - } - } - for(AnnotationEntry a : al) { - if(project.data.getRsvdAnnotFeature(a.source, a.feature).equals(AnnotFeature.CDS)) { - alst.add(a); - break; - } - } - for(AnnotationEntry a : al) { - if(project.data.getRsvdAnnotFeature(a.source, a.feature).equals(AnnotFeature.EXON)) - alst.add(a); - } - for(AnnotationEntry a : al) { - if(project.data.getRsvdAnnotFeature(a.source, a.feature).equals(AnnotFeature.SPLICEJUNCTION)) - alst.add(a); - } - for(AnnotationEntry a : al) { - if(!project.data.getRsvdAnnotFeature(a.source, a.feature).equals(AnnotFeature.TRANSCRIPT) && - !project.data.getRsvdAnnotFeature(a.source, a.feature).equals(AnnotFeature.GENE) && - !project.data.getRsvdAnnotFeature(a.source, a.feature).equals(AnnotFeature.CDS) && - !project.data.getRsvdAnnotFeature(a.source, a.feature).equals(AnnotFeature.EXON) && - !project.data.getRsvdAnnotFeature(a.source, a.feature).equals(AnnotFeature.SPLICEJUNCTION) && - !a.source.equals(STRUCTURAL_SOURCE)) - alst.add(a); - } - } -}