007cb48e6924935c046a7a0d0354eeac84e5f6cb angie Wed Oct 5 11:30:12 2011 -0700 Feature #3710 (vcfTabix UI options): added filtering by value of FILTER column. diff --git src/hg/hgTracks/vcfTrack.c src/hg/hgTracks/vcfTrack.c index 944cedc..e66ff4a 100644 --- src/hg/hgTracks/vcfTrack.c +++ src/hg/hgTracks/vcfTrack.c @@ -6,39 +6,68 @@ #include "errCatch.h" #include "hacTree.h" #include "hdb.h" #include "hgTracks.h" #include "pgSnp.h" #include "trashDir.h" #include "vcf.h" #include "vcfUi.h" #if (defined USE_TABIX && defined KNETFILE_HOOKS) #include "knetUdc.h" #include "udc.h" #endif//def USE_TABIX && KNETFILE_HOOKS #ifdef USE_TABIX -static struct pgSnp *vcfFileToPgSnp(struct vcfFile *vcff) +static boolean getFilterValues(struct trackDb *tdb, struct slName **retValues) +/* Return TRUE and set retValues if cart contains FILTER column values to exclude */ +{ +char cartVar[512]; +safef(cartVar, sizeof(cartVar), "%s.exclude_filterColumn", tdb->track); +if (cartListVarExists(cart, cartVar)) + { + struct slName *selectedValues = cartOptionalSlNameList(cart, cartVar); + if (retValues != NULL) + *retValues = selectedValues; + 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 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++) { @@ -750,31 +779,31 @@ 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) { if (hapClustEnabled && vcff->genotypeCount > 1 && vcff->genotypeCount < 3000 && (tg->visibility == tvPack || tg->visibility == tvSquish)) vcfHapClusterOverloadMethods(tg, vcff); else { - tg->items = vcfFileToPgSnp(vcff); + 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) { if (isNotEmpty(errCatch->message->string)) tg->networkErrMsg = cloneString(errCatch->message->string); tg->drawItems = bigDrawWarning; tg->totalHeight = bigWarnTotalHeight; } errCatchFree(&errCatch);