dbf7b1ce3e172cf9f85fa2275c15368d27c0ff80 braney Tue Feb 15 14:13:37 2011 -0800 a complicated commit to support the arrows in decipher tracks, next item buttons on bigBeds, and the beginnings of BAM wiggles diff --git src/hg/hgTracks/bamTrack.c src/hg/hgTracks/bamTrack.c index 51be6f2..a8c2fa7 100644 --- src/hg/hgTracks/bamTrack.c +++ src/hg/hgTracks/bamTrack.c @@ -1,30 +1,31 @@ /* bamTrack -- handlers for alignments in BAM format (produced by MAQ, * BWA and some other short-read alignment tools). */ #ifdef USE_BAM #include "common.h" #include "hCommon.h" #include "hash.h" #include "linefile.h" #include "htmshell.h" #include "jksql.h" #include "hdb.h" #include "hgTracks.h" #include "cds.h" #include "bamFile.h" +#include "wigCommon.h" #if (defined USE_BAM && defined KNETFILE_HOOKS) #include "knetUdc.h" #include "udc.h" #endif//def USE_BAM && KNETFILE_HOOKS static char const rcsid[] = "$Id: bamTrack.c,v 1.32 2010/05/27 21:13:24 angie Exp $"; struct bamTrackData { struct track *tg; struct hash *pairHash; int minAliQual; char *colorMode; char *grayMode; char *userTag; @@ -762,30 +763,145 @@ track->drawItemAt = bamDrawAt; } if (!showNames) { track->drawName = TRUE; // ironic, but this is how to suppress item labels in pack mode. track->drawLeftLabels = maybeDrawLeftLabels; } track->nextItemButtonable = track->nextExonButtonable = FALSE; track->nextPrevItem = NULL; track->nextPrevExon = NULL; if (differentString(colorMode, "off")) track->colorShades = shadesOfGray; } +struct bamWigTrackData +{ +struct preDrawElement *preDraw; +double scale; +int width; +int preDrawZero; +}; + +static void bamWigLoadItems(struct track *tg) +{ +/* Figure out bigWig file name. */ +struct sqlConnection *conn = hAllocConnTrack(database, tg->tdb); +char *fileName = bbiNameFromSettingOrTable(tg->tdb, conn, tg->table); +tg->customPt = fileName; +hFreeConn(&conn); +} + +static int countBam(const bam1_t *bam, void *data) +/* bam_fetch() calls this on each bam alignment retrieved. */ +{ +struct bamWigTrackData *btd = (struct bamWigTrackData *)data; +const bam1_core_t *core = &bam->core; + +int tLength=0, tPos = core->pos, qPos = 0; +unsigned int *cigar = bam1_cigar(bam); +int i; +double scale = btd->scale; +for (i = 0; i < core->n_cigar; i++) + { + char op; + int n = bamUnpackCigarElement(cigar[i], &op); + switch (op) + { + case 'M': // match or mismatch (gapless aligned block) + { + int start = (int)(scale * (tPos - winStart)); + int end = (int)(scale * ((tPos + n) - winStart)); + for(i=start; i < end; i++) + btd->preDraw[i + btd->preDrawZero].count++; + tPos = tPos + n; + qPos = qPos + n; + tLength += n; + break; + } + case 'I': // inserted in query + qPos += n; + break; + case 'D': // deleted from query + case 'N': // long deletion from query (intron as opposed to small del) + tPos += n; + tLength += n; + break; + case 'S': // skipped query bases at beginning or end ("soft clipping") + case 'H': // skipped query bases not stored in record's query sequence ("hard clipping") + case 'P': // P="silent deletion from padded reference sequence" -- ignore these. + break; + default: + errAbort("countBam: unrecognized CIGAR op %c -- update me", op); + } + + } +return 0; +} + +static void bamWigDrawItems(struct track *tg, int seqStart, int seqEnd, + struct hvGfx *hvg, int xOff, int yOff, int width, + MgFont *font, Color color, enum trackVisibility vis) +{ +/* Allocate predraw area. */ +int preDrawZero, preDrawSize; +struct preDrawContainer *preDrawList = NULL; +struct bamWigTrackData *bwData; +double scale = (double)width/(winEnd - winStart); + +AllocVar(bwData); +bwData->preDraw = initPreDraw(width, &preDrawSize, &preDrawZero); +bwData->scale = scale; +bwData->width = width; +bwData->preDrawZero = preDrawZero; + +char posForBam[512]; +safef(posForBam, sizeof(posForBam), "%s:%d-%d", chromName, winStart, winEnd); + +char *fileName = tg->customPt; +tg->customPt = NULL; + +bamFetch(fileName, posForBam, countBam, bwData, NULL); + +/* fill in rest of predraw */ +int i; +for (i=0; ipreDraw[i + preDrawZero]; + pe->min = pe->count; + pe->max = pe->count; + pe->sumData = pe->count; + pe->sumSquares = pe->count * pe->count; + } + +AllocVar(preDrawList); +preDrawList->preDraw = bwData->preDraw; +/* Call actual graphing routine. */ +wigDrawPredraw(tg, seqStart, seqEnd, hvg, xOff, yOff, width, font, color, vis, + preDrawList, preDrawZero, preDrawSize, &tg->graphUpperLimit, &tg->graphLowerLimit); + +} + +void bamWigMethods(struct track *track, struct trackDb *tdb, + int wordCount, char *words[]) +/* Set up bamWig methods. */ +{ +bedGraphMethods(track, tdb, wordCount, words); +track->loadItems = bamWigLoadItems; +track->drawItems = bamWigDrawItems; +} #else /* no USE_BAM */ #include "common.h" #include "hgTracks.h" // If code was not built with USE_BAM=1, but there are bam tracks, display a message // in place of the tracks (instead of annoying "No track handler" warning messages). void drawUseBamWarning(struct track *tg, int seqStart, int seqEnd, struct hvGfx *hvg, int xOff, int yOff, int width, MgFont *font, Color color, enum trackVisibility vis) /* Draw a message saying that the code needs to be built with USE_BAM=1. */ { char message[512]; safef(message, sizeof(message), "Get samtools(.sourceforge.net) and recompile kent/src with USE_BAM=1");