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; i<width; ++i)
+    {
+    struct preDrawElement *pe = &bwData->preDraw[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");