e323d595c241d03570d380d8c60de60e99c1c4ec
braney
Fri Mar 21 12:36:21 2025 -0700
add support for bigDbSnp to quicklift
diff --git src/hg/hgc/hgc.c src/hg/hgc/hgc.c
index b51fa89417f..8ec8aebd78d 100644
--- src/hg/hgc/hgc.c
+++ src/hg/hgc/hgc.c
@@ -11004,31 +11004,35 @@
printf("
");
printPosOnChrom(chrom, atoi(chromStart), atoi(chromEnd), NULL, FALSE, itemName);
}
void doCosmic(struct trackDb *tdb, char *item)
/* Put up COSMIC track info. */
{
genericHeader(tdb, item);
printCosmicDetails(tdb, item);
printTrackHtml(tdb);
}
void printDecipherSnvsDetails(struct trackDb *tdb, char *itemName, boolean encode)
/* Print details of a DECIPHER entry. */
{
-struct sqlConnection *conn = hAllocConn(database);
+char *db = database;
+char *liftDb = cloneString(trackDbSetting(tdb, "quickLiftDb"));
+if (liftDb != NULL)
+ db = liftDb;
+struct sqlConnection *conn = hAllocConn(db);
char query[256];
struct sqlResult *sr;
char **row;
char *strand={"+"};
int start = cartInt(cart, "o");
int end = cartInt(cart, "t");
char *chrom = cartString(cart, "c");
/* So far, we can just remove "chr" from UCSC chrom names to get DECIPHER names */
char *decipherChrom = chrom;
if (startsWithNoCase("chr", decipherChrom))
decipherChrom += 3;
printf("Patient %s
", itemName);
@@ -11122,35 +11126,39 @@
hFreeConn(&conn);
}
void doDecipherSnvs(struct trackDb *tdb, char *item, char *itemForUrl)
/* Put up DECIPHER track info. */
{
genericHeader(tdb, item);
printDecipherSnvsDetails(tdb, item, FALSE);
printTrackHtml(tdb);
}
void printDecipherCnvsDetails(struct trackDb *tdb, char *itemName, boolean encode)
/* Print details of a DECIPHER entry. */
{
-struct sqlConnection *conn = hAllocConn(database);
+char *db = database;
+char *liftDb = cloneString(trackDbSetting(tdb, "quickLiftDb"));
+if (liftDb != NULL)
+ db = liftDb;
+struct sqlConnection *conn = hAllocConn(db);
char query[256];
struct sqlResult *sr;
char **row;
-struct sqlConnection *conn2 = hAllocConn(database);
+struct sqlConnection *conn2 = hAllocConn(db);
char query2[256];
struct sqlResult *sr2;
char **row2;
char *strand={"+"};
int start = cartInt(cart, "o");
int end = cartInt(cart, "t");
char *chrom = cartString(cart, "c");
/* So far, we can just remove "chr" from UCSC chrom names to get DECIPHER names */
char *decipherChrom = chrom;
if (startsWithNoCase("chr", decipherChrom))
decipherChrom += 3;
printf("Patient %s
", itemName);
@@ -18620,40 +18628,40 @@
}
else
ranOffEnd = TRUE;
}
}
}
if (! ranOffEnd)
{
struct dnaSeq *seq =
hDnaFromSeq(database, gene->chrom, snpPlusOffset, snpPlusOffset+1, dnaUpper);
base = seq->dna[0];
}
return base;
}
-char *getSymbolForGeneName(char *geneTable, char *geneId)
+char *getSymbolForGeneName(char *db, char *geneTable, char *geneId)
/* Given a gene track and gene accession, look up the symbol if we know where to look
* and if we find it, return a string with both symbol and acc. */
{
struct dyString *dy = dyStringNew(32);
char buf[256];
char *sym = NULL;
if (sameString(geneTable, "knownGene") || sameString(geneTable, "refGene"))
{
- struct sqlConnection *conn = hAllocConn(database);
+ struct sqlConnection *conn = hAllocConn(db);
char query[256];
query[0] = '\0';
if (sameString(geneTable, "knownGene"))
sqlSafef(query, sizeof(query), "select geneSymbol from kgXref where kgID = '%s'", geneId);
else if (sameString(geneTable, "refGene"))
sqlSafef(query, sizeof(query), "select name from %s where mrnaAcc = '%s'", refLinkTable, geneId);
sym = sqlQuickQuery(conn, query, buf, sizeof(buf)-1);
hFreeConn(&conn);
}
if (sym != NULL)
dyStringPrintf(dy, "%s (%s)", sym, geneId);
else
dyStringAppend(dy, geneId);
return dyStringCannibalize(&dy);
}
@@ -18800,39 +18808,39 @@
geneTrack, geneName, snpMisoLinkFromFunc("stop_retained_variant"),
refAA, refCodonHtml, snpAA, snpCodonHtml);
else
printf(firstTwoColumnsPctS "%s %c (%s) --> %c (%s)\n",
geneTrack, geneName, snpMisoLinkFromFunc("coding-synon"),
refAA, refCodonHtml, snpAA, snpCodonHtml);
}
}
else
printf(firstTwoColumnsPctS "%s %s --> %s\n",
geneTrack, geneName, snpMisoLinkFromFunc("cds-synonymy-unknown"),
abbreviateAllele(refAllele), abbreviateAllele(al));
}
}
-void printSnp125FunctionInGene(struct snp125 *snp, char *geneTable, char *geneTrack,
+void printSnp125FunctionInGene(char *db, struct snp125 *snp, char *geneTable, char *geneTrack,
struct genePred *gene)
/* Given a SNP and a gene that overlaps it, say where in the gene it overlaps
* and if in CDS, say what effect the coding alleles have. */
{
int snpStart = snp->chromStart, snpEnd = snp->chromEnd;
int cdsStart = gene->cdsStart, cdsEnd = gene->cdsEnd;
boolean geneIsRc = sameString(gene->strand, "-");
-char *geneName = getSymbolForGeneName(geneTable, gene->name);
+char *geneName = getSymbolForGeneName(db, geneTable, gene->name);
int i, iStart = 0, iEnd = gene->exonCount, iIncr = 1;
if (geneIsRc)
{ iStart = gene->exonCount - 1; iEnd = -1; iIncr = -1; }
for (i = iStart; i != iEnd; i += iIncr)
{
int exonStart = gene->exonStarts[i], exonEnd = gene->exonEnds[i];
if (snpEnd > exonStart && snpStart < exonEnd)
{
if (snpEnd > cdsStart && snpStart < cdsEnd)
printSnp125FunctionInCDS(snp, geneTable, geneTrack, gene, i, geneName);
else if (cdsEnd > cdsStart)
{
boolean is5Prime = ((geneIsRc && (snpStart >= cdsEnd)) ||
(!geneIsRc && (snpEnd < cdsStart)));
printf(firstTwoColumnsPctS "%s\n", geneTrack, geneName,
@@ -18880,176 +18888,184 @@
{
struct sqlResult *sr;
char query[512];
char **row;
int snpStart = snp->chromStart, snpEnd = snp->chromEnd;
int nearCount = 0;
int maxDistance = 10000;
/* query to the left: */
sqlSafef(query, sizeof(query), "select name,txEnd,strand from %s "
"where chrom = '%s' and txStart < %d and txEnd > %d",
geneTable, snp->chrom, snpStart, snpStart - maxDistance);
sr = sqlGetResult(conn, query);
while ((row = sqlNextRow(sr)) != NULL)
{
char *gene = row[0];
- char *geneName = getSymbolForGeneName(geneTable, gene);
+ char *geneName = getSymbolForGeneName(sqlGetDatabase(conn), geneTable, gene);
int end = sqlUnsigned(row[1]);
char *strand = row[2];
boolean isRc = strand[0] == '-';
printf(firstTwoColumnsPctS "%s (%d bases %sstream)\n",
geneTrack, geneName, snpMisoLinkFromFunc(isRc ? "near-gene-5" : "near-gene-3"),
(snpStart - end + 1), (isRc ? "up" : "down"));
nearCount++;
}
sqlFreeResult(&sr);
/* query to the right: */
sqlSafef(query, sizeof(query), "select name,txStart,strand from %s "
"where chrom = '%s' and txStart < %d and txEnd > %d",
geneTable, snp->chrom, snpEnd + maxDistance, snpEnd);
sr = sqlGetResult(conn, query);
while ((row = sqlNextRow(sr)) != NULL)
{
char *gene = row[0];
- char *geneName = getSymbolForGeneName(geneTable, gene);
+ char *geneName = getSymbolForGeneName(sqlGetDatabase(conn), geneTable, gene);
int start = sqlUnsigned(row[1]);
char *strand = row[2];
boolean isRc = strand[0] == '-';
printf(firstTwoColumnsPctS "%s (%d bases %sstream)\n",
geneTrack, geneName, snpMisoLinkFromFunc(isRc ? "near-gene-3" : "near-gene-5"),
(start - snpEnd + 1), (isRc ? "down" : "up"));
nearCount++;
}
sqlFreeResult(&sr);
if (nearCount == 0)
printf("%s | | %s |
", geneTrack,
snpMisoLinkFromFunc("intergenic_variant"));
}
static struct genePred *getGPsWithFrames(struct sqlConnection *conn, char *geneTable,
char *chrom, int start, int end)
/* Given a known-to-exist genePred table name and a range, return
* genePreds in range with exonFrames populated. */
{
struct genePred *gpList = NULL;
boolean hasBin;
struct sqlResult *sr = hRangeQuery(conn, geneTable, chrom, start, end, NULL, &hasBin);
-struct sqlConnection *conn2 = hAllocConn(database);
+struct sqlConnection *conn2 = hAllocConn(sqlGetDatabase(conn));
boolean hasFrames = (sqlFieldIndex(conn2, geneTable, "exonFrames") == hasBin + 14);
char **row;
while ((row = sqlNextRow(sr)) != NULL)
{
int fieldCount = hasBin + (hasFrames ? 15 : 10);
struct genePred *gp;
if (hasFrames)
{
gp = genePredExtLoad(row+hasBin, fieldCount);
// Some tables have an exonFrames column but it's empty...
if (gp->exonFrames == NULL)
genePredAddExonFrames(gp);
}
else
{
gp = genePredLoad(row+hasBin);
genePredAddExonFrames(gp);
}
slAddHead(&gpList, gp);
}
sqlFreeResult(&sr);
hFreeConn(&conn2);
return gpList;
}
-void printSnp125FunctionShared(struct snp125 *snp, struct slName *geneTracks)
+void printSnp125FunctionShared(char *db, struct snp125 *snp, struct slName *geneTracks)
{
-struct sqlConnection *conn = hAllocConn(database);
+struct sqlConnection *conn = hAllocConn(db);
struct slName *gt;
boolean first = TRUE;
for (gt = geneTracks; gt != NULL; gt = gt->next)
if (sqlTableExists(conn, gt->name))
{
if (first)
{
printf("
UCSC's predicted function relative to selected gene tracks:\n");
printf("\n");
}
struct genePred *geneList = getGPsWithFrames(conn, gt->name, snp->chrom,
snp->chromStart, snp->chromEnd);
struct genePred *gene;
char query[256];
char buf[256];
sqlSafef(query, sizeof(query), "select shortLabel from trackDb where tableName='%s'",
gt->name);
char *shortLabel = sqlQuickQuery(conn, query, buf, sizeof(buf)-1);
if (shortLabel == NULL) shortLabel = gt->name;
for (gene = geneList; gene != NULL; gene = gene->next)
- printSnp125FunctionInGene(snp, gt->name, shortLabel, gene);
+ printSnp125FunctionInGene(db, snp, gt->name, shortLabel, gene);
if (geneList == NULL)
printSnp125NearGenes(conn, snp, gt->name, shortLabel);
first = FALSE;
}
if (! first)
printf("
\n");
hFreeConn(&conn);
}
void printSnp125Function(struct trackDb *tdb, struct snp125 *snp)
/* If the user has selected a gene track for functional annotation,
* report how this SNP relates to any nearby genes. */
{
char varName[512];
safef(varName, sizeof(varName), "%s_geneTrack", tdb->track);
struct slName *geneTracks = cartOptionalSlNameList(cart, varName);
if (geneTracks == NULL && !cartListVarExists(cart, varName))
{
char *defaultGeneTracks = trackDbSetting(tdb, "defaultGeneTracks");
if (isNotEmpty(defaultGeneTracks))
geneTracks = slNameListFromComma(defaultGeneTracks);
else
return;
}
-printSnp125FunctionShared(snp, geneTracks);
+char *db = database;
+char *liftDb = cloneString(trackDbSetting(tdb, "quickLiftDb"));
+if (liftDb != NULL)
+ db = liftDb;
+printSnp125FunctionShared(db, snp, geneTracks);
}
void printSnp153Function(struct trackDb *tdb, struct snp125 *snp)
/* If the user has selected a gene track for functional annotation,
* report how this SNP relates to any nearby genes. */
{
struct slName *geneTracks = NULL;
struct trackDb *correctTdb = tdbOrAncestorByName(tdb, tdb->track);
struct slName *defaultGeneTracks = slNameListFromComma(trackDbSetting(tdb, "defaultGeneTracks"));
-struct trackDb *geneTdbList = snp125FetchGeneTracks(database, cart);
+char *db = database;
+char *liftDb = cloneString(trackDbSetting(tdb, "quickLiftDb"));
+if (liftDb != NULL)
+ db = liftDb;
+struct trackDb *geneTdbList = snp125FetchGeneTracks(db, cart);
struct trackDb *gTdb;
for (gTdb = geneTdbList; gTdb; gTdb=gTdb->next)
{
char *trackName = gTdb->track;
char suffix[512];
safef(suffix, sizeof(suffix), "geneTrack.%s", trackName);
boolean option = cartUsualBooleanClosestToHome(cart, correctTdb, FALSE, suffix, slNameInList(defaultGeneTracks,trackName));
if (option)
{
slNameAddHead(&geneTracks, trackName);
}
}
if (geneTracks)
- printSnp125FunctionShared(snp, geneTracks);
+ printSnp125FunctionShared(db, snp, geneTracks);
}
char *dbSnpFuncFromInt(unsigned char funcCode)
/* Translate an integer function code from NCBI into an abbreviated description.
* Do not free return value! */
// Might be a good idea to flesh this out with all codes, libify, and share with
// snpNcbiToUcsc instead of partially duplicating.
{
switch (funcCode)
{
case 3:
return "coding-synon";
case 8:
return "cds-reference";
case 41:
@@ -19060,38 +19076,38 @@
return "stop-loss";
case 44:
return "frameshift";
case 45:
return "cds-indel";
default:
{
static char buf[16];
safef(buf, sizeof(buf), "%d", funcCode);
return buf;
}
}
}
-void printSnp125CodingAnnotations(struct trackDb *tdb, struct snp125 *snp)
+void printSnp125CodingAnnotations(char *db, struct trackDb *tdb, struct snp125 *snp)
/* If tdb specifies extra table(s) that contain protein-coding annotations,
* show the effects of SNP on transcript coding sequences. */
{
char *tables = trackDbSetting(tdb, "codingAnnotations");
if (isEmpty(tables))
return;
-struct sqlConnection *conn = hAllocConn(database);
+struct sqlConnection *conn = hAllocConn(db);
struct slName *tbl, *tableList = slNameListFromString(tables, ',');
struct dyString *query = dyStringNew(0);
for (tbl = tableList; tbl != NULL; tbl = tbl->next)
{
if (!sqlTableExists(conn, tbl->name))
continue;
char setting[512];
safef(setting, sizeof(setting), "codingAnnoLabel_%s", tbl->name);
char *label = trackDbSettingOrDefault(tdb, setting, NULL);
if (label == NULL && endsWith(tbl->name, "DbSnp"))
label = "dbSNP";
else
label = tbl->name;
boolean hasBin = hIsBinned(database, tbl->name);
boolean hasCoords = (sqlFieldIndex(conn, tbl->name, "chrom") != -1);
@@ -19108,31 +19124,31 @@
if (first)
{
printf("
Coding annotations by %s:
\n", label);
first = FALSE;
}
struct snp125CodingCoordless *anno = snp125CodingCoordlessLoad(row+rowOffset);
int i;
boolean gotRef = (anno->funcCodes[0] == 8);
for (i = 0; i < anno->alleleCount; i++)
{
memSwapChar(anno->peptides[i], strlen(anno->peptides[i]), 'X', '*');
if (anno->funcCodes[i] == 8)
continue;
char *txName = anno->transcript;
if (startsWith("NM_", anno->transcript))
- txName = getSymbolForGeneName("refGene", anno->transcript);
+ txName = getSymbolForGeneName(db, "refGene", anno->transcript);
char *func = dbSnpFuncFromInt(anno->funcCodes[i]);
printf("%s: %s ", txName, snpMisoLinkFromFunc(func));
if (sameString(func, "frameshift") || sameString(func, "cds-indel"))
{
puts("
");
continue;
}
if (gotRef)
printf("%s (%s) --> ", anno->peptides[0],
highlightCodonBase(anno->codons[0], anno->frame));
printf("%s (%s)
\n", anno->peptides[i],
highlightCodonBase(anno->codons[i], anno->frame));
}
}
sqlFreeResult(&sr);
@@ -19240,31 +19256,35 @@
snp->locType);
printf("Class | %s |
\n", snp->class);
printf("Validation | %s |
\n", snp->valid);
printf("Function | %s |
\n",
snpMisoLinkFromFunc(snp->func));
printf("Molecule Type | %s |
\n",
snp->molType);
if (snp->avHet>0)
printf("Average Heterozygosity | "
"%.3f +/- %.3f |
\n", snp->avHet, snp->avHetSE);
printf("Weight | %d |
\n", snp->weight);
if (version >= 132)
printSnp132ExtraColumns(tdb, snp);
else
printf("\n");
-printSnp125CodingAnnotations(tdb, snp125);
+char *db = database;
+char *liftDb = cloneString(trackDbSetting(tdb, "quickLiftDb"));
+if (liftDb != NULL)
+ db = liftDb;
+printSnp125CodingAnnotations(db, tdb, snp125);
writeSnpExceptionWithVersion(tdb, snp, version);
printSnp125Function(tdb, snp125);
}
static char *getExcDescTable(struct trackDb *tdb)
/* Look up snpExceptionDesc in tdb and provide default if not found. Don't free return value! */
{
static char excDescTable[128];
char *excDescTableSetting = trackDbSetting(tdb, "snpExceptionDesc");
if (excDescTableSetting)
safecpy(excDescTable, sizeof(excDescTable), excDescTableSetting);
else
safef(excDescTable, sizeof(excDescTable), "%sExceptionDesc", tdb->table);
return excDescTable;
}