e46073f856770bdfef4f7637eea8f9f9297aa139 chmalee Tue Nov 19 15:57:08 2019 -0800 Initial commit of new track type vcfPhased trio. A line with ticks, one per haplotype per sample in the VCF, as specified by trackDb variables. diff --git src/hg/lib/vcfUi.c src/hg/lib/vcfUi.c index 045f92c..4847cfa 100644 --- src/hg/lib/vcfUi.c +++ src/hg/lib/vcfUi.c @@ -372,43 +372,154 @@ static void vcfCfgMinAlleleFreq(struct cart *cart, struct trackDb *tdb, struct vcfFile *vcff, char *name, boolean parentLevel) /* Show input for minimum allele frequency, if we can extract it from the VCF INFO column. */ { printf("Minimum minor allele frequency (if INFO column includes AF or AC+AN):\n"); double cartMinFreq = cartOrTdbDouble(cart, tdb, VCF_MIN_ALLELE_FREQ_VAR, VCF_DEFAULT_MIN_ALLELE_FREQ); char varName[1024]; safef(varName, sizeof(varName), "%s." VCF_MIN_ALLELE_FREQ_VAR, name); cgiMakeDoubleVarInRange(varName, cartMinFreq, "minor allele frequency between 0.0 and 0.5", 5, "0.0", "0.5"); puts("
"); } +static struct slPair *vcfPhasedGetSamplesFromTdb(struct trackDb *tdb, boolean hideOtherSamples) +/* Get the different VCF Phased Trio setings out of trackDb onto a list */ +{ +// cloneString here because we will be munging the result if there are alternate labels +char *childSampleMaybeAlias = cloneString(trackDbLocalSetting(tdb, VCF_PHASED_CHILD_SAMPLE_SETTING)); +char *parentSamplesMaybeAlias = cloneString(trackDbLocalSetting(tdb, VCF_PHASED_PARENTS_SAMPLE_SETTING)); +char *samples[VCF_PHASED_MAX_OTHER_SAMPLES+1]; // for now only allow at most two parents +int numOthers = 0; +if (parentSamplesMaybeAlias && !hideOtherSamples) + { + numOthers = chopCommas(cloneString(parentSamplesMaybeAlias), samples); + if (numOthers > VCF_PHASED_MAX_OTHER_SAMPLES) + { + warn("More than %d other samples specified for phased trio", VCF_PHASED_MAX_OTHER_SAMPLES); + numOthers = VCF_PHASED_MAX_OTHER_SAMPLES; + } + // shove child into middle of array, and if there are two parents, scoot the second one to the end + int lastParentIx = VCF_PHASED_MAX_OTHER_SAMPLES - 1; + if (samples[lastParentIx] != NULL) + samples[VCF_PHASED_MAX_OTHER_SAMPLES] = cloneString(samples[lastParentIx]); + samples[lastParentIx] = cloneString(childSampleMaybeAlias); + } +else + samples[0] = cloneString(childSampleMaybeAlias); + +boolean gotAlias = strchr(samples[0], '|') != NULL; // default to whatever is first +struct slPair *ret = NULL; +int i; +for (i = 0; i < numOthers+1; i++) + { + char *val = strchr(samples[i], '|'); + boolean foundAlias = val != NULL; + if (val != NULL) + { + if (foundAlias != gotAlias) + errAbort("Either all samples have aliases or none."); + else + *val++ = 0; + } + char *name = samples[i]; + struct slPair *temp = slPairNew(cloneString(name), cloneString(val)); + slAddHead(&ret, temp); + } +slReverse(&ret); +return ret; +} + +struct slPair *vcfPhasedGetSampleOrder(struct cart *cart, struct trackDb *tdb) +/* Parse out a trio sample order from either trackDb or the cart */ +{ +char sampleOrderVar[1028],hideParentsVar[1028]; +safef(sampleOrderVar, sizeof(sampleOrderVar), "%s.%s", tdb->track, VCF_PHASED_SAMPLE_ORDER_VAR); +safef(hideParentsVar, sizeof(hideParentsVar), "%s.%s", tdb->track, VCF_PHASED_HIDE_OTHER_VAR); +boolean hideOtherSamples = cartUsualBoolean(cart, hideParentsVar, FALSE); +char *cartOrder = cartOptionalString(cart, sampleOrderVar); +struct slPair *tdbOrder = vcfPhasedGetSamplesFromTdb(tdb,hideOtherSamples); +if (cartOrder != NULL && !hideOtherSamples) + { + struct slName *name; + struct slName *fromCart = slNameListFromComma(cartOrder); + struct slPair *ret = NULL; + for (name = fromCart; name != NULL; name = name->next) + { + struct slPair *temp = slPairFind(tdbOrder, name->name); + slAddHead(&ret, temp); + } + slReverse(ret); + return ret; + } +else + return tdbOrder; +} + +static boolean hasSampleAliases(struct trackDb *tdb) +/* Check whether trackDb has aliases for the sample names */ +{ +struct slPair *nameVals = vcfPhasedGetSamplesFromTdb(tdb,FALSE); +return nameVals->val != NULL; +} + +static void vcfCfgPhasedTrioUi(struct cart *cart, struct trackDb *tdb, struct vcfFile *vcff, char *name) +/* Put up the phased trio specific config settings */ +{ +if (hasSampleAliases(tdb)) + { + printf("Label samples by:"); + char defaultLabel[1024], aliasLabel[1024]; + safef(defaultLabel, sizeof(defaultLabel), "%s.%s", tdb->track, VCF_PHASED_DEFAULT_LABEL_VAR); + safef(aliasLabel, sizeof(aliasLabel), "%s.%s", tdb->track, VCF_PHASED_ALIAS_LABEL_VAR); + boolean isDefaultChecked = cartUsualBoolean(cart, defaultLabel, TRUE); + boolean isAliasChecked = cartUsualBoolean(cart, aliasLabel, FALSE); + cgiMakeCheckBox(defaultLabel, isDefaultChecked); + printf("VCF file sample names  "); + cgiMakeCheckBox(aliasLabel, isAliasChecked); + printf("aliases"); + printf("
"); + } +if (trackDbSetting(tdb,VCF_PHASED_PARENTS_SAMPLE_SETTING)) + { + printf("Hide parent/other sample(s)"); + char hideVarName[1024]; + safef(hideVarName, sizeof(hideVarName), "%s.%s", tdb->track, VCF_PHASED_HIDE_OTHER_VAR); + boolean hidingOtherSamples = cartUsualBoolean(cart, hideVarName, FALSE); + cgiMakeCheckBox(hideVarName, hidingOtherSamples); + } +} + void vcfCfgUi(struct cart *cart, struct trackDb *tdb, char *name, char *title, boolean boxed) /* VCF: Variant Call Format. redmine #3710 */ { boxed = cfgBeginBoxAndTitle(tdb, boxed, title); printf("", boxed ? " width='100%'" : ""); struct vcfFile *vcff = vcfHopefullyOpenHeader(cart, tdb); if (vcff != NULL) { boolean parentLevel = isNameAtParentLevel(tdb, name); - if (vcff->genotypeCount > 1) + if (vcff->genotypeCount > 1 && !sameString(tdb->type, "vcfPhasedTrio")) { vcfCfgHapCluster(cart, tdb, vcff, name, parentLevel); } + if (sameString(tdb->type, "vcfPhasedTrio")) + { + vcfCfgPhasedTrioUi(cart, tdb, vcff, name); + } if (differentString(tdb->track,"evsEsp6500")) { puts("

Filters

"); vcfCfgMinQual(cart, tdb, vcff, name, parentLevel); vcfCfgFilterColumn(cart, tdb, vcff, name, parentLevel); } vcfCfgMinAlleleFreq(cart, tdb, vcff, name, parentLevel); } else { printf("Sorry, couldn't access VCF file.
\n"); } puts(""); if (boxed && fileExists(hHelpFile("hgVcfTrackHelp")))