733ba7b804e84d7b60ccad1f137398ecd52db983 chmalee Tue Apr 23 18:15:09 2024 -0700 Add a general highlight trackDb variable(s), working like trackDb filters, except put a color behind the item, refs #24507 diff --git src/hg/hgTracks/encode.c src/hg/hgTracks/encode.c index 32e15a8..79761a6 100644 --- src/hg/hgTracks/encode.c +++ src/hg/hgTracks/encode.c @@ -1,365 +1,365 @@ /* encode.c - hgTracks routines that are specific to the ENCODE project */ /* Copyright (C) 2012 The Regents of the University of California * See kent/LICENSE or http://genome.ucsc.edu/license/ for licensing information. */ #include "common.h" #include "hCommon.h" #include "hdb.h" #include "hui.h" #include "hgTracks.h" #include "customTrack.h" #include "encode.h" #include "encode/encodeRna.h" #include "encode/encodePeak.h" #include "bigBedFilter.h" extern struct trackLayout tl; char *encodeErgeName(struct track *tg, void *item) /* return the actual data name, in form xx/yyyy cut off xx/ return yyyy */ { char *name; struct linkedFeatures *lf = item; name = strstr(lf->name, "/"); if (name != NULL) name ++; if (name != NULL) return name; return "unknown"; } void encodeErgeMethods(struct track *tg) /* setup special methods for ENCODE dbERGE II tracks */ { tg->itemName = encodeErgeName; } Color encodeStanfordNRSFColor(struct track *tg, void *item, struct hvGfx *hvg) /* color by strand */ { struct bed *thisItem = item; int r = tg->color.r; int g = tg->color.g; int b = tg->color.b; if (thisItem->strand[0] == '-') { r = g; g = b; b = tg->color.r; } return hvGfxFindColorIx(hvg, r, g, b); } void encodeStanfordNRSFMethods(struct track *tg) /* custom methods for ENCODE Stanford NRSF data */ { tg->itemColor = encodeStanfordNRSFColor; tg->itemNameColor = encodeStanfordNRSFColor; } void loadEncodeRna(struct track *tg) /* Load up encodeRna from database table to track items. */ { bedLoadItem(tg, "encodeRna", (ItemLoader)encodeRnaLoad); } void freeEncodeRna(struct track *tg) /* Free up encodeRna items. */ { encodeRnaFreeList((struct encodeRna**)&tg->items); } Color encodeRnaColor(struct track *tg, void *item, struct hvGfx *hvg) /* Return color of encodeRna track item. */ { struct encodeRna *el = item; if(el->isRmasked) return MG_BLACK; if(el->isTranscribed) return hvGfxFindColorIx(hvg, 0x79, 0xaa, 0x3d); if(el->isPrediction) return MG_RED; return MG_BLUE; } char *encodeRnaName(struct track *tg, void *item) /* Return RNA gene name. */ { struct encodeRna *el = item; char *full = el->name; static char abbrev[SMALLBUF]; char *e; strcpy(abbrev, skipChr(full)); subChar(abbrev, '_', ' '); abbr(abbrev, " pseudogene"); if ((e = strstr(abbrev, "-related")) != NULL) strcpy(e, "-like"); return abbrev; } void encodeRnaMethods(struct track *tg) /* Make track for rna genes . */ { tg->loadItems = loadEncodeRna; tg->freeItems = freeEncodeRna; tg->itemName = encodeRnaName; tg->itemColor = encodeRnaColor; tg->itemNameColor = encodeRnaColor; } static struct linkedFeatures *lfFromEncodePeak(struct slList *item, struct trackDb *tdb, int scoreMin, int scoreMax) /* Translate an {encode,narrow,broad,gapped}Peak item into a linkedFeatures. */ { struct encodePeak *peak = (struct encodePeak *)item; struct linkedFeatures *lf; struct simpleFeature *sfList = NULL; if (!peak) return NULL; AllocVar(lf); lf->start = peak->chromStart; lf->end = peak->chromEnd; if (peak->peak > -1) { lf->tallStart = peak->chromStart + peak->peak; lf->tallEnd = lf->tallStart + 1; } lf->filterColor = -1; lf->orientation = orientFromChar(peak->strand[0]); adjustBedScoreGrayLevel(tdb, (struct bed *)peak, scoreMin, scoreMax); lf->grayIx = grayInRange((int)peak->score, scoreMin, scoreMax); lf->name = cloneString(peak->name); if (peak->blockCount > 0) { int i; for (i = 0; i < peak->blockCount; i++) { struct simpleFeature *sf; AllocVar(sf); sf->start = lf->start + peak->blockStarts[i]; sf->end = lf->start + peak->blockStarts[i] + peak->blockSizes[i]; sf->grayIx = lf->grayIx; slAddHead(&sfList, sf); } slReverse(&sfList); } else { AllocVar(sfList); sfList->start = lf->start; sfList->end = lf->end; sfList->grayIx = lf->grayIx; } lf->components = sfList; return lf; } static char *encodePeakFilter(char *trackName, struct trackDb *tdb, boolean isCustom) { struct dyString *extraWhere = dyStringNew(128); boolean and = FALSE; extraWhere = dyAddFilterAsInt(cart,tdb,extraWhere,SCORE_FILTER,"0:1000","score",&and); extraWhere = dyAddFilterAsDouble(cart,tdb,extraWhere,SIGNAL_FILTER,NULL,"signalValue",&and); extraWhere = dyAddFilterAsDouble(cart,tdb,extraWhere,PVALUE_FILTER,NULL,"pValue",&and); extraWhere = dyAddFilterAsDouble(cart,tdb,extraWhere,QVALUE_FILTER,NULL,"qValue",&and); if (sameString(extraWhere->string, "")) return NULL; return dyStringCannibalize(&extraWhere); } void bigNarrowPeakLoadItems(struct track *tg) /* Load a set of narrowPeaks from a bigNarrowPeak file. */ { struct linkedFeatures *lfList = NULL; enum encodePeakType pt = 0; int scoreMin = atoi(trackDbSettingClosestToHomeOrDefault(tg->tdb, "scoreMin", "0")); int scoreMax = atoi(trackDbSettingClosestToHomeOrDefault(tg->tdb, "scoreMax", "1000")); pt = narrowPeak; tg->customInt = pt; struct bbiFile *bbi = fetchBbiForTrack(tg); struct lm *lm = lmInit(0); struct bigBedInterval *bb, *bbList = bigBedIntervalQuery(bbi, chromName, winStart, winEnd, 0, lm); int fieldCount = 10; char *bedRow[fieldCount]; char startBuf[16], endBuf[16]; struct bigBedFilter *filters = NULL; struct bigBedFilter *filter; -if ((filter = bigBedMakeNumberFilter(cart, bbi, tg->tdb, SCORE_FILTER, "0:1000", "score")) != NULL) +if ((filter = bigBedMakeNumberFilter(cart, bbi, tg->tdb, SCORE_FILTER, "0:1000", "score", FALSE)) != NULL) slAddHead(&filters, filter); -if ((filter = bigBedMakeNumberFilter(cart, bbi, tg->tdb, SIGNAL_FILTER, NULL, "signalValue")) != NULL) +if ((filter = bigBedMakeNumberFilter(cart, bbi, tg->tdb, SIGNAL_FILTER, NULL, "signalValue", FALSE)) != NULL) slAddHead(&filters, filter); -if ((filter = bigBedMakeNumberFilter(cart, bbi, tg->tdb, PVALUE_FILTER, NULL, "pValue")) != NULL) +if ((filter = bigBedMakeNumberFilter(cart, bbi, tg->tdb, PVALUE_FILTER, NULL, "pValue", FALSE)) != NULL) slAddHead(&filters, filter); -if ((filter = bigBedMakeNumberFilter(cart, bbi, tg->tdb, QVALUE_FILTER, NULL, "qValue")) != NULL) +if ((filter = bigBedMakeNumberFilter(cart, bbi, tg->tdb, QVALUE_FILTER, NULL, "qValue", FALSE)) != NULL) slAddHead(&filters, filter); if (compositeChildHideEmptySubtracks(cart, tg->tdb, NULL, NULL)) labelTrackAsFiltered(tg); unsigned filtered = 0; for (bb = bbList; bb != NULL; bb = bb->next) { bigBedIntervalToRow(bb, chromName, startBuf, endBuf, bedRow, ArraySize(bedRow)); if (bigBedFilterInterval(bbi, bedRow, filters)) { struct encodePeak *peak = encodePeakGeneralLoad(bedRow, pt); struct linkedFeatures *lf = lfFromEncodePeak((struct slList *)peak, tg->tdb, scoreMin, scoreMax); if (lf) slAddHead(&lfList, lf); else filtered++; } else filtered++; } if (filtered) labelTrackAsFilteredNumber(tg, filtered); slReverse(&lfList); slSort(&lfList, linkedFeaturesCmp); tg->items = lfList; } static void encodePeakLoadItemsBoth(struct track *tg, struct customTrack *ct) /* Load up an encodePeak table from the regular database or the customTrash one. */ { char *db, *table; struct sqlConnection *conn; struct sqlResult *sr = NULL; char **row; char *filterConstraints = NULL; int rowOffset; struct linkedFeatures *lfList = NULL; enum encodePeakType pt = 0; int scoreMin = atoi(trackDbSettingClosestToHomeOrDefault(tg->tdb, "scoreMin", "0")); int scoreMax = atoi(trackDbSettingClosestToHomeOrDefault(tg->tdb, "scoreMax", "1000")); if (ct) { db = CUSTOM_TRASH; table = ct->dbTableName; } else { db = database; table = tg->tdb->table; } conn = hAllocConn(db); pt = encodePeakInferTypeFromTable(db, table, tg->tdb->type); tg->customInt = pt; filterConstraints = encodePeakFilter(tg->tdb->track, tg->tdb, (ct!=NULL)); sr = hRangeQuery(conn, table, chromName, winStart, winEnd, filterConstraints, &rowOffset); while ((row = sqlNextRow(sr)) != NULL) { struct encodePeak *peak = encodePeakGeneralLoad(row + rowOffset, pt); struct linkedFeatures *lf = lfFromEncodePeak((struct slList *)peak, tg->tdb, scoreMin, scoreMax); if (lf) slAddHead(&lfList, lf); } sqlFreeResult(&sr); hFreeConn(&conn); slReverse(&lfList); slSort(&lfList, linkedFeaturesCmp); tg->items = lfList; } static void encodePeakLoadItemsNormal(struct track *tg) /* Load the encodePeak table form the database. */ { encodePeakLoadItemsBoth(tg, NULL); } static void encodePeakLoadItemsCt(struct track *tg) /* Load the encodePeak table form the customTrash database. */ { struct customTrack *ct = tg->customPt; encodePeakLoadItemsBoth(tg, ct); } static void encodePeakDrawAt(struct track *tg, void *item, struct hvGfx *hvg, int xOff, int y, double scale, MgFont *font, Color color, enum trackVisibility vis) /* Draw the peak from the linkedFeature. Currently this doesn't draw any */ /* sorta shading based on the signalValue/pValue. */ { struct linkedFeatures *lf = item; int heightPer = tg->heightPer; int shortOff = heightPer/4; int shortHeight = heightPer - 2*shortOff; char *exonArrows = trackDbSettingClosestToHomeOrDefault(tg->tdb, "exonArrows", "off"); boolean drawArrows = FALSE; if ((exonArrows != NULL) && sameString(exonArrows, "on")) drawArrows = TRUE; Color rangeColor = shadesOfGray[lf->grayIx]; Color peakColor = (tg->ixColor != blackIndex()) ? tg->ixColor : getOrangeColor(); if (drawArrows || lf->tallStart == 0) { shortOff = 0; shortHeight = heightPer; } if (lf->components) { struct simpleFeature *sf; drawScaledBox(hvg, lf->start, lf->end, scale, xOff, y+(heightPer/2), 1, rangeColor); for (sf = lf->components; sf != NULL; sf = sf->next) { drawScaledBox(hvg, sf->start, sf->end, scale, xOff, y+shortOff, shortHeight, rangeColor); if (drawArrows) { int x1 = round((double)(sf->start-winStart)*scale) + xOff; int x2 = round((double)(sf->end-winStart)*scale) + xOff; int w = x2-x1; if (w < 1) w = 1; clippedBarbs(hvg, x1, y + heightPer/2, w, tl.barbHeight, tl.barbSpacing, lf->orientation, MG_WHITE, FALSE); } } } else drawScaledBox(hvg, lf->start, lf->end, scale, xOff, y+shortOff, shortHeight, rangeColor); if ((lf->tallEnd > 0) && (lf->tallStart < lf->end)) drawScaledBox(hvg, lf->tallStart, lf->tallEnd, scale, xOff, y, heightPer, peakColor); } char *encodePeakItemName(struct track *tg, void *item) /* Get rid of the '.' names */ { struct linkedFeatures *lf = item; if (lf->name && sameString(lf->name, ".")) return ""; else return lf->name; } void encodePeakMethods(struct track *tg) /* Methods for ENCODE peak track uses mostly linkedFeatures. */ { linkedFeaturesMethods(tg); tg->loadItems = encodePeakLoadItemsNormal; tg->drawItemAt = encodePeakDrawAt; tg->nextPrevItem = linkedFeaturesLabelNextPrevItem; tg->itemName = encodePeakItemName; tg->canPack = TRUE; } void encodePeakMethodsCt(struct track *tg) /* Methods for ENCODE peak track uses mostly linkedFeatures. */ { encodePeakMethods(tg); tg->loadItems = encodePeakLoadItemsCt; }