f8d4a7651a5843d1c0bfa90cdb7da7582615c263 kate Thu Aug 9 13:47:29 2018 -0700 Add filter to hide interactions lacking one or both ends in the window. Helpful for busy/noisy datasets. refs #21109 diff --git src/hg/hgTracks/interactTrack.c src/hg/hgTracks/interactTrack.c index f770776..b19dba2 100644 --- src/hg/hgTracks/interactTrack.c +++ src/hg/hgTracks/interactTrack.c @@ -33,58 +33,93 @@ return tg->colorShades[grayInRange(inter->score, 0, 1000)]; } /* There must be a better way..., e.g.: unsigned red = COLOR_32_RED(inter->color); unsigned green = COLOR_32_GREEN(inter->color); unsigned blue = COLOR_32_BLUE(inter->color); */ unsigned red = (inter->color & 0xff0000) >> 16; unsigned green = (inter->color & 0xff00) >> 8; unsigned blue = inter->color & 0xff; return hvGfxFindColorIx(hvg, red, green, blue); } +boolean interactSourceInWindow(struct interact *inter) +/* True if midpoint of source is on screen */ +{ +unsigned s = interactRegionCenter(inter->sourceStart, inter->sourceEnd); +return (s >= winStart) && (s < winEnd); +} + +boolean interactTargetInWindow(struct interact *inter) +/* True if midpoint of target is on screen */ +{ +unsigned t = interactRegionCenter(inter->targetStart, inter->targetEnd); +return (t >= winStart) && (t < winEnd); +} + void interactLoadItems(struct track *tg) /* Load all interact items in region */ { loadSimpleBedWithLoader(tg, (bedItemLoader)interactLoadAndValidate); if (slCount(tg->items) == 0 && tg->limitedVisSet) { // too many items to display // borrowed behaviors in bamTrack and vcfTrack // TODO BRANEY: make this behavior generic for bigBeds // (bigBedSelectRange) tg->drawItems = bigDrawWarning; tg->networkErrMsg = "Too many items in display (zoom in)"; tg->totalHeight = bigWarnTotalHeight; return; } -// filter on score +// filters + +// score filter char buf[1024]; safef(buf, sizeof buf, "%s.%s", tg->tdb->track, INTERACT_MINSCORE); int minScore = cartUsualInt(cart, buf, 0); struct interact *inter, *next, *filteredItems = NULL; int count = slCount(tg->items); + +// exclude if missing endpoint(s) in window +char *endsVisible = cartUsualStringClosestToHome(cart, tg->tdb, FALSE, + INTERACT_ENDS_VISIBLE, INTERACT_ENDS_VISIBLE_DEFAULT); for (inter = tg->items; inter; inter = next) { next = inter->next; if (inter->score < minScore) continue; + if (differentString(endsVisible, INTERACT_ENDS_VISIBLE_ANY)) + { + boolean sOnScreen = interactSourceInWindow(inter); + boolean tOnScreen = interactTargetInWindow(inter); + if (sameString(endsVisible, INTERACT_ENDS_VISIBLE_TWO)) + { + if (!(sOnScreen && tOnScreen)) + continue; + } + if (sameString(endsVisible, INTERACT_ENDS_VISIBLE_ONE)) + { + 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; } char *interactMouseover(struct interact *inter, char *otherChrom) /* Make mouseover text for an interaction */ { struct dyString *ds = dyStringNew(0); if (isEmptyTextField(inter->name))