725da8e0b151e80ec2c9e123971431129c339c17
angie
  Wed Oct 5 13:46:01 2011 -0700
Filter VCF items at load time so they apply to haplotype sorting mode too (oops).
diff --git src/hg/hgTracks/vcfTrack.c src/hg/hgTracks/vcfTrack.c
index e66ff4a..8617c79 100644
--- src/hg/hgTracks/vcfTrack.c
+++ src/hg/hgTracks/vcfTrack.c
@@ -31,43 +31,58 @@
     return TRUE;
     }
 return FALSE;
 }
 
 static boolean excludeRecord(struct vcfRecord *record, struct slName *filterValues)
 /* Return TRUE if record's FILTER column value(s) matches one of filterValues (from cart). */
 {
 int i;
 for (i = 0;  i < record->filterCount;  i++)
     if (slNameInList(filterValues, record->filters[i]))
 	return TRUE;
 return FALSE;
 }
 
+static void filterRecords(struct vcfFile *vcff, struct trackDb *tdb)
+/* If a filter is specified in the cart, remove any records that don't pass filter. */
+{
+struct slName *filterValues = NULL;
+boolean gotFilter = getFilterValues(tdb, &filterValues);
+if (!gotFilter)
+    return;
+
+struct vcfRecord *rec, *nextRec, *newList = NULL;
+for (rec = vcff->records;  rec != NULL;  rec = nextRec)
+    {
+    nextRec = rec->next;
+    if (!excludeRecord(rec, filterValues))
+	slAddHead(&newList, rec);
+    }
+slReverse(&newList);
+vcff->records = newList;
+}
+
 static struct pgSnp *vcfFileToPgSnp(struct vcfFile *vcff, struct trackDb *tdb)
 /* Convert vcff's records to pgSnp; don't free vcff until you're done with pgSnp
  * because it contains pointers into vcff's records' chrom. */
 {
 struct pgSnp *pgsList = NULL;
 struct vcfRecord *rec;
 int maxLen = 33;
-struct slName *filterValues = NULL;
-boolean gotFilter = getFilterValues(tdb, &filterValues);
 for (rec = vcff->records;  rec != NULL;  rec = rec->next)
     {
-    if (gotFilter && excludeRecord(rec, filterValues))
-	continue;
     struct pgSnp *pgs = pgSnpFromVcfRecord(rec);
     // Insertion sequences can be quite long; abbreviate here for display.
     int len = strlen(pgs->name);
     if (len > maxLen)
 	{
 	if (strchr(pgs->name, '/') != NULL)
 	    {
 	    char *copy = cloneString(pgs->name);
 	    char *allele[8];
 	    int cnt = chopByChar(copy, '/', allele, pgs->alleleCount);
 	    int maxAlLen = maxLen / pgs->alleleCount;
 	    pgs->name[0] = '\0';
 	    int i;
 	    for (i = 0;  i < cnt;  i++)
 		{
@@ -774,30 +789,31 @@
     fileOrUrl = bbiNameFromSettingOrTable(tg->tdb, conn, tg->table);
     hFreeConn(&conn);
     }
 int vcfMaxErr = -1;
 struct vcfFile *vcff = NULL;
 boolean compositeLevel = isNameAtCompositeLevel(tg->tdb, tg->tdb->track);
 boolean hapClustEnabled = cartUsualBooleanClosestToHome(cart, tg->tdb, compositeLevel,
 							VCF_HAP_ENABLED_VAR, TRUE);
 /* protect against temporary network error */
 struct errCatch *errCatch = errCatchNew();
 if (errCatchStart(errCatch))
     {
     vcff = vcfTabixFileMayOpen(fileOrUrl, chromName, winStart, winEnd, vcfMaxErr);
     if (vcff != NULL)
 	{
+	filterRecords(vcff, tg->tdb);
 	if (hapClustEnabled && vcff->genotypeCount > 1 && vcff->genotypeCount < 3000 &&
 	    (tg->visibility == tvPack || tg->visibility == tvSquish))
 	    vcfHapClusterOverloadMethods(tg, vcff);
 	else
 	    {
 	    tg->items = vcfFileToPgSnp(vcff, tg->tdb);
 	    // pgSnp bases coloring/display decision on count of items:
 	    tg->customInt = slCount(tg->items);
 	    }
 	// Don't vcfFileFree here -- we are using its string pointers!
 	}
     }
 errCatchEnd(errCatch);
 if (errCatch->gotError || vcff == NULL)
     {