0f3ca3eaf5792df01b7c600a5428d2d0b2809fcd max Fri Sep 20 13:18:01 2024 -0700 Revert "more features to hubtools: search in both parent and subdirs, better docs" This reverts commit 05e67c59a20a5d00b810a981aef3b00c5bef82e1. diff --git src/hg/hgTracks/simpleTracks.c src/hg/hgTracks/simpleTracks.c index e6c9d30..39c2763 100644 --- src/hg/hgTracks/simpleTracks.c +++ src/hg/hgTracks/simpleTracks.c @@ -1659,101 +1659,30 @@ return FALSE; // Ignore. if (chromStart > winEnd || winStart > chromEnd || (!isIns && chromStart == winEnd) || (!isIns && chromEnd == winStart)) // doesn't overlap window? return FALSE; // nothing to do if (chromStart < winStart) // clip to part overlapping window chromStart = winStart; if (chromEnd > winEnd) // which prevents x1,x2 from overflowing when zooming-in makes scale large. chromEnd = winEnd; *pX1 = round((double)(chromStart-winStart)*scale) + xOff; *pX2 = isIns ? (*pX1 + 1) : round((double)(chromEnd-winStart)*scale) + xOff; return TRUE; } -void drawNotches(struct hvGfx* hvg, int x1, int x2, int y, int height, Color color, int startPhase, int endPhase) -{ -// do nothing for -1 and 0. Also ignore invalid exonFrame numbers, e.g. 4. -int w = (int)(height*0.75); -int halfHeight = (int)(height/2); - -if (x2-x1 < 2*w) - w = ((x2-x1)/2); - -//if ((x2-x1) > 8*height) // TODO: this should use the letter-width somehow... - //return; - -if ((startPhase==1 || startPhase==2)) - { - struct gfxPoly *poly = gfxPolyNew(); - switch (startPhase) - { - case 1 : - // a triangle - gfxPolyAddPoint(poly, x1, y+halfHeight); - gfxPolyAddPoint(poly, x1+w, y); - gfxPolyAddPoint(poly, x1+w, y+height); - break; - - case 2 : - { - // the opposite of a triangle - int halfW = (int)(w/2); - gfxPolyAddPoint(poly, x1, y); - gfxPolyAddPoint(poly, x1, y+height); - gfxPolyAddPoint(poly, x1+w, y+height); - gfxPolyAddPoint(poly, x1+halfW, y+halfHeight); - gfxPolyAddPoint(poly, x1+w, y); - break; - } - } - - hvGfxDrawPoly(hvg,poly,color,TRUE); - gfxPolyFree(&poly); - } - -if (endPhase==1 || endPhase==2) - { - struct gfxPoly *poly = gfxPolyNew(); - switch (endPhase) - { - case 1 : - // a triangle - gfxPolyAddPoint(poly, x2-w, y); - gfxPolyAddPoint(poly, x2+w, y+halfHeight); - gfxPolyAddPoint(poly, x2-w, y+height); - break; - - case 2 : - { - // the opposite of a triangle - int halfW = (int)(w/2); - gfxPolyAddPoint(poly, x2-w, y); - gfxPolyAddPoint(poly, x2-w, y+height); - gfxPolyAddPoint(poly, x2, y+height); - gfxPolyAddPoint(poly, x2-halfW, y+halfHeight); - gfxPolyAddPoint(poly, x2, y); - break; - } - } - - hvGfxDrawPoly(hvg,poly,color,TRUE); - gfxPolyFree(&poly); - } -} - void drawScaledBox(struct hvGfx *hvg, int chromStart, int chromEnd, double scale, int xOff, int y, int height, Color color) /* Draw a box scaled from chromosome to window coordinates. * Get scale first with scaleForPixels. */ { int x1, x2; if (scaledBoxToPixelCoords(chromStart, chromEnd, scale, xOff, &x1, &x2)) { int w = x2-x1; if (w == 0) // when zoomed out, avoid shinking to nothing w = 1; hvGfxBox(hvg, x1, y, w, height, color); } } @@ -2733,51 +2662,51 @@ *pNewWinStart = *pNewWinEnd - newWinSize; } #define EXONTEXTLEN 256 static void makeExonFrameText(int exonIntronNumber, int numExons, int startPhase, int endPhase, char *buf) /* Write mouseover text that describes the exon's phase into buf[EXONTEXTLEN]. Note that start/end-phases are in the direction of transcription: if transcript is on + strand, the start phase is the exonFrame value, and the end phase is the next exonFrame (3' on DNA) value if transcript is on - strand, the start phase is the previous (=3' on DNA) exonFrame and the end phase is the exonFrame */ { if (startPhase==-1) // UTRs don't have a frame at all { - safef(buf, EXONTEXTLEN, "<br>untranslated region"); + safef(buf, EXONTEXTLEN, ", untranslated region"); } else { char *exonNote = ""; boolean isNotLastExon = (exonIntronNumber<numExons); if (isNotLastExon) { if (startPhase==endPhase) - exonNote = " = in-frame exon"; + exonNote = ": in-frame exon"; else - exonNote = " = out-of-frame exon"; - safef(buf, EXONTEXTLEN, "<br><b>Codon Phase:</b> Start %d, End %d%s", startPhase, endPhase, exonNote); + exonNote = ": out-of-frame exon"; + safef(buf, EXONTEXTLEN, ", codon phase: start %d, end %d%s", startPhase, endPhase, exonNote); } else { if (startPhase==0) - exonNote = " = in-frame exon"; + exonNote = ": in-frame exon"; else - exonNote = " = out-of-frame exon"; - safef(buf, EXONTEXTLEN, "<br><b>Start Codon Phase:</b> %d%s", startPhase, exonNote); + exonNote = ": out-of-frame exon"; + safef(buf, EXONTEXTLEN, ", start codon phase %d%s", startPhase, exonNote); } } } boolean linkedFeaturesNextPrevItem(struct track *tg, struct hvGfx *hvg, void *item, int x, int y, int w, int h, boolean next) /* Draw a mapBox over the arrow-button on an *item already in the window*. */ /* Clicking this will do one of several things: */ { boolean result = FALSE; struct linkedFeatures *lf = item; struct simpleFeature *exons = lf->components; struct simpleFeature *exon = exons; char *nextExonText; char *prevExonText; long newWinSize = virtWinEnd - virtWinStart; @@ -2957,286 +2886,35 @@ linkedFeaturesMoveWinStart(xExonStart, bufferToEdge, newWinSize, &newWinStart, &newWinEnd); if (!revStrand) safef(mouseOverText, sizeof(mouseOverText), "%s (%d/%d)", prevExonText, numExons-exonIx, numExons); else safef(mouseOverText, sizeof(mouseOverText), "%s (%d/%d)", nextExonText, exonIx+1, numExons); mapBoxJumpTo(hvg, x, y, w, h, tg, virtChromName, newWinStart, newWinEnd, mouseOverText); result = TRUE; break; } } slFreeList(&exonList); slFreeList(&crList); return result; } -/* this is a take at refactoring linkedFeaturesItemExonMaps */ -static void drawExonMapsNotches(struct track *tg, struct hvGfx *hvg, void *item, double scale, - int y, int heightPer, int sItem, int eItem, - boolean lButton, boolean rButton, int buttonW, Color color) -/* Draw mapBoxes over exons and introns labeled with exon/intron numbers, phase information, and draw notches for phases. */ -{ -struct linkedFeatures *lf = item; -struct simpleFeature *exons = lf->components; -struct simpleFeature *exon = exons; -char *exonText, *intronText; -int numExons = 0; -int exonIx = 1; -struct slRef *exonList = NULL, *ref; -// TODO this exonText (and intronText) setting is just a made-up placeholder. -// could add a real setting name. Maybe someday extend to exon names (LRG?) instead of just exon numbers -if (startsWith("chain", tg->tdb->type) || startsWith("lrg", tg->tdb->track) || startsWith("net", tg->tdb->track)) - { - exonText = trackDbSettingClosestToHomeOrDefault(tg->tdb, "exonText" , "Block"); - intronText = trackDbSettingClosestToHomeOrDefault(tg->tdb, "intronText", "Gap" ); // what really goes here for chain type? - } -else - { - exonText = trackDbSettingClosestToHomeOrDefault(tg->tdb, "exonText" , "Exon" ); - intronText = trackDbSettingClosestToHomeOrDefault(tg->tdb, "intronText", "Intron"); - } - -while (exon != NULL) -/* Make a stupid list of exons separate from what's given. */ -/* It seems like lf->components isn't necessarily sorted. */ - { - refAdd(&exonList, exon); - exon = exon->next; - } -/* Now sort it. */ -slSort(&exonList, exonSlRefCmp); - -numExons = slCount(exonList); -boolean revStrand = (lf->orientation == -1); -int eLast = -1; -int s = -1; -int e = -1; -boolean isExon = TRUE; -int picStart = insideX; -int picEnd = picStart + insideWidth; -if (lButton) - picStart += buttonW; -if (rButton) - picEnd -= buttonW; - -for (ref = exonList; TRUE; ) - { - exon = ref->val; - if (isExon) - { - s = exon->start; - e = exon->end; - } - else - { - s = eLast; - e = exon->start; - } - // skip exons and introns that are completely outside the window - if (s <= winEnd && e >= winStart) - { - int sClp = (s < winStart) ? winStart : s; - int eClp = (e > winEnd) ? winEnd : e; - - int sx = round((sClp - winStart)*scale) + insideX; - int ex = round((eClp - winStart)*scale) + insideX; - - // skip regions entirely outside available picture - // (accounts for space taken by exon arrows buttons) - if (sx <= picEnd && ex >= picStart) - { - // clip it to avail pic - sx = (sx < picStart) ? picStart : sx; - ex = (ex > picEnd) ? picEnd : ex; - - int w = ex - sx; - - if (w > 0) // draw exon or intron if width is greater than 0 - { - int exonIntronNumber; - char *exonIntronText; - int numExonIntrons = numExons; - if (isExon) - { - exonIntronText = exonText; - } - else - { - exonIntronText = intronText; - --numExonIntrons; // introns are one fewer than exons - } - - char strandChar; - if (!revStrand) { - exonIntronNumber = exonIx; - strandChar = '+'; - } - else { - exonIntronNumber = numExonIntrons-exonIx+1; - strandChar = '-'; - } - - // we still need to show the existing mouseover text - char* existingText = lf->mouseOver; - if (isEmpty(existingText)) - existingText = lf->name; - - int startPhase = -1; - int endPhase = -1; - char phaseText[EXONTEXTLEN]; - phaseText[0] = 0; - struct genePred *gp = lf->original; - if ((gp != NULL) && gp->exonFrames && isExon) - { - startPhase = gp->exonFrames[exonIx-1]; - if (!revStrand) - endPhase = gp->exonFrames[exonIx]; - else - if (exonIx>1) - endPhase = gp->exonFrames[exonIx-2]; - makeExonFrameText(exonIntronNumber, numExons, startPhase, endPhase, phaseText); - } - - // draw mapBoxes for the codons if we are zoomed in far enough - struct simpleFeature *codon; - struct dyString *codonDy = dyStringNew(0); - int codonS, codonE; - if (isExon && lf->codons && zoomedToCdsColorLevel) - { - for (codon = lf->codons; codon != NULL; codon = codon->next) - { - codonS = codon->start; codonE = codon->end; - if (codonS <= winEnd && codonE >= winStart) - { - int codonSClp = (codonS < winStart) ? winStart : codonS; - int codonEClp = (codonE > winEnd) ? winEnd : codonE; - - int codonsx = round((codonSClp - winStart)*scale) + insideX; - int codonex = round((codonEClp - winStart)*scale) + insideX; - - // skip regions entirely outside available picture - // (accounts for space taken by exon arrows buttons) - if (codonsx <= picEnd && codonex >= picStart) - { - // clip it to avail pic - codonsx = (codonsx < picStart) ? picStart : codonsx; - codonex = (codonex > picEnd) ? picEnd : codonex; - - int w = codonex - codonsx; - if (w > 0) - { - // temporarily remove the mouseOver from the lf, since linkedFeatureMapItem will always - // prefer a lf->mouseOver over the itemName - char *oldMouseOver = lf->mouseOver; - lf->mouseOver = NULL; - dyStringClear(codonDy); - if (!isEmpty(existingText)) - dyStringPrintf(codonDy, "%s, ", existingText); - int codonHgvsIx = (codon->codonIndex - 1) * 3; - if (codonHgvsIx >= 0) - dyStringPrintf(codonDy, "<b>cDNA Pos:</b> c.%d-%d<br>", codonHgvsIx + 1, codonHgvsIx + 3); - dyStringPrintf(codonDy, "<b>Strand:</b> %c<br><b>%s</b> %d of %d%s", - strandChar, exonIntronText, exonIntronNumber, numExonIntrons, phaseText); - tg->mapItem(tg, hvg, item, codonDy->string, tg->mapItemName(tg, item), - sItem, eItem, codonsx, y, w, heightPer); - // and restore the mouseOver - lf->mouseOver = oldMouseOver; - } - } - } - } - } - } - /*else - { - // temporarily remove the mouseOver from the lf, since linkedFeatureMapItem will always - // prefer a lf->mouseOver over the itemName - if (!isEmpty(existingText)) - safef(mouseOverText, sizeof(mouseOverText), "%s, W < 0 ?? strand %c, %s %d of %d%s", - existingText, strandChar, exonIntronText, exonIntronNumber, numExonIntrons, phaseText); - else - safef(mouseOverText, sizeof(mouseOverText), "W < 0 ?? strand %c, %s %d of %d%s", - strandChar, exonIntronText, exonIntronNumber, numExonIntrons, phaseText); - char *oldMouseOver = lf->mouseOver; - lf->mouseOver = NULL; - tg->mapItem(tg, hvg, item, mouseOverText, tg->mapItemName(tg, item), - sItem, eItem, sx, y, w, heightPer); - // and restore the mouseOver - lf->mouseOver = oldMouseOver; - } - */ - - /*if (w > 0) // draw exon or intron if width is greater than 0 - { - char *sep = ""; - if (!isEmpty(existingText)) - sep = ", "; - - safef(mouseOverText, sizeof(mouseOverText), "%s%sstrand %c, %s %d of %d%s", - existingText, sep, strandChar, exonIntronText, exonIntronNumber, numExonIntrons, phaseText); - - // temporarily remove the mouseOver from the lf, since linkedFeatureMapItem will always - // prefer a lf->mouseOver over the itemName - char *oldMouseOver = lf->mouseOver; - lf->mouseOver = NULL; - tg->mapItem(tg, hvg, item, mouseOverText, tg->mapItemName(tg, item), - sItem, eItem, sx, y, w, heightPer); - // and restore the old mouseOver - lf->mouseOver = oldMouseOver; - - picStart = ex; // prevent pileups. is this right? add 1? does it work? - - Color notchColor = lighterColor(hvg, color); - Color notchColor2 = lighterColor(hvg, notchColor); - struct rgbColor rgb = hvGfxColorIxToRgb(hvg, notchColor2); - Color notchColor3 = MAKECOLOR_32_A(rgb.r,rgb.g,rgb.b,0.5); - drawNotches(hvg, sx, ex, y, heightPer, notchColor3, startPhase, endPhase); - } - */ - } - } - - if (isExon) - { - eLast = e; - ref = ref->next; - if (!ref) - break; - } - else - { - exonIx++; - } - isExon = !isExon; - - if (s > winEnd) // since the rest will also be outside the window - break; - - } - -slFreeList(&exonList); -} - -/* OLD CODE - under hg.conf control - to be removed one day */ void linkedFeaturesItemExonMaps(struct track *tg, struct hvGfx *hvg, void *item, double scale, int y, int heightPer, int sItem, int eItem, - boolean lButton, boolean rButton, int buttonW, Color color) + boolean lButton, boolean rButton, int buttonW) /* Draw mapBoxes over exons and introns labeled with exon/intron numbers */ { -if (cfgOptionBooleanDefault("newExonTooltips", FALSE)) - drawExonMapsNotches(tg, hvg, item, scale, y, heightPer, sItem, eItem, lButton, rButton, buttonW, color); - struct linkedFeatures *lf = item; struct simpleFeature *exons = lf->components; struct simpleFeature *exon = exons; char *exonText, *intronText; int numExons = 0; int exonIx = 1; struct slRef *exonList = NULL, *ref; // TODO this exonText (and intronText) setting is just a made-up placeholder. // could add a real setting name. Maybe someday extend to exon names (LRG?) instead of just exon numbers if (startsWith("chain", tg->tdb->type) || startsWith("lrg", tg->tdb->track)) { exonText = trackDbSettingClosestToHomeOrDefault(tg->tdb, "exonText" , "Block"); intronText = trackDbSettingClosestToHomeOrDefault(tg->tdb, "intronText", "Gap" ); // what really goes here for chain type? } else @@ -3437,31 +3115,30 @@ break; } else { exonIx++; } isExon = !isExon; if (s > winEnd) // since the rest will also be outside the window break; } slFreeList(&exonList); } -/* END OLD CODE */ static struct window *makeMergedWindowList(struct window *windows) /* Make a copy of the windows list, merging nearby regions on the same chrom and which are within some limit (1MB?) of each other. */ { int mergeLimit = 1024*1024; struct window *w = windows; struct window *resultList = NULL; struct window *mergedW = NULL; if (!windows) errAbort("Unexpected error: windows list NULL in makeMergedWindowList()"); boolean doNew = TRUE; while(TRUE) { if (doNew) @@ -4598,31 +4275,32 @@ color); } s = e2; } if (e > tallEnd) { s2 = s; if (s2 < tallEnd) s2 = tallEnd; if (lf->highlightColor && (lf->highlightMode == highlightOutline)) { drawScaledBox(hvg, s2, e, scale, xOff, y+shortOff, shortHeight, lf->highlightColor); drawScaledBox(hvg, s2, e, scale, xOff+1, y+shortOff+1, shortHeight-2, color); } else { - drawScaledBox(hvg, s2, e, scale, xOff, y+shortOff, shortHeight, color); + drawScaledBox(hvg, s2, e, scale, xOff, y+shortOff, shortHeight, + color); } e = s2; } /* Draw "tall" portion of exon (or codon) */ if (e > s) { if (drawOpt > baseColorDrawOff && e + 6 >= winStart && s - 6 < winEnd && (e-s <= 3 || !baseColorNeedsCodons)) baseColorDrawItem(tg, lf, sf->grayIx, hvg, xOff, y, scale, font, s, e, heightPer, zoomedToCodonLevel, qSeq, qOffset, sf, psl, drawOpt, MAXPIXELS, winStart, color); else { @@ -4887,32 +4565,31 @@ int w = x2-textX; if (lButton) { // if left-button, the label will be on far left, split out a map just for that label. tg->mapItem(tg, hvg, item, tg->itemName(tg, item), tg->mapItemName(tg, item), s, e, textX, y, insideX-textX, heightPer); textX = insideX + buttonW; // continue on the right side of the left exon button w = x2-textX; } if (rButton) { w -= buttonW; } if (compat) { // draw labeled exon/intron maps with exon/intron numbers - linkedFeaturesItemExonMaps(tg, hvg, item, scale, y, heightPer, s, e, lButton, rButton, buttonW, color); - + linkedFeaturesItemExonMaps(tg, hvg, item, scale, y, heightPer, s, e, lButton, rButton, buttonW); x2 = x1; w = x2-textX; } // if not already mapped, pick up the label if (!(lButton && compat)) { tg->mapItem(tg, hvg, item, tg->itemName(tg, item), tg->mapItemName(tg, item), s, e, textX, y, w, heightPer); } } else if (vis == tvSquish) { int w = x2-textX; tg->mapItem(tg, hvg, item, tg->itemName(tg, item), tg->mapItemName(tg, item), s, e, textX, y, w, heightPer); @@ -4925,31 +4602,31 @@ int trackPastTabX = (withLeftLabels ? trackTabWidth : 0); tg->mapItem(tg, hvg, item, tg->itemName(tg, item), tg->mapItemName(tg, item), s, e, trackPastTabX, y, insideX - trackPastTabX, heightPer); /* Depending on which button mapboxes we drew, draw the remaining mapbox. */ if (lButton) { geneMapBoxX += buttonW; geneMapBoxW -= buttonW; } if (rButton) { geneMapBoxW -= buttonW; } if (compat) { // draw labeled exon/intron maps with exon/intron numbers - linkedFeaturesItemExonMaps(tg, hvg, item, scale, y, heightPer, s, e, lButton, rButton, buttonW, color); + linkedFeaturesItemExonMaps(tg, hvg, item, scale, y, heightPer, s, e, lButton, rButton, buttonW); if (!lButton) { int w = x1 - geneMapBoxX; if (w > 0) tg->mapItem(tg, hvg, item, tg->itemName(tg, item), tg->mapItemName(tg, item), s, e, geneMapBoxX, y, w, heightPer); } if (!rButton) { int w = geneMapBoxX + geneMapBoxW - x2; if (w > 0) tg->mapItem(tg, hvg, item, tg->itemName(tg, item), tg->mapItemName(tg, item), s, e, x2, y, w, heightPer); } } @@ -13413,31 +13090,30 @@ char *table = tg->table; int bedSize = tg->bedSize; /* field count of bed part */ boolean useItemRgb = bedItemRgb(tg->tdb); struct customTrack *ct = tg->customPt; if (ct == NULL) conn = hAllocConn(database); else { conn = hAllocConn(CUSTOM_TRASH); table = ct->dbTableName; bedSize = ct->fieldCount - 2; useItemRgb = bedItemRgb(ct->tdb); } sr = hRangeQuery(conn, table, chromName, winStart, winEnd, NULL, &rowOffset); - while ((row = sqlNextRow(sr)) != NULL) { el = bedDetailLoadAsLf(row, rowOffset, bedSize, useItemRgb); slAddHead(&list, el); } slReverse(&list); sqlFreeResult(&sr); hFreeConn(&conn); tg->items = list; } void loadProtVar(struct track *tg) /* Load UniProt Variants with labels */ { struct protVarPos *list = NULL, *el;