de29d745d32fb04a5187fb5998cc94bbb9bf41a4
angie
Wed Aug 9 13:39:59 2017 -0700
Add optional HGVS output to annoGratorGpVar and hgVai. Since annoGratorGpVar is genePred-based, it can't yet take advantage of variantProjector's full PSL+CDS+sequence support, so when transcripts don't align cleanly to genome, HGVS c./n./p. output may be incorrect. refs #19968
diff --git src/hg/hgVai/hgVai.c src/hg/hgVai/hgVai.c
index 24d4ac0..4784225 100644
--- src/hg/hgVai/hgVai.c
+++ src/hg/hgVai/hgVai.c
@@ -968,30 +968,58 @@
isVisible ? "block" : "none");
cartMakeCheckBox(cart, "hgva_txStatus_refSeqStatus", FALSE);
puts("Include the "
"RefSeq status of each transcript.
");
puts("");
}
printf("
",
somethingIsVisible ? "none" : "block");
puts("No transcript status data are available for the selected gene track.");
puts("
");
puts("
");
endCollapsibleSection();
}
+static void selectHgvsOut()
+/* Offer HGVS output choices */
+{
+startCollapsibleSection("hgvsOut", "HGVS variant nomenclature", TRUE);
+printf("The Human Genome Variation Society (HGVS) "
+ "has established a "
+ "sequence variant nomenclature, "
+ "an international standard used to report variation in "
+ "genomic, transcript and protein sequences.
\n");
+cartMakeCheckBox(cart, "hgva_hgvsG", FALSE);
+printf("Include HGVS genomic (g.) terms in output
\n");
+cartMakeCheckBox(cart, "hgva_hgvsCN", FALSE);
+printf("Include HGVS coding (c.) terms if applicable, otherwise noncoding (n.) terms, in output"
+ "
\n");
+cartMakeCheckBox(cart, "hgva_hgvsP", FALSE);
+printf("Include HGVS protein (p.) terms (if applicable) in output
\n");
+cartMakeCheckBox(cart, "hgva_hgvsPAddParens", FALSE);
+printf("When including HGVS protein (p.) terms, add parentheses around changes to emphasize "
+ "that they are predictions
\n");
+cartMakeCheckBox(cart, "hgva_hgvsBreakDelIns", FALSE);
+printf("For variants that involve both a deletion and insertion, "
+ "including multi-nucleotide variants, "
+ "include the deleted sequence (e.g. show \"delAGinsTT\" instead of only \"delinsTT\")"
+ "
\n");
+puts("
");
+endCollapsibleSection();
+}
+
boolean isHg19RegulatoryTrack(struct trackDb *tdb, void *filterData)
/* For now, just look for a couple specific tracks by tableName. */
{
//#*** NEED METADATA
return (sameString("wgEncodeRegDnaseClusteredV3", tdb->table) ||
sameString("wgEncodeRegTfbsClusteredV3", tdb->table));
}
boolean isHg38RegulatoryTrack(struct trackDb *tdb, void *filterData)
/* For now, just look for a couple specific tracks by tableName. */
{
//#*** NEED METADATA
return (sameString("wgEncodeRegDnaseClustered", tdb->table) ||
sameString("wgEncodeRegTfbsClusteredV3", tdb->table));
}
@@ -1117,30 +1145,31 @@
struct slName *dbNsfpTables = findDbNsfpTables();
boolean gotSnp = findSnpBed4("", NULL, NULL);
struct slRef *elTrackRefList = NULL, *scoreTrackRefList = NULL;
findCons(&elTrackRefList, &scoreTrackRefList);
struct slRef *cosmicTrackRefList = findTrackRefByName("cosmic");
boolean hasTxStat = hasTxStatus();
if (dbNsfpTables == NULL && !gotSnp && elTrackRefList == NULL && scoreTrackRefList == NULL &&
cosmicTrackRefList == NULL && !hasTxStat)
return;
puts("
");
printf("\n");
// Make wrapper table for collapsible sections:
puts("");
selectDbNsfp(dbNsfpTables);
selectTxStatus(hasTxStat, geneTrack);
+selectHgvsOut();
selectDbSnp(gotSnp);
trackCheckBoxSection("Cosmic", "COSMIC", cosmicTrackRefList);
trackCheckBoxSection("ConsEl", "Conserved elements", elTrackRefList);
trackCheckBoxSection("ConsScore", "Conservation scores", scoreTrackRefList);
puts("
");
}
void selectFiltersFunc()
/* Options to restrict variants based on gene region/soTerm from gpFx */
{
startCollapsibleSection("filtersFunc", "Functional role", FALSE);
printf("Include variants annotated as
\n");
jsMakeSetClearContainer();
cartMakeCheckBox(cart, "hgva_include_intergenic", TRUE);
printf("intergenic
\n");
@@ -1398,30 +1427,47 @@
ZeroVar(&aggvFuncFilter);
aggvFuncFilter.intergenic = cartUsualBoolean(cart, "hgva_include_intergenic", TRUE);
aggvFuncFilter.upDownstream = cartUsualBoolean(cart, "hgva_include_upDownstream", TRUE);
aggvFuncFilter.nmdTranscript = cartUsualBoolean(cart, "hgva_include_nmdTranscript", TRUE);
aggvFuncFilter.exonLoss = cartUsualBoolean(cart, "hgva_include_exonLoss", TRUE);
aggvFuncFilter.utr = cartUsualBoolean(cart, "hgva_include_utr", TRUE);
aggvFuncFilter.cdsSyn = cartUsualBoolean(cart, "hgva_include_cdsSyn", TRUE);
aggvFuncFilter.cdsNonSyn = cartUsualBoolean(cart, "hgva_include_cdsNonSyn", TRUE);
aggvFuncFilter.intron = cartUsualBoolean(cart, "hgva_include_intron", TRUE);
aggvFuncFilter.splice = cartUsualBoolean(cart, "hgva_include_splice", TRUE);
aggvFuncFilter.nonCodingExon = cartUsualBoolean(cart, "hgva_include_nonCodingExon", TRUE);
aggvFuncFilter.noVariation = cartUsualBoolean(cart, "hgva_include_noVariation", TRUE);
annoGratorGpVarSetFuncFilter(gpVarGrator, &aggvFuncFilter);
}
+static void setHgvsOutOptions(struct annoGrator *gpVarGrator)
+/* Use cart variables to configure gpVarGrator's HGVS output. */
+{
+uint hgvsOutOptions = 0;
+if (cartUsualBoolean(cart, "hgva_hgvsG", FALSE))
+ hgvsOutOptions |= HGVS_OUT_G;
+if (cartUsualBoolean(cart, "hgva_hgvsCN", FALSE))
+ hgvsOutOptions |= HGVS_OUT_CN;
+if (cartUsualBoolean(cart, "hgva_hgvsP", FALSE))
+ hgvsOutOptions |= HGVS_OUT_P;
+if (cartUsualBoolean(cart, "hgva_hgvsPAddParens", FALSE))
+ hgvsOutOptions |= HGVS_OUT_P_ADD_PARENS;
+if (cartUsualBoolean(cart, "hgva_hgvsBreakDelIns", FALSE))
+ hgvsOutOptions |= HGVS_OUT_BREAK_DELINS;
+annoGratorGpVarSetHgvsOutOptions(gpVarGrator, hgvsOutOptions);
+}
+
struct annoGrator *gratorForSnpBed4(struct hash *gratorsByName, char *suffix,
struct annoAssembly *assembly, char *chrom,
enum annoGratorOverlap overlapRule,
char **retDescription)
/* Look up snpNNNsuffix; if we find it, return a grator (possibly for a bigBed 4 file),
* otherwise return NULL. */
{
char *fileName = NULL;
struct trackDb *tdb = NULL;
if (! findSnpBed4(suffix, &fileName, &tdb))
return NULL;
struct annoGrator *grator = NULL;
// First look in gratorsByName to see if this grator has already been constructed:
if (tdb != NULL)
{
@@ -2738,30 +2784,31 @@
if (! isCommandLine)
doUi();
return;
}
primary = hAnnoStreamerFromTrackDb(assembly, varTdb->table, varTdb, chrom, maxVarRows, NULL);
primaryLongLabel = varTdb->longLabel;
}
enum annoGratorOverlap geneOverlapRule = agoMustOverlap;
struct joinerDtf *txStatusExtras = getTxStatusExtras(database, geneTrack);
struct jsonElement *gpConfig = configForStreamer(database, geneTdb, txStatusExtras);
struct annoGrator *gpVarGrator = hAnnoGratorFromTrackDb(assembly, geneTdb->table, geneTdb, chrom,
ANNO_NO_LIMIT, primary->asObj,
geneOverlapRule, gpConfig);
setGpVarFuncFilter(gpVarGrator);
+setHgvsOutOptions(gpVarGrator);
// Some grators may be used as both filters and output values. To avoid making
// multiple grators for the same source, hash them by trackName:
struct hash *gratorsByName = hashNew(8);
struct annoGrator *snpGrator = NULL;
char *snpDesc = NULL;
if (cartUsualBoolean(cart, "hgva_rsId", TRUE))
snpGrator = gratorForSnpBed4(gratorsByName, "", assembly, chrom, agoNoConstraint, &snpDesc);
// Now construct gratorList in the order in which annoFormatVep wants to see them,
// i.e. first the gpVar, then the snpNNN, then whatever else:
struct annoGrator *gratorList = NULL;
slAddHead(&gratorList, gpVarGrator);
if (snpGrator != NULL)