39e533cc9ffcb46d9c484dc09a387a031a739391 Merge parents 1c86690 f642bab kate Mon Sep 24 16:35:53 2018 -0700 Updating from master diff --cc src/hg/hgTracks/interactTrack.c index 1365ee9,ce8ee7a..da67bef --- src/hg/hgTracks/interactTrack.c +++ src/hg/hgTracks/interactTrack.c @@@ -100,147 -99,30 +100,153 @@@ { if (!(sOnScreen || tOnScreen)) continue; } } slAddHead(&filteredItems, inter); } slReverse(&filteredItems); // consider sorting by score/value so highest scored items draw last (on top) if (slCount(filteredItems) != count) labelTrackAsFiltered(tg); tg->items = filteredItems; } +void interactDrawLeftLabels(struct track *tg, int seqStart, int seqEnd, + struct hvGfx *hvg, int xOff, int yOff, int width, int height, + boolean withCenterLabels, MgFont *font, + Color color, enum trackVisibility vis) +/* Override default */ +{ +} + +void interactFreeItems(struct track *tg) +/* Free up interact items track */ +{ +interactFreeList((struct interact **)(&tg->items)); +} + +static boolean isBedMode(struct track *tg) +/* Pack and squish modes display using BED linked features code */ +{ +return tg->visibility == tvPack || tg->visibility == tvSquish; +} + +static struct linkedFeatures *interactToLf(struct interact *inter, boolean doColor) +/* Convert interact BED to linkedFeatures */ +{ +struct bed *bed = interactToBed(inter); +struct linkedFeatures *lf = lfFromBed(bed); +if (doColor) + { + lf->extra = (void *)USE_ITEM_RGB; /* signal for coloring */ + lf->filterColor = bed->itemRgb; + } +bedFree(&bed); +// TODO: use lfFromBedExtra with scoreMin, scoreMax ? +return lf; +} + ++static boolean isMergeMode(struct track *tg) ++/* Packed mode with merging on targets */ ++{ ++return cartBoolean(cart, "interactTargetMerge"); ++} ++ +void interactLoadItems(struct track *tg) +/* Load interact items in interact format */ +{ +loadAndFilterItems(tg); +if (isBedMode(tg)) + { + // convert to BEDs for linked feature display + struct interact *inters = tg->items, *inter; + struct linkedFeatures *lfs = NULL, *lf; + struct hash *intersMerge = hashNew(0); - boolean doMerge = cartVarExists(cart, "interactTargetMerge"); ++ boolean doMerge = isMergeMode(tg); + boolean doColor = !tg->colorShades; + for (inter = inters; inter; inter = inter->next) + { + if (doMerge) + { + lf = (struct linkedFeatures *) hashFindVal(intersMerge, inter->targetName); + if (lf) + { + // add a simple feature for this source to the linked feature + struct simpleFeature *sf = NULL; + AllocVar(sf); + sf->start = inter->sourceStart; + sf->end = inter->sourceEnd; + struct simpleFeature *sfs = lf->components; + slAddHead(&sfs, sf); + lf->components = sfs; + // TODO: consider averaging score + +/* + // FIXME: just for demo + struct bed *tempBed = interactToBed(inter); + if (orientFromChar(tempBed->strand[0]) != lf->orientation) + lf->orientation = 0; + bedFree(&tempBed); +*/ + } + else + { + // create a linked feature for this target + lf = interactToLf(inter, doColor); + lf->name = inter->targetName; + lf->tallStart = inter->targetStart; + lf->tallEnd = inter->targetEnd; + lf->orientation = 0; + hashAdd(intersMerge, lf->name, lf); + } + } + else + { + lf = interactToLf(inter, doColor); + slAddHead(&lfs, lf); + } + } + if (doMerge) + { + // sort simplefeatures and adjust bounds of merged features + struct hashEl *el, *els = hashElListHash(intersMerge); + for (el = els; el; el = el->next) + { + lf = (struct linkedFeatures *)el->val; + linkedFeaturesSortAndBound(lf); + slAddHead(&lfs, lf); + } + slSort(&lfs, linkedFeaturesCmp); + } + else + { + slReverse(&lfs); + } + tg->items = lfs; + // TODO: consider freeing interact items + } +else + { + tg->mapsSelf = TRUE; + tg->totalHeight = interactTotalHeight; + tg->drawLeftLabels = interactDrawLeftLabels; + tg->freeItems = interactFreeItems; + } +} + char *interactMouseover(struct interact *inter, char *otherChrom) /* Make mouseover text for an interaction */ { struct dyString *ds = dyStringNew(0); if (isEmptyTextField(inter->name)) { if (!isEmptyTextField(inter->exp)) dyStringPrintf(ds, "%s ", inter->exp); if (otherChrom) dyStringPrintf(ds, "%s", otherChrom); else { char buf[4096]; sprintLongWithCommas(buf, inter->chromEnd - inter->chromStart); dyStringPrintf(ds, "%s bp", buf); @@@ -680,56 -571,39 +686,59 @@@ ellipseOrient = ELLIPSE_TOP; yLeft = yOff + tg->height - peakHeight; yTop = yOff + tg->height + peakHeight; } hvGfxEllipseDraw(hvg, lowerX, yLeft, upperX, yTop, color, ellipseOrient, isReversed && doDashes); // draw grab box and map box on peak int maxY = peakHeight + yOff; int peakX = ((upperX - lowerX + 1) / 2) + lowerX; drawPeakMapbox(tg, hvg, inter->chromStart, inter->chromEnd, inter->name, statusBuf, peakX, maxY, peakColor, highlightColor, drawUp); } } } -void interactDrawLeftLabels(struct track *tg, int seqStart, int seqEnd, - struct hvGfx *hvg, int xOff, int yOff, int width, int height, - boolean withCenterLabels, MgFont *font, - Color color, enum trackVisibility vis) -/* Override default */ +void interactLinkedFeaturesDrawAt(struct track *tg, void *item, + struct hvGfx *hvg, int xOff, int y, double scale, + MgFont *font, Color color, enum trackVisibility vis) +/* Draw a item with target in contrasting color */ +{ +linkedFeaturesDrawAt(tg, item, hvg, xOff, y, scale, font, color, vis); + ++if (isMergeMode(tg)) + { + struct linkedFeatures *lf = item; + // TODO: use magenta if track isn't colored ? + drawScaledBox(hvg, lf->tallStart, lf->tallEnd, scale, xOff, y, tg->heightPer, MG_BLACK); + } ++} + +void interactDrawItems(struct track *tg, int seqStart, int seqEnd, + struct hvGfx *hvg, int xOff, int yOff, int width, + MgFont *font, Color color, enum trackVisibility vis) +/* Draw a list of interact structures. */ +{ +if (isBedMode(tg)) + { + tg->drawItemAt = interactLinkedFeaturesDrawAt; + linkedFeaturesDraw(tg, seqStart, seqEnd, hvg, xOff, yOff, width, font, color, vis); + } +else + drawInteractItems(tg, seqStart, seqEnd, hvg, xOff, yOff, width, font, color, vis); } void interactMethods(struct track *tg) /* Interact track type methods */ { +tg->bedSize = 12; +linkedFeaturesMethods(tg); // for pack and squish modes tg->loadItems = interactLoadItems; tg->drawItems = interactDrawItems; -tg->drawLeftLabels = interactDrawLeftLabels; -tg->totalHeight = interactTotalHeight; -tg->mapsSelf = TRUE; } void interactCtMethods(struct track *tg) /* Interact track methods for custom track */ { interactMethods(tg); }