8ce7da98082db69f86314bf79d8f69978e008455 angie Fri Apr 28 16:43:36 2017 -0700 hgVai was crashing when there was a new snpNNN table in the database but not yet in trackDb. Now make sure to use the latest SNPs track not just the latest table. refs #19272 diff --git src/hg/hgVai/hgVai.c src/hg/hgVai/hgVai.c index 868a394..24d4ac0 100644 --- src/hg/hgVai/hgVai.c +++ src/hg/hgVai/hgVai.c @@ -482,31 +482,33 @@ printf("If you have more than one custom track or hub track in " PGSNP_OR_VCF " format, please select the one you wish to annotate:<BR>\n"); } printf("<B>variants: </B>"); printf("<SELECT ID='hgva_variantTrack' NAME='hgva_variantTrack'>\n"); jsOnEventById("change", "hgva_variantTrack", "hgva.changeVariantSource();"); char *selected = cartUsualString(cart, "hgva_variantTrack", ""); struct slRef *ref; for (ref = varTrackList; ref != NULL; ref = ref->next) { struct trackDb *tdb = ref->val; printOption(tdb->track, selected, tdb->longLabel); } printOption(hgvaSampleVariants, selected, hgvaSampleVariantsLabel); printOption(hgvaUseHgvs, selected, hgvaHgvsLabel); -boolean hasSnps = (hFindLatestSnpTable(database, NULL) != NULL); +struct trackDb *snpTdb = hFindLatestSnpTrack(database, NULL, &fullTrackList); +// We can convert rsIds from snpNNN tables (but not ancient "snp" - no refUCSC column) into VCF +boolean hasSnps = (snpTdb != NULL && differentString(snpTdb->table, "snp")); if (hasSnps) printOption(hgvaUseVariantIds, selected, hgvaVariantIdsLabel); printf("</SELECT><BR>\n"); printf("<div id='"hgvaHgvsPasteContainer"'%s>\n", differentString(selected, hgvaUseHgvs) ? " style='display: none;'" : ""); printf("Enter HGVS terms: one term per line; blank lines and comment lines beginning with '#' " "are ignored.<BR>\n"); char *oldPasted = cartUsualString(cart, hgvaHgvs, ""); cgiMakeTextArea(hgvaHgvs, oldPasted, 10, 70); puts("</div>"); if (hasSnps) { printf("<div id='"hgvaVariantPasteContainer"'%s>\n", @@ -713,68 +715,63 @@ printDbNsfpSource(table->name, HDIV); printDbNsfpSource(table->name, HVAR); } else printDbNsfpSource(table->name, 0); } jsEndContainer(); puts("<BR>"); endCollapsibleSection(); } boolean findSnpBed4(char *suffix, char **retFileName, struct trackDb **retTdb) /* If we can find the latest snpNNNsuffix table, or better yet a bigBed file for it (faster), * set the appropriate ret* and return TRUE, otherwise return FALSE. */ { -char *table = hFindLatestSnpTable(database, suffix); -if (table == NULL) +struct trackDb *tdb = hFindLatestSnpTrack(database, suffix, &fullTrackList); +if (tdb == NULL) return FALSE; boolean foundIt = FALSE; // Do we happen to have a bigBed version? Better yet, bed4 only for current uses: char origFileName[HDB_MAX_PATH_STRING]; -safef(origFileName, sizeof(origFileName), "/gbdb/%s/vai/%s.bed4.bb", database, table); +safef(origFileName, sizeof(origFileName), "/gbdb/%s/vai/%s.bed4.bb", database, tdb->table); char* fileName = hReplaceGbdb(origFileName); if (fileExists(fileName)) { if (retFileName != NULL) *retFileName = fileName; foundIt = TRUE; } else { // Not bed4; try just .bb: freez(&fileName); - safef(origFileName, sizeof(origFileName), "/gbdb/%s/vai/%s.bb", database, table); + safef(origFileName, sizeof(origFileName), "/gbdb/%s/vai/%s.bb", database, tdb->table); fileName = hReplaceGbdb(origFileName); if (fileExists(fileName)) { if (retFileName != NULL) *retFileName = fileName; foundIt = TRUE; } } -if (foundIt && retTdb == NULL) - return TRUE; -struct trackDb *tdb = tdbForTrack(database, table, &fullTrackList); -if (tdb != NULL) - { - if (retTdb != NULL) +if (retTdb == NULL) + return foundIt; +else *retTdb = tdb; return TRUE; } -return foundIt; -} void selectDbSnp(boolean gotSnp) /* Offer to include rsID (and other fields, or leave that for advanced output??) if available */ { if (!gotSnp) return; startCollapsibleSection("dbSnp", "Known variation", TRUE); cartMakeCheckBox(cart, "hgva_rsId", TRUE); printf("Include <A HREF='http://www.ncbi.nlm.nih.gov/projects/SNP/' TARGET=_BLANK>dbSNP</A> " "rs# ID if one exists<BR>\n"); puts("<BR>"); endCollapsibleSection(); } #define GENCODE_PREFIX "wgEncodeGencode" @@ -2181,38 +2178,38 @@ dyStringPrintf(dy, "'%s'", el->name); } return dyStringCannibalize(&dy); } //#*** Variant ID-matching should be metadata-driven too. termRegex -> data source. static const char *rsIdRegex = "^rs[0-9]+$"; static void rsIdsToVcfRecords(struct annoAssembly *assembly, struct slName *rsIds, struct vcfFile *vcff, struct vcfRecord **pRecList, struct slName **pCommentList) /* If possible, look up coordinates and alleles of dbSNP rs IDs. */ { if (rsIds == NULL) return; -char *table = hFindLatestSnpTable(database, NULL); -if (table == NULL) +struct trackDb *tdb = hFindLatestSnpTrack(database, NULL, &fullTrackList); +if (tdb == NULL) return; struct sqlConnection *conn = hAllocConn(assembly->name); // Build a 'name in (...)' query, and build a hash of IDs so we can test whether all were found struct dyString *dq = sqlDyStringCreate("select chrom, chromStart, chromEnd, name, strand, " "refUCSC, observed from %s where name in (", - table); + tdb->table); struct hash *idHash = hashNew(0); struct slName *id; for (id = rsIds; id != NULL; id = id->next) { tolowers(id->name); dyStringPrintf(dq, "%s'%s'", (id != rsIds ? "," : ""), id->name); hashStoreName(idHash, id->name); } dyStringAppend(dq, ");"); struct sqlResult *sr = sqlGetResult(conn, dq->string); // Construct a minimal VCF row to make a vcfRecord for each variant. char *vcfRow[9]; vcfRow[5] = vcfRow[6] = vcfRow[7] = "."; // placeholder for qual, filter, info // It would be cool to someday add snpNNN's exceptions column to the filter or info. struct dyString *dyAltAlStr = dyStringNew(0);