957f2123050742982ef6c7aefcab70d29144924c braney Mon Oct 9 17:49:04 2017 -0700 allow bedGraph. Change names in collections so they don't match names in trackDb, move the copying of custom tracks and collections to BEFORE the load of trackHubs, misc other bugs diff --git src/hg/hgTracks/bedGraph.c src/hg/hgTracks/bedGraph.c index d53a51b..4df6942 100644 --- src/hg/hgTracks/bedGraph.c +++ src/hg/hgTracks/bedGraph.c @@ -1,297 +1,303 @@ /* bedGraph - stuff to handle loading and display of * bedGraph type tracks in browser. Will be graphing a specified * column of a bed file. */ /* Copyright (C) 2011 The Regents of the University of California * See README in this or parent directory for licensing information. */ #include "common.h" #include "hash.h" #include "linefile.h" #include "jksql.h" #include "hdb.h" #include "hgTracks.h" #include "wiggle.h" #include "scoredRef.h" #include "customTrack.h" #include "wigCommon.h" /* The item names have been massaged during the Load. An * individual item may have been read in on multiple table rows and * had an extension on it to make it unique from the others. Also, * each different zoom level had a different extension name. * All these names were condensed into the root of the name with * the extensions removed. */ static char *bedGraphName(struct track *tg, void *item) /* Return name of bedGraph level track. */ { struct bedGraphItem *bg = item; return bg->name; } void ctBedGraphLoadItems(struct track *tg) { /* load custom bedGraph track data */ /* Verify this is a custom track */ if (! (isCustomTrack(tg->table) && tg->customPt)) errAbort("ctBedGraphLoadItems: did not find a custom wiggle track: %s", tg->track); errAbort("custom track bedGraph load items not yet implemented"); } /* bedGraphLoadItems - an ordinary bed load, but we are interested * in only the chrom, start, end, and the graphColumn */ static void bedGraphLoadItems(struct track *tg) { struct sqlConnection *conn; struct sqlResult *sr = (struct sqlResult *) NULL; char **row = (char **)NULL; int rowOffset = 0; struct bedGraphItem *bgList = NULL; int itemsLoaded = 0; int colCount = 0; struct wigCartOptions *wigCart = (struct wigCartOptions *) tg->wigCartData; int graphColumn = 5; char *tableName; if(sameString(tg->table, "affyTranscription")) wigCart->colorTrack = "affyTransfrags"; graphColumn = wigCart->graphColumn; #ifndef GBROWSE if (isCustomTrack(tg->table) && tg->customPt) { struct customTrack *ct = (struct customTrack *) tg->customPt; tableName = ct->dbTableName; conn = hAllocConn(CUSTOM_TRASH); } +else if (isCustomTrack(tg->table) ) + { + // we can get custom tracks through track hubs that don't have customPt + conn = hAllocConn(CUSTOM_TRASH); + tableName = trackDbSetting(tg->tdb, "dbTableName"); + } else #endif /* GBROWSE */ { tableName = tg->table; conn = hAllocConnTrack(database, tg->tdb); } sr = hRangeQuery(conn, tableName, chromName, winStart, winEnd, NULL, &rowOffset); colCount = sqlCountColumns(sr) - rowOffset; /* Must have at least four good columns */ if (colCount < 4) errAbort("bedGraphLoadItems: table %s only has %d data columns, must be at least 4", tableName, colCount); if (colCount < graphColumn) errAbort("bedGraphLoadItems: table %s only has %d data columns, specified graph column %d does not exist", tableName, colCount, graphColumn); /* before loop, determine actual row[graphColumn] index */ graphColumn += (rowOffset - 1); while ((row = sqlNextRow(sr)) != NULL) { struct bedGraphItem *bg; struct bed *bed; ++itemsLoaded; /* load chrom, start, end */ bed = bedLoadN(row+rowOffset, 3); AllocVar(bg); bg->start = bed->chromStart; bg->end = bed->chromEnd; if ((colCount > 4) && ((graphColumn + rowOffset) != 4)) bg->name = cloneString(row[3+rowOffset]); else { char name[128]; safef(name,ArraySize(name),"%s.%d", bed->chrom, itemsLoaded); bg->name = cloneString(name); } bg->dataValue = sqlFloat(row[graphColumn]); /* filled in by DrawItems */ bg->graphUpperLimit = wigEncodeStartingUpperLimit; bg->graphLowerLimit = wigEncodeStartingLowerLimit; slAddHead(&bgList, bg); bedFree(&bed); } sqlFreeResult(&sr); hFreeConn(&conn); slReverse(&bgList); tg->items = bgList; } /* bedGraphLoadItems() */ static void bedGraphFreeItems(struct track *tg) { #if defined(DEBUG) snprintf(dbgMsg, DBGMSGSZ, "I haven't seen bedGraphFreeItems ever called ?"); wigDebugPrint("bedGraphFreeItems"); #endif } struct preDrawContainer *bedGraphLoadPreDraw(struct track *tg, int seqStart, int seqEnd, int width) /* Do bits that load the predraw buffer tg->preDrawContainer. */ { /* Just need to do this once... */ if (tg->preDrawContainer) return tg->preDrawContainer; struct bedGraphItem *wi; double pixelsPerBase = scaleForPixels(width); int i; /* an integer loop counter */ /* Allocate predraw and save it and related info in the track. */ struct preDrawContainer *pre = tg->preDrawContainer = initPreDrawContainer(width); struct preDrawElement *preDraw = pre->preDraw; /* to accumulate everything in prep for draw */ int preDrawZero = pre->preDrawZero; /* location in preDraw where screen starts */ int preDrawSize = pre->preDrawSize; /* size of preDraw array */ /* walk through all the data fill in the preDraw array */ for (wi = tg->items; wi != NULL; wi = wi->next) { double dataValue = wi->dataValue; /* the data value to graph */ /* Ready to draw, what do we know: * the feature being processed: * chrom coords: [wi->start : wi->end) * its data value: dataValue = wi->dataValue * * The drawing window, in pixels: * xOff = left margin, yOff = top margin, h = height of drawing window * drawing window in chrom coords: seqStart, seqEnd * 'pixelsPerBase' is known */ /* let's check end point screen coordinates. If they are * the same, then this entire data block lands on one pixel, * It is OK if these end up + or -, we do want to * keep track of pixels before and after the screen for * later smoothing operations */ int x1 = (wi->start - seqStart) * pixelsPerBase; int x2 = (wi->end - seqStart) * pixelsPerBase; if (x2 > x1) { for (i = x1; i <= x2; ++i) { int xCoord = preDrawZero + i; if ((xCoord >= 0) && (xCoord < preDrawSize)) { ++preDraw[xCoord].count; if (dataValue > preDraw[xCoord].max) preDraw[xCoord].max = dataValue; if (dataValue < preDraw[xCoord].min) preDraw[xCoord].min = dataValue; preDraw[xCoord].sumData += dataValue; preDraw[xCoord].sumSquares += dataValue * dataValue; } } } else { /* only one pixel for this block of data */ int xCoord = preDrawZero + x1; /* if the point falls within our array, record it. * the (wi->validCount > 0) is a safety check. It * should always be true unless the data was * prepared incorrectly. */ if ((xCoord >= 0) && (xCoord < preDrawSize)) { ++preDraw[xCoord].count; if (dataValue > preDraw[xCoord].max) preDraw[xCoord].max = dataValue; if (dataValue < preDraw[xCoord].min) preDraw[xCoord].min = dataValue; preDraw[xCoord].sumData += dataValue; preDraw[xCoord].sumSquares += dataValue * dataValue; } } } /* for (wi = tg->items; wi != NULL; wi = wi->next) */ return pre; } static void bedGraphPreDrawItems(struct track *tg, int seqStart, int seqEnd, struct hvGfx *hvg, int xOff, int yOff, int width, MgFont *font, Color color, enum trackVisibility vis) { struct preDrawContainer *pre = bedGraphLoadPreDraw(tg, seqStart, seqEnd, width); if (pre != NULL) { wigPreDrawPredraw(tg, seqStart, seqEnd, hvg, xOff, yOff, width, font, color, vis, pre, pre->preDrawZero, pre->preDrawSize, &tg->graphUpperLimit, &tg->graphLowerLimit); } } static void bedGraphDrawItems(struct track *tg, int seqStart, int seqEnd, struct hvGfx *hvg, int xOff, int yOff, int width, MgFont *font, Color color, enum trackVisibility vis) { struct preDrawContainer *pre = tg->preDrawContainer; if (pre != NULL) { wigDrawPredraw(tg, seqStart, seqEnd, hvg, xOff, yOff, width, font, color, vis, pre, pre->preDrawZero, pre->preDrawSize, tg->graphUpperLimit, tg->graphLowerLimit); } } /* * WARNING ! - track->visibility is merely the default value * from the trackDb entry at this time. It will be set after this * by hgTracks from its cart UI setting. When called in * TotalHeight it will then be the requested visibility. */ void bedGraphMethods(struct track *track, struct trackDb *tdb, int wordCount, char *words[]) { struct wigCartOptions *wigCart = wigCartOptionsNew(cart, tdb, wordCount, words); wigCart->bedGraph = TRUE; /* signal to left labels */ switch (wordCount) { case 2: wigCart->graphColumn = atoi(words[1]); /* protect against nonsense values */ if ( (wigCart->graphColumn < 2) || (wigCart->graphColumn > 100) ) wigCart->graphColumn = 5; /* default score column */ break; default: wigCart->graphColumn = 5; /* default score column */ break; } track->minRange = wigCart->minY; track->maxRange = wigCart->maxY; track->graphUpperLimit = wigEncodeStartingUpperLimit; track->graphLowerLimit = wigEncodeStartingLowerLimit; track->loadItems = bedGraphLoadItems; track->freeItems = bedGraphFreeItems; track->preDrawItems = bedGraphPreDrawItems; track->preDrawMultiRegion = wigMultiRegionGraphLimits; track->drawItems = bedGraphDrawItems; track->itemName = bedGraphName; track->mapItemName = bedGraphName; track->totalHeight = wigTotalHeight; track->itemHeight = tgFixedItemHeight; track->itemStart = tgItemNoStart; track->itemEnd = tgItemNoEnd; track->mapsSelf = TRUE; track->wigCartData = (void *) wigCart; track->colorShades = shadesOfGray; track->drawLeftLabels = wigLeftLabels; track->loadPreDraw = bedGraphLoadPreDraw; /* the lfSubSample type makes the image map function correctly */ track->subType = lfSubSample; /*make subType be "sample" (=2)*/ } /* bedGraphMethods() */