7285e559ae48d7db239fb9161931f6d2934230bc braney Wed Sep 24 10:26:02 2014 -0700 add maf SNP view to maf display diff --git src/hg/hgTracks/wigMafTrack.c src/hg/hgTracks/wigMafTrack.c index 90459ae..c71ec27 100644 --- src/hg/hgTracks/wigMafTrack.c +++ src/hg/hgTracks/wigMafTrack.c @@ -9,30 +9,31 @@ #include "hash.h" #include "linefile.h" #include "jksql.h" #include "hdb.h" #include "hgTracks.h" #include "maf.h" #include "scoredRef.h" #include "wiggle.h" #include "hCommon.h" #include "hgMaf.h" #include "mafTrack.h" #include "customTrack.h" #include "mafSummary.h" #include "mafFrames.h" #include "phyloTree.h" +#include "soTerm.h" #define GAP_ITEM_LABEL "Gaps" #define MAX_SP_SIZE 2000 struct wigMafItem /* A maf track item -- * a line of bases (base level) or pairwise density gradient (zoomed out). */ { struct wigMafItem *next; char *name; /* Common name */ char *db; /* Database */ int group; /* number of species group/clade */ int ix; /* Position in list. */ int height; /* Pixel height of item. */ @@ -498,32 +499,37 @@ { return mi->ix != -1; } static struct wigMafItem *loadPairwiseItems(struct track *track) /* Make up items for modes where pairwise data are shown. First an item for the score wiggle, then a pairwise item for each "other species" in the multiple alignment. These may be density plots (pack) or wiggles (full). Return item list. Also set customPt with mafList if zoomed in */ { struct wigMafItem *miList = NULL, *speciesItems = NULL, *mi; struct track *wigTrack = track->subtracks; int scoreHeight = tl.fontHeight * 4; +char *snpTable = trackDbSetting(track->tdb, "snpTable"); +boolean doSnpTable = FALSE; +if ( (track->limitedVis == tvPack) && (snpTable != NULL)) + doSnpTable = TRUE; -if (winBaseCount < MAF_SUMMARY_VIEW) +// the maf's only get loaded if we're not in summary or snpTable views +if (!doSnpTable && (winBaseCount < MAF_SUMMARY_VIEW)) { /* "close in" display uses actual alignments from file */ struct mafPriv *mp = getMafPriv(track); struct sqlConnection *conn, *conn2; if (mp->ct) { char *fileName = getCustomMafFile(track); conn = hAllocConn(CUSTOM_TRASH); conn2 = hAllocConn(CUSTOM_TRASH); mp->list = wigMafLoadInRegion(conn, conn2, mp->ct->dbTableName, chromName, winStart, winEnd, fileName); hFreeConn(&conn); hFreeConn(&conn2); } @@ -991,30 +997,145 @@ int height, int seqStart, int seqEnd, struct hvGfx *hvg, int xOff, int yOff, int width, MgFont *font, Color color, Color altColor, enum trackVisibility vis) { struct sqlConnection *conn = hAllocConn(CUSTOM_TRASH); drawScoreOverviewC(conn, tableName, height, seqStart, seqEnd, hvg, xOff, yOff, width, font, color, altColor, vis); hFreeConn(&conn); } +static boolean drawPairsFromSnpTable(struct track *track, + char *snpTable, + int seqStart, int seqEnd, + struct hvGfx *hvg, int xOff, int yOff, int width, MgFont *font, + Color color, enum trackVisibility vis) +/* use trackDb variable "snpTable" bed to draw this mode */ +{ +struct wigMafItem *miList = track->items, *mi = miList; +struct sqlConnection *conn; +struct sqlResult *sr = NULL; +char **row = NULL; +int rowOffset = 0; +struct hash *componentHash = newHash(6); +struct hashEl *hel; +struct dyString *where = dyStringNew(256); +char *whereClause = NULL; + +if (miList == NULL) + return FALSE; + +if (snpTable == NULL) + return FALSE; + +/* Create SQL where clause that will load up just the + * beds for the species that we are including. */ +conn = hAllocConn(database); +dyStringAppend(where, "name in ("); +for (mi = miList; mi != NULL; mi = mi->next) + { + if (!isPairwiseItem(mi)) + /* exclude non-species items (e.g. conservation wiggle */ + continue; + dyStringPrintf(where, "'%s'", mi->db); + if (mi->next != NULL) + dyStringAppend(where, ","); + } +dyStringAppend(where, ")"); +/* check for empty where clause */ +if (!sameString(where->string,"name in ()")) + whereClause = where->string; +sr = hOrderedRangeQuery(conn, snpTable, chromName, seqStart, seqEnd, + whereClause, &rowOffset); + +/* Loop through result creating a hash of lists of beds . + * The hash is keyed by species. */ +while ((row = sqlNextRow(sr)) != NULL) + { + struct bed *bed = bedLoadN(&row[1], 5); + /* prune to fit in window bounds */ + if (bed->chromStart < seqStart) + bed->chromStart = seqStart; + if (bed->chromEnd > seqEnd) + bed->chromEnd = seqEnd; + if ((hel = hashLookup(componentHash, bed->name)) == NULL) + hashAdd(componentHash, bed->name, bed); + else + slAddHead(&(hel->val), bed); + } +sqlFreeResult(&sr); +hFreeConn(&conn); + +/* display pairwise items */ +Color yellow = hvGfxFindRgb(hvg, &undefinedYellowColor); +for (mi = miList; mi != NULL; mi = mi->next) + { + if (mi->ix < 0) + /* ignore item for the score */ + continue; + struct bed *bedList = (struct bed *)hashFindVal(componentHash, mi->db); + if (bedList == NULL) + bedList = (struct bed *)hashFindVal(componentHash, mi->name); + + if (bedList != NULL) + { + hvGfxSetClip(hvg, xOff, yOff, width, mi->height); + + struct bed *bed = bedList; + + double scale = scaleForPixels(width); + for(; bed; bed = bed->next) + { + int x1 = round((bed->chromStart - seqStart)*scale); + int x2 = round((bed->chromEnd - seqStart)*scale); + int w = x2-x1+1; + int height1 = mi->height-1; + int color = MG_BLACK; + switch(bed->score) + { + case 0: + color = yellow; + break; + case _5_prime_UTR_variant: + case _3_prime_UTR_variant: + case coding_sequence_variant: + case intron_variant: + case intergenic_variant: + color = MG_BLUE; + break; + case synonymous_variant: + color = MG_GREEN; + break; + case missense_variant: + color = MG_RED; + break; + } + hvGfxBox(hvg, x1 + xOff, yOff, w, height1, color); + + } + hvGfxUnclip(hvg); + } + yOff += mi->height; + } +return TRUE; +} + static boolean drawPairsFromSummary(struct track *track, int seqStart, int seqEnd, struct hvGfx *hvg, int xOff, int yOff, int width, MgFont *font, Color color, enum trackVisibility vis) { /* Draw pairwise display for this multiple alignment */ char *summary; struct wigMafItem *miList = track->items, *mi = miList; struct sqlConnection *conn; struct sqlResult *sr = NULL; char **row = NULL; int rowOffset = 0; struct mafSummary *ms, *summaryList; struct hash *componentHash = newHash(6); struct hashEl *hel; @@ -1347,33 +1468,38 @@ * When zoomed in, use on-the-fly scoring of alignments extracted from multiple * When zoomed out: * if "pairwise" setting is on, use pairwise tables (maf or wiggle) * <species>_<suffix> for maf, <species>_<suffix>_wig for wiggle * For full mode, display graph. * for pack mode, display density plot. * if "summary" setting is on, use maf summary table * (saves space, and performs better) */ { if (displayZoomedIn(track)) return drawPairsFromMultipleMaf(track, seqStart, seqEnd, hvg, xOff, yOff, width, font, color, vis); if (isCustomTrack(track->table) || pairwiseSuffix(track)) return drawPairsFromPairwiseMafScores(track, seqStart, seqEnd, hvg, xOff, yOff, width, font, color, vis); - if (summarySetting(track)) + if ((winBaseCount >= MAF_SUMMARY_VIEW) && summarySetting(track)) return drawPairsFromSummary(track, seqStart, seqEnd, hvg, xOff, yOff, width, font, color, vis); + char *snpTable = trackDbSetting(track->tdb, "snpTable"); + if ( (track->limitedVis == tvPack) && (snpTable != NULL)) + return drawPairsFromSnpTable(track, snpTable, seqStart, seqEnd, hvg, + xOff, yOff, width, font, color, vis); + return FALSE; } static void alternateBlocksBehindChars(struct hvGfx *hvg, int x, int y, int width, int height, int charWidth, int charCount, int stripeCharWidth, Color a, Color b) /* Draw blocks that alternate between color a and b. */ { int x1,x2 = x + width; int color = a; int i; for (i=0; i<charCount; i += stripeCharWidth) { x1 = i * width / charCount; x2 = (i+stripeCharWidth) * width/charCount;