b818160961573cd7b8902303ca4dc532d1366513 max Mon Apr 29 11:14:47 2024 -0700 adding name filter and color track options to hgTrackUi, refs #20460 diff --git src/hg/hgTracks/simpleTracks.c src/hg/hgTracks/simpleTracks.c index 5d5bd77..9ed8cd6 100644 --- src/hg/hgTracks/simpleTracks.c +++ src/hg/hgTracks/simpleTracks.c @@ -1798,30 +1798,69 @@ return GLYPH_INV_TRIANGLE; if (sameWordOk(glyphStr, GLYPH_STRING_SQUARE)) return GLYPH_SQUARE; if (sameWordOk(glyphStr, GLYPH_STRING_DIAMOND)) return GLYPH_DIAMOND; if (sameWordOk(glyphStr, GLYPH_STRING_OCTAGON)) return GLYPH_OCTAGON; if (sameWordOk(glyphStr, GLYPH_STRING_STAR)) return GLYPH_STAR; if (sameWordOk(glyphStr, GLYPH_STRING_PENTAGRAM)) return GLYPH_PENTAGRAM; return GLYPH_CIRCLE; } +void filterItemsOnNames(struct track *tg) +/* Only keep items with a name in the .nameFilter cart var. + * Not using filterItems(), because filterItems has no state at all. */ +{ +char varName[SMALLBUF]; +safef(varName, sizeof(varName), "%s.nameFilter", tg->tdb->track); +char *nameFilterStr = cartNonemptyString(cart, varName); + +if (nameFilterStr==NULL) + return; + +struct slName *names = slNameListFromString(nameFilterStr, ','); +struct hash *nameHash = hashFromSlNameList(names); + +struct slList *newList = NULL, *el, *next; +for (el = tg->items; el != NULL; el = next) + { + next = el->next; + struct linkedFeatures *lf = (struct linkedFeatures*)el; + char *name = lf->name; + if (name && hashLookup(nameHash, name)) + slAddHead(&newList, el); +} +tg->items = newList; + +char *suf = ""; +int nameCount = slCount(names); +if (nameCount > 1) + suf = "s"; + +char buf[SMALLBUF]; +safef(buf, sizeof(buf), " (manually filtered to show only %d accession%s)", nameCount, suf); +char *oldLabel = tg->longLabel; +tg->longLabel = catTwoStrings(tg->longLabel, buf); +freez(&oldLabel); + +slFreeList(&names); +hashFree(&nameHash); +} void filterItems(struct track *tg, boolean (*filter)(struct track *tg, void *item), char *filterType) /* Filter out items from track->itemList. */ { struct slList *newList = NULL, *oldList = NULL, *el, *next; boolean exclude = FALSE; boolean color = FALSE; enum trackVisibility vis = tvHide; if (sameWord(filterType, "none")) return; if (sameWord(filterType, "include")) exclude = FALSE; @@ -4137,45 +4176,48 @@ /*if we are zoomed in far enough, look to see if we are coloring by codon, and setup if so.*/ if (vis != tvDense) { drawOpt = baseColorDrawSetup(hvg, tg, lf, &qSeq, &qOffset, &psl); if (drawOpt > baseColorDrawOff) exonArrows = FALSE; } if ((tg->tdb != NULL) && (vis != tvDense)) intronGap = atoi(trackDbSettingOrDefault(tg->tdb, "intronGap", "0")); lfColors(tg, lf, hvg, &color, &bColor); if (vis == tvDense && trackDbSetting(tg->tdb, EXP_COLOR_DENSE)) color = saveColor; +color = colorFromCart(tg, color); + +struct genePred *gp = NULL; +if (startsWith("genePred", tg->tdb->type) || startsWith("bigGenePred", tg->tdb->type)) + gp = (struct genePred *)(lf->original); + boolean baseColorNeedsCodons = (drawOpt == baseColorDrawItemCodons || drawOpt == baseColorDrawDiffCodons || drawOpt == baseColorDrawGenomicCodons); if (psl && baseColorNeedsCodons) { boolean isXeno = ((tg->subType == lfSubXeno) || (tg->subType == lfSubChain) || startsWith("mrnaBla", tg->table)); int sizeMul = pslIsProtein(psl) ? 3 : 1; lf->codons = baseColorCodonsFromPsl(lf, psl, sizeMul, isXeno, maxShade, drawOpt, tg); } else if (drawOpt > baseColorDrawOff) { - struct genePred *gp = NULL; - if (startsWith("genePred", tg->tdb->type) || startsWith("bigGenePred", tg->tdb->type)) - gp = (struct genePred *)(lf->original); if (gp && gp->cdsStart != gp->cdsEnd) lf->codons = baseColorCodonsFromGenePred(lf, gp, (drawOpt != baseColorDrawDiffCodons), cartUsualBooleanClosestToHome(cart, tg->tdb, FALSE, CODON_NUMBERING_SUFFIX, TRUE)); } if (psl && drawOpt == baseColorDrawCds && !zoomedToCdsColorLevel) baseColorSetCdsBounds(lf, psl, tg); tallStart = lf->tallStart; tallEnd = lf->tallEnd; if ((tallStart == 0 && tallEnd == 0) && lf->start != 0 && !sameWord(tg->table, "jaxQTL3")) { // sometimes a bed <8 will get passed off as a bed 8, tsk tsk tallStart = lf->start; tallEnd = lf->end; } int ourStart = lf->start; @@ -5228,30 +5270,32 @@ } #endif//ndef IMAGEv2_SHORT_MAPITEMS y += tg->lineHeight; } } } void genericDrawItems(struct track *tg, int seqStart, int seqEnd, struct hvGfx *hvg, int xOff, int yOff, int width, MgFont *font, Color color, enum trackVisibility vis) /* Draw generic item list. Features must be fixed height * and tg->drawItemAt has to be filled in. */ { withIndividualLabels = TRUE; // set this back to default just in case someone left it false (I'm looking at you pgSnp) +color = colorFromCart(tg, color); + if (tg->mapItem == NULL) tg->mapItem = genericMapItem; if (vis != tvDense && baseColorCanDraw(tg)) baseColorInitTrack(hvg, tg); boolean doWiggle = checkIfWiggling(cart, tg); if (doWiggle) { genericDrawItemsWiggle(tg, seqStart, seqEnd, hvg, xOff, yOff, width, font, color, vis); } else if (vis == tvPack || vis == tvSquish || (vis == tvFull && isTypeBedLike(tg))) { genericDrawItemsPackSquish(tg, seqStart, seqEnd, hvg, xOff, yOff, width, font, color, vis); } @@ -5264,30 +5308,32 @@ struct hvGfx *hvg, int xOff, int yOff, int width, MgFont *font, Color color, enum trackVisibility vis) /* Draw linked features items. */ { if (vis == tvDense && tg->colorShades) slSort(&tg->items, cmpLfsWhiteToBlack); genericDrawItems(tg, seqStart, seqEnd, hvg, xOff, yOff, width, font, color, vis); } void linkedFeaturesDraw(struct track *tg, int seqStart, int seqEnd, struct hvGfx *hvg, int xOff, int yOff, int width, MgFont *font, Color color, enum trackVisibility vis) /* Draw linked features items. */ { +color = colorFromCart(tg, color); + if (tg->items == NULL && vis == tvDense && canDrawBigBedDense(tg)) { bigBedDrawDense(tg, seqStart, seqEnd, hvg, xOff, yOff, width, font, color); } else { if (vis == tvDense && tg->colorShades) slSort(&tg->items, cmpLfWhiteToBlack); genericDrawItems(tg, seqStart, seqEnd, hvg, xOff, yOff, width, font, color, vis); } // put up the color key for the gnomAD pLI track if (startsWith("pliBy", tg->track)) doPliColors = TRUE; @@ -6899,30 +6945,32 @@ char *bigGenePred = trackDbSetting(tdb, "bigGeneDataUrl"); struct udcFile *file; boolean isBigGenePred = FALSE; if ((bigGenePred != NULL) && ((file = udcFileMayOpen(bigGenePred, udcDefaultDir())) != NULL)) { isBigGenePred = TRUE; udcFileClose(&file); loadKnownBigGenePred(tg, isGencode); } else if (!isGencode) loadGenePredWithName2(tg); else loadKnownGencode(tg); +filterItemsOnNames(tg); + char varName[SMALLBUF]; safef(varName, sizeof(varName), "%s.show.noncoding", tdb->track); boolean showNoncoding = cartUsualBoolean(cart, varName, TRUE); safef(varName, sizeof(varName), "%s.show.spliceVariants", tdb->track); boolean showSpliceVariants = cartUsualBoolean(cart, varName, TRUE); if (!showNoncoding) tg->items = stripShortLinkedFeatures(tg->items); if (!showSpliceVariants) { if (isBigGenePred) { tg->items = stripLinkedFeaturesWithoutBitInScore(tg->items, BIT_CANON); } else {