90386a2976637e3a37523bc7d04f6577d7c3f6b3 braney Thu Aug 3 14:10:42 2017 -0700 fold Joel's insert display changes into tree diff --git src/hg/hgTracks/snakeTrack.c src/hg/hgTracks/snakeTrack.c index 1a84742..8a7bdf5 100644 --- src/hg/hgTracks/snakeTrack.c +++ src/hg/hgTracks/snakeTrack.c @@ -18,30 +18,32 @@ #include "errCatch.h" #include "twoBit.h" #include "bigWarn.h" #include <pthread.h> #include "trackHub.h" #include "limits.h" #include "snakeUi.h" #include "bits.h" #include "trix.h" #include "halBlockViz.h" #include "bigPsl.h" // this is the number of pixels used by the target self-align bar #define DUP_LINE_HEIGHT 4 +// this is the number of pixels used when displaying the insertion lengths +#define INSERT_TEXT_HEIGHT 10 struct snakeFeature { struct snakeFeature *next; int start, end; /* Start/end in browser coordinates. */ int qStart, qEnd; /* query start/end */ int level; /* level in snake */ int orientation; /* strand... -1 is '-', 1 is '+' */ boolean drawn; /* did we draw this feature? */ char *qSequence; /* may have sequence, or NULL */ char *tSequence; /* may have sequence, or NULL */ char *qName; /* chrom name on other species */ unsigned pixX1, pixX2; /* pixel coordinates within window */ }; @@ -658,31 +660,31 @@ { if (tg->networkErrMsg != NULL) { // we had a parallel load failure tg->drawItems = bigDrawWarning; tg->totalHeight = bigWarnTotalHeight; return bigWarnTotalHeight(tg, vis); } if (vis == tvDense) return tg->lineHeight; if (vis == tvSquish) return tg->lineHeight/2; -int height = DUP_LINE_HEIGHT; +int height = DUP_LINE_HEIGHT + INSERT_TEXT_HEIGHT; struct slList *item = tg->items; item = tg->items; for (item=tg->items;item; item = item->next) { height += tg->itemHeight(tg, item); } if (height < DUP_LINE_HEIGHT + tg->lineHeight) height = DUP_LINE_HEIGHT + tg->lineHeight; return height; } static void snakeDraw(struct track *tg, int seqStart, int seqEnd, struct hvGfx *hvg, int xOff, int yOff, int width, @@ -1082,108 +1084,180 @@ y1 = offY + (lastLevel * 2 + 1) * lineHeight - 1; y2 = offY + (sf->level * 2 ) * lineHeight - lineHeight/3;; } s = sf->start; e = sf->end; sx = round((double)((int)s-winStart)*scale) + xOff; ex = round((double)((int)e-winStart)*scale) + xOff; color = (sf->orientation == -1) ? MG_RED : MG_BLUE; if (lastX != -1) { char buffer[1024]; #define MG_ORANGE 0xff0082E6 int color = MG_GRAY; - if (lastQEnd != qs) - color = MG_ORANGE; + if (lastQEnd != qs) { + long long queryInsertSize = llabs(lastQEnd - qs); + long long targetInsertSize; + if (sf->orientation == 1) + targetInsertSize = s - lastE; + else + targetInsertSize = lastS - e; + int blue = 0; + int red = 0; + int green = 0; + if (queryInsertSize > targetInsertSize) { + double frac = ((double) queryInsertSize - targetInsertSize) / targetInsertSize; + if (frac > 1.0) + frac = 1.0; + red = 255 - 255 * frac; + blue = 255 * frac; + } else { + double frac = ((double) targetInsertSize - queryInsertSize) / targetInsertSize; + if (frac > 1.0) + frac = 1.0; + red = 255 - 255 * frac; + green = 255 * frac; + } + color = hvGfxFindColorIx(hvg, red, green, blue); + } + double queryGapNFrac = 0.0; + double queryGapMaskedFrac = 0.0; + if (qs - lastQEnd != 0 && qs - lastQEnd < 1000000) { + // sketchy + char *fileName = trackDbSetting(tg->tdb, "bigDataUrl"); + char *otherSpecies = trackDbSetting(tg->tdb, "otherSpecies"); + int handle = halOpenLOD(fileName, NULL); + char *queryGapDna = halGetDna(handle, otherSpecies, sf->qName, lastQEnd, qs, NULL); + long long numNs = 0; + long long numMasked = 0; + char *i = queryGapDna; + while (*i != '\0') { + if (*i == 'N' || *i == 'n') { + numNs++; + numMasked++; + } + if (*i == 'a' || *i == 't' || *i == 'g' || *i == 'c') { + numMasked++; + } + i++; + } + free(queryGapDna); + queryGapMaskedFrac = ((double) numMasked) / (qs - lastQEnd); + queryGapNFrac = ((double) numNs) / (qs - lastQEnd); + } // draw the vertical orange bars if there is an insert in the other sequence if ((winBaseCount < showSnpWidth) ) { if ((sf->orientation == 1) && (qs != lastQEnd) && (lastE == s)) { hvGfxLine(hvg, sx, y2 - lineHeight/2 , sx, y2 + lineHeight/2, MG_ORANGE); - safef(buffer, sizeof buffer, "%dbp", qs - lastQEnd); + safef(buffer, sizeof buffer, "%dbp (%.1lf%% N, %.1lf%% masked)", qs - lastQEnd, queryGapNFrac*100, queryGapMaskedFrac*100); boundMapBox(hvg, s, e, sx, y2 - lineHeight/2, 1, lineHeight, tg->track, "foo", buffer, NULL, TRUE, NULL); + safef(buffer, sizeof buffer, "%dbp", qs - lastQEnd); + hvGfxTextCentered(hvg, sx - 10, y2 + lineHeight/2, 20, INSERT_TEXT_HEIGHT, MG_ORANGE, font, buffer); } else if ((sf->orientation == -1) && (qs != lastQEnd) && (lastS == e)) { hvGfxLine(hvg, ex, y2 - lineHeight/2 , ex, y2 + lineHeight/2, MG_ORANGE); - safef(buffer, sizeof buffer, "%dbp", qs - lastQEnd); + safef(buffer, sizeof buffer, "%dbp (%.1lf%% N, %.1lf%% masked)", qs - lastQEnd, queryGapNFrac*100, queryGapMaskedFrac*100); boundMapBox(hvg, s, e, ex, y2 - lineHeight/2, 1, lineHeight, tg->track, "foo", buffer, NULL, TRUE, NULL); + safef(buffer, sizeof buffer, "%dbp", qs - lastQEnd); + hvGfxTextCentered(hvg, ex - 10, y2 + lineHeight/2, 20, INSERT_TEXT_HEIGHT, MG_ORANGE, font, buffer); } } // now draw the lines between blocks if ((!((lastX == sx) && (y1 == y2))) && (sf->drawn || ((prevSf != NULL) && (prevSf->drawn))) && (((lastE >= winStart) && (lastE <= winEnd)) || ((s > winStart) && (s < winEnd)))) { if (lastLevel == sf->level) { - safef(buffer, sizeof buffer, "%dbp", qs - lastQEnd); + if (sf->orientation == 1) + safef(buffer, sizeof buffer, "%dbp (%dbp in ref) (%.1lf%% N, %.1lf%% masked)", qs - lastQEnd, s - lastE, queryGapNFrac*100, queryGapMaskedFrac*100); + else + safef(buffer, sizeof buffer, "%dbp (%dbp in ref) (%.1lf%% N, %.1lf%% masked)", qs - lastQEnd, lastS - e, queryGapNFrac*100, queryGapMaskedFrac*100); if (sf->orientation == -1) { if (lastX != ex) { hvGfxLine(hvg, ex, y1, lastX, y2, color); boundMapBox(hvg, s, e, ex, y1, lastX-ex, 1, tg->track, "", buffer, NULL, TRUE, NULL); + if (lastQEnd != qs) { + safef(buffer, sizeof buffer, "%dbp", qs - lastQEnd); + hvGfxTextCentered(hvg, ex, y2 + lineHeight/2, lastX-ex, INSERT_TEXT_HEIGHT, MG_ORANGE, font, buffer); + } } } else { if (lastX != sx) { hvGfxLine(hvg, lastX, y1, sx, y2, color); boundMapBox(hvg, s, e, lastX, y1, sx-lastX, 1, tg->track, "", buffer, NULL, TRUE, NULL); + if (lastQEnd != qs) { + safef(buffer, sizeof buffer, "%dbp", qs - lastQEnd); + hvGfxTextCentered(hvg, lastX, y2 + lineHeight/2, sx-lastX, INSERT_TEXT_HEIGHT, MG_ORANGE, font, buffer); + } } } } else if (lastLevel > sf->level) { hvGfxLine(hvg, lastX, y1, sx, y2, color); hvGfxLine(hvg, sx, y2, sx, y2 - lineHeight - lineHeight/3, color); char buffer[1024]; - safef(buffer, sizeof buffer, "%d-%d %dbp gap",prevSf->qStart,prevSf->qEnd, qs - lastQEnd); + safef(buffer, sizeof buffer, "%d-%d %dbp gap (%.1lf%% N, %.1lf%% masked)",prevSf->qStart,prevSf->qEnd, qs - lastQEnd, queryGapNFrac*100, queryGapMaskedFrac*100); boundMapBox(hvg, s, e, sx, y2 - lineHeight - lineHeight/3, 2, lineHeight + lineHeight/3, tg->track, "", buffer, NULL, TRUE, NULL); + safef(buffer, sizeof buffer, "%dbp", qs - lastQEnd); + if (lastQEnd != qs) + hvGfxTextCentered(hvg, sx - 10, y2 + lineHeight/2, 20, INSERT_TEXT_HEIGHT, MG_ORANGE, font, buffer); } else { char buffer[1024]; - safef(buffer, sizeof buffer, "%d-%d %dbp gap",prevSf->qStart,prevSf->qEnd, qs - lastQEnd); + safef(buffer, sizeof buffer, "%d-%d %dbp gap (%.1lf%% N, %.1lf%% masked)",prevSf->qStart,prevSf->qEnd, qs - lastQEnd, queryGapNFrac*100, queryGapMaskedFrac*100); if (sf->orientation == -1) { hvGfxLine(hvg, lastX-1, y1, ex, y2, color); hvGfxLine(hvg, ex, y2, ex, y2 + lineHeight , color); boundMapBox(hvg, s, e, ex-1, y2, 2, lineHeight , tg->track, "", buffer, NULL, TRUE, NULL); + safef(buffer, sizeof buffer, "%dbp", qs - lastQEnd); + if (lastQEnd != qs) + hvGfxTextCentered(hvg, ex - 10, y2 + lineHeight, 20, INSERT_TEXT_HEIGHT, MG_ORANGE, font, buffer); } else { hvGfxLine(hvg, lastX-1, y1, sx, y2, color); hvGfxLine(hvg, sx, y2, sx, y2 + lineHeight , color); boundMapBox(hvg, s, e, sx-1, y2, 2, lineHeight , tg->track, "", buffer, NULL, TRUE, NULL); + safef(buffer, sizeof buffer, "%dbp", qs - lastQEnd); + if (lastQEnd != qs) + hvGfxTextCentered(hvg, sx - 10, y2 + lineHeight, 20, INSERT_TEXT_HEIGHT, MG_ORANGE, font, buffer); } } } } if (sf->orientation == -1) lastX = sx; else lastX = ex; lastS = s; lastE = e; lastLevel = sf->level; lastQEnd = qe; } }