7a16880260a6d93d0616bd8a1660fde60ac0bb3b chmalee Fri May 22 16:13:56 2020 -0700 Use cart*ClosestToHome functions for setting trackUi vars so composite level track settings work correctly, refs #25585 diff --git src/hg/hgTracks/vcfTrack.c src/hg/hgTracks/vcfTrack.c index a4a9ed8..799787f 100644 --- src/hg/hgTracks/vcfTrack.c +++ src/hg/hgTracks/vcfTrack.c @@ -157,31 +157,31 @@ { double majorAlFreq = max(refFreq, maxAltFreq); if (majorAlFreq > (1.0 - minFreq)) return TRUE; } return FALSE; } static void filterRefOnlyAlleles(struct vcfFile *vcff, struct trackDb *tdb) /* Drop items from VCF that don't differ from the reference for any of the * samples specified in trackDb */ { struct vcfRecord *rec, *nextRecord, *retList = NULL; const struct vcfGenotype *gt; -struct slPair *sample, *sampleOrder = vcfPhasedGetSampleOrder(cart, tdb); +struct slPair *sample, *sampleOrder = vcfPhasedGetSampleOrder(cart, tdb, FALSE); for (rec = vcff->records; rec != NULL; rec = nextRecord) { nextRecord = rec->next; boolean allRef = TRUE; for (sample = sampleOrder; sample != NULL; sample = sample->next) { gt = vcfRecordFindGenotype(rec, sample->name); if (gt && !(gt->hapIxA == 0 && gt->hapIxB == 0) ) allRef = FALSE; } if (!allRef) slAddHead(&retList, rec); } slReverse(&retList); vcff->records = retList; @@ -220,31 +220,31 @@ unsigned int vcfStart; unsigned int vcfEnd; }; 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. If the trackDb setting * sampleName is present, then check whether all the records are phased or not */ { struct pgSnp *pgsList = NULL; struct vcfRecord *rec; int maxLen = 33; int maxAlCount = 5; struct slPair *sample = NULL, *phasedSamples = NULL; if (sameString(tdb->type, "vcfPhasedTrio")) - phasedSamples = vcfPhasedGetSampleOrder(cart, tdb); + phasedSamples = vcfPhasedGetSampleOrder(cart, tdb, FALSE); vcff->allPhased = TRUE; for (rec = vcff->records; rec != NULL; rec = rec->next) { struct pgSnpVcfStartEnd *psvs = needMem(sizeof(*psvs)); psvs->vcfStart = vcfRecordTrimIndelLeftBase(rec); psvs->vcfEnd = vcfRecordTrimAllelesRight(rec); for (sample = phasedSamples; sample != NULL; sample = sample->next) { const struct vcfGenotype *gt = vcfRecordFindGenotype(rec, sample->name); if (!gt->isPhased) vcff->allPhased = FALSE; } struct pgSnp *pgs = pgSnpFromVcfRecord(rec); memcpy(&(psvs->pgs), pgs, sizeof(*pgs)); @@ -2013,35 +2013,32 @@ static void vcfPhasedSetupHaplotypesLines(struct track *track, struct hvGfx *hvg, int xOff, int yOff, int width, int *retYOffsets, struct slPair *sampleNames, MgFont *font) /* Setup the background for drawing the ticks, the two haplotype lines for each sample, and the * transparent gray box to help distinguish between consecutive samples */ { int sampleHeight = round(track->height / track->customInt); double yHap1 = track->lineHeight; // relative offset of first haplotype line double yHap2 = sampleHeight - track->lineHeight; // relative offset of second line struct slPair *name; int i, y1, y2; struct rgbColor yellow = lightRainbowAtPos(0.2); int transYellow = MAKECOLOR_32_A(yellow.r, yellow.g, yellow.b, 100); -char defaultLabelVar[1024], aliasLabelVar[1024]; -safef(defaultLabelVar, sizeof(defaultLabelVar), "%s.%s", track->track, VCF_PHASED_DEFAULT_LABEL_VAR); -safef(aliasLabelVar, sizeof(aliasLabelVar), "%s.%s", track->track, VCF_PHASED_ALIAS_LABEL_VAR); -boolean useDefaultLabel = cartUsualBoolean(cart, defaultLabelVar, TRUE); -boolean useAliasLabel = cartUsualBoolean(cart, aliasLabelVar, FALSE); +boolean useDefaultLabel = cartUsualBooleanClosestToHome(cart, track->tdb, FALSE, VCF_PHASED_DEFAULT_LABEL_VAR, TRUE); +boolean useAliasLabel = cartUsualBooleanClosestToHome(cart, track->tdb, FALSE, VCF_PHASED_ALIAS_LABEL_VAR, FALSE); for (name = sampleNames, i = 0; name != NULL; name = name->next, i++) { y1 = yOff + yHap1 + (i * sampleHeight); y2 = yOff + yHap2 + (i * sampleHeight); retYOffsets[2*i] = y1; retYOffsets[(2*i) + 1] = y2; // make the background of every other lane light yellow, but only when NOT doing PDF/EPS output if ((hvg->pixelBased && i & 1)) { hvGfxBox(hvg, xOff, y1-(track->lineHeight), width, (y2 + track->lineHeight) - (y1-track->lineHeight), transYellow); } hvGfxLine(hvg, xOff, y1, xOff+width, y1, MG_BLACK); hvGfxLine(hvg, xOff, y2, xOff+width, y2, MG_BLACK); struct dyString *label = dyStringNew(0); @@ -2052,31 +2049,31 @@ vcfPhasedAddLabel(track, hvg, label->string, yOff, round(((y1 + y2) / 2) - (track->lineHeight / 2)), font, MG_BLACK); } } static void vcfPhasedDrawItems(struct track *track, int seqStart, int seqEnd, struct hvGfx *hvg, int xOff, int yOff, int width, MgFont *font, Color color, enum trackVisibility vis) /* Split samples' chromosomes (haplotypes), cluster them by parents, and * draw them all along a line representing each chromosome*/ { struct vcfFile *vcff = track->extraUiData; if (vcff->records == NULL) return; const double scale = scaleForPixels(width); -struct slPair *pair, *sampleNames = vcfPhasedGetSampleOrder(cart, track->tdb); +struct slPair *pair, *sampleNames = vcfPhasedGetSampleOrder(cart, track->tdb, FALSE); int gtCount = slCount(sampleNames); int yOffsets[gtCount * 2]; // y offsets of each haplotype line char *sampleOrder[gtCount]; // order of sampleName lines int i; for (pair = sampleNames, i = 0; pair != NULL && i < gtCount; pair = pair->next, i++) sampleOrder[i] = pair->name; // child sample is required to be in the middle/bottom of the trio char *childSample = gtCount > 2 ? sampleOrder[1] : sampleOrder[0]; // set up the "haplotype" lines and the transparent yellow box to delineate samples vcfPhasedSetupHaplotypesLines(track, hvg, xOff, yOff, width, yOffsets, sampleNames, font); // sort the variants by haplotype then draw ticks int nRecords = slCount(vcff->records); int centerIx = getCenterVariantIx(track, seqStart, seqEnd, vcff->records); @@ -2090,31 +2087,31 @@ vcfPhasedDrawOneRecord(track, hvg, rec, item, hapOrder, gtCount * 2, xOff, yOffsets, sampleOrder, scale); } } static int vcfPhasedItemHeight(struct track *tg, void *item) { return tg->heightPer; } int vcfPhasedTrackHeight(struct track *tg, enum trackVisibility vis) { const struct vcfFile *vcff = tg->extraUiData; // when doing composite track height, vcfPhasedLoadItems won't have been called yet! if (!vcff || vcff->records == NULL) return 0; -int totalSamples = slCount(vcfPhasedGetSampleOrder(cart, tg->tdb)); +int totalSamples = slCount(vcfPhasedGetSampleOrder(cart, tg->tdb, FALSE)); tg->lineHeight = tl.fontHeight + 1; tg->heightPer = tl.fontHeight; // if all variants in view are phased, then 3 lines per sample, // else 4 lines. The extra 2 is for clear separation int heightPerSample; if (vcff->allPhased) heightPerSample = (3 * tg->lineHeight) + 2; else heightPerSample = (4 * tg->lineHeight) + 2; tg->height = totalSamples * heightPerSample; tg->itemHeight = vcfPhasedItemHeight; // custom int is reserved for doing pgSnp coloring but as far as I can tell is // never actually used? tg->customInt = totalSamples; return tg->height;