Index: src/hg/hgTracks/bamTrack.c
===================================================================
RCS file: /projects/compbio/cvsroot/kent/src/hg/hgTracks/bamTrack.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -b -B -U 4 -r1.7 -r1.8
--- src/hg/hgTracks/bamTrack.c	25 Aug 2009 06:04:05 -0000	1.7
+++ src/hg/hgTracks/bamTrack.c	8 Sep 2009 21:39:38 -0000	1.8
@@ -17,8 +17,9 @@
 struct bamTrackData
     {
     struct track *tg;
     struct hash *pairHash;
+    int minAliQual;
     };
 
 struct simpleFeature *sfFromNumericCigar(const bam1_t *bam, int *retLength)
 /* Translate BAM's numeric CIGAR encoding into a list of simpleFeatures, 
@@ -78,20 +79,34 @@
 lf->components = sfFromNumericCigar(bam, &length);
 lf->start = lf->tallStart = core->pos;
 lf->end = lf->tallEnd = core->pos + length;
 lf->extra = bamGetQuerySequence(bam);
+lf->grayIx = maxShade;
 return lf;
 }
 
+boolean passesFilters(const bam1_t *bam, struct bamTrackData *btd)
+/* Return TRUE if bam passes hgTrackUi-set filters. */
+{
+if (bam == NULL)
+    return FALSE;
+const bam1_core_t *core = &bam->core;
+// Always reject unmapped items -- nowhere to draw them.
+if (core->flag & BAM_FUNMAP)
+    return FALSE;
+if (core->qual < btd->minAliQual)
+    return FALSE;
+return TRUE;
+}
+
 int addBam(const bam1_t *bam, void *data)
 /* bam_fetch() calls this on each bam alignment retrieved.  Translate each bam 
  * into a linkedFeatures item, and add it to tg->items. */
 {
-const bam1_core_t *core = &bam->core;
-if (core->flag & BAM_FUNMAP)
+struct bamTrackData *btd = (struct bamTrackData *)data;
+if (!passesFilters(bam, btd))
     return 0;
 struct linkedFeatures *lf = bamToLf(bam, data);
-struct bamTrackData *btd = (struct bamTrackData *)data;
 struct track *tg = btd->tg;
 slAddHead(&(tg->items), lf);
 return 0;
 }
@@ -108,8 +123,9 @@
 AllocVar(sf);
 sf->start = sf->end = lf->start = lf->end = lf->tallStart = lf->tallEnd = startEnd;
 lf->components = sf;
 lf->extra = cloneString("");
+lf->grayIx = maxShade;
 return lf;
 }
 
 static struct linkedFeaturesSeries *lfsFromLf(struct linkedFeatures *lf)
@@ -133,12 +149,12 @@
  * into a linkedFeaturesSeries item, and either store it until we find its mate
  * or add it to tg->items. */
 {
 const bam1_core_t *core = &bam->core;
-if (core->flag & BAM_FUNMAP)
+struct bamTrackData *btd = (struct bamTrackData *)data;
+if (! passesFilters(bam, btd))
     return 0;
 struct linkedFeatures *lf = bamToLf(bam, data);
-struct bamTrackData *btd = (struct bamTrackData *)data;
 struct track *tg = btd->tg;
 if (! (core->flag & BAM_FPAIRED))
     {
     slAddHead(&(tg->items), lfsFromLf(lf));
@@ -147,24 +163,30 @@
     {
     struct linkedFeatures *lfMate = (struct linkedFeatures *)hashFindVal(btd->pairHash, lf->name);
     if (lfMate == NULL)
 	{
-	if (core->flag & BAM_FPROPER_PAIR && core->mpos < 0)
+	if (core->flag & BAM_FPROPER_PAIR)
 	    {
-	    // If we know that this is properly paired, but don't know where its mate
-	    // is, make a bogus item off the edge of the window so that if we don't
+	    // If we know that this is properly paired, but don't have the mate,
+	    // make a bogus item off the edge of the window so that if we don't
 	    // encounter its mate later, we can at least draw an arrow off the
 	    // edge of the window.
+	    struct linkedFeatures *stub;
+	    if (core->mpos < 0)
+		{
 	    int offscreen = (lf->orientation > 0) ? winEnd + 10 : winStart - 10;
 	    if (offscreen < 0) offscreen = 0;
-	    struct linkedFeatures *stub = lfStub(offscreen, -lf->orientation);
-	    lf->next = stub;
+		stub = lfStub(offscreen, -lf->orientation);
 	    }
-	else if (! (core->flag & BAM_FPROPER_PAIR))
+	    else
 	    {
-	    // TODO: find a way to make this a lighter shade.
-	    // doesn't work: lf->grayIx += 2;
+		stub = lfStub(core->mpos, -lf->orientation);
+		}
+	    lf->next = stub;
 	    }
+	else
+	    // not properly paired: make it a lighter shade.
+	    lf->grayIx -= 2;
 	hashAdd(btd->pairHash, lf->name, lf);
 	}
     else
 	{
@@ -195,9 +217,12 @@
 char posForBam[512];
 safef(posForBam, sizeof(posForBam), "%s:%d-%d", seqNameForBam, winStart, winEnd);
 
 struct hash *pairHash = isPaired ? hashNew(18) : NULL;
-struct bamTrackData btd = {tg, pairHash};
+char cartVarName[512];
+safef(cartVarName, sizeof(cartVarName), "%s_minAliQual", tg->tdb->tableName);
+int minAliQual = cartUsualInt(cart, cartVarName, 0);
+struct bamTrackData btd = {tg, pairHash, minAliQual};
 bamFetch(database, tg->mapName, posForBam, (isPaired ? addBamPaired : addBam), &btd);
 if (isPaired)
     {
     struct hashEl *hel;
@@ -253,7 +278,8 @@
     }
 track->labelNextItemButtonable = track->nextItemButtonable = FALSE;
 track->labelNextPrevItem = NULL;
 track->nextPrevItem = NULL;
+track->colorShades = shadesOfGray;
 }
 
 #endif /* USE_BAM */

