80daf93864f5609f6b7695766a78edd90cac0c1d
braney
Fri Jul 31 12:29:05 2026 -0700
quickLift: accept broadPeak tracks, and make lifted peak details right. refs #37970
Add broadPeak to the types validateOneTdb will lift; hgTracks already knew
how to load one. Make hgc's encodePeak handler read the table out of the
source assembly and lift the items, instead of looking in the destination
assembly where the table does not exist and coming up empty. Lift peaks with
a new quickLiftPeaks() rather than casting them to bed and calling
quickLiftBeds(), whose thickStart and thickEnd assignments land on
signalValue and pValue in struct encodePeak.
diff --git src/hg/hgc/encodeClick.c src/hg/hgc/encodeClick.c
index 3ec564cc1f6..02b9f15002b 100644
--- src/hg/hgc/encodeClick.c
+++ src/hg/hgc/encodeClick.c
@@ -1,30 +1,32 @@
/* Handle details page for ENCODE tracks. */
/* Copyright (C) 2013 The Regents of the University of California
* See kent/LICENSE or http://genome.ucsc.edu/license/ for licensing information. */
#include "common.h"
#include "cart.h"
#include "hgc.h"
#include "hCommon.h"
#include "hgColors.h"
#include "customTrack.h"
#include "web.h"
#include "encode/encodePeak.h"
#include "peptideMapping.h"
#include "chromAlias.h"
+#include "quickLift.h"
+#include "trackHub.h"
#ifdef UNUSED
static boolean pairInList(struct slPair *pair, struct slPair *list)
/* Return TRUE if pair is in list. */
{
struct slPair *el;
for (el = list; el != NULL; el = el->next)
if (sameString(pair->name, el->name) && sameString(pair->val, el->val))
return TRUE;
return FALSE;
}
static boolean selGroupListMatch(struct trackDb *tdb, struct slPair *selGroupList)
/* Return TRUE if tdb has match to every item in selGroupList */
{
@@ -92,30 +94,77 @@
}
else
{
signal = sqlFloat(rowPastOffset[12]);
pValue = sqlFloat(rowPastOffset[13]);
qValue = sqlFloat(rowPastOffset[14]);
}
if (signal >= 0)
printf("Signal value: %.3f
\n", signal);
if (pValue >= 0)
printf("P-value (-log10): %.3f
\n", pValue);
if (qValue >= 0)
printf("Q-value (FDR): %.3f
\n", qValue);
}
+static void printLiftedPeak(struct encodePeak *peak, char *item, char *chrom, int start, int end,
+ enum encodePeakType peakType)
+/* Print a quickLifted peak. Like printPeak, but works from the loaded structure since
+ * the item has been mapped out of the source assembly and there is no SQL row to print. */
+{
+if ((peak->chromStart != start) || (peak->chromEnd != end))
+ return;
+if (!sameString(peak->name, item))
+ return;
+
+if (peak->name[0] != '.')
+ printf("Name: %s
\n", peak->name);
+printf("Position: "
+ "%s:%d-%d
\n",
+ hgTracksPathAndSettings(), database, chrom, start+1, end, chrom, start+1, end);
+if (((peakType == narrowPeak) || (peakType == encodePeak)) && (peak->peak > -1))
+ printf("Peak point: %d
\n", start + peak->peak + 1); // one based
+if (peak->strand[0] != '.')
+ printf("Strand: %c
\n", peak->strand[0]);
+printf("Score: %d
\n", peak->score);
+if (peak->signalValue >= 0)
+ printf("Signal value: %.3f
\n", peak->signalValue);
+if (peak->pValue >= 0)
+ printf("P-value (-log10): %.3f
\n", peak->pValue);
+if (peak->qValue >= 0)
+ printf("Q-value (FDR): %.3f
\n", peak->qValue);
+}
+
+static ItemLoader2 peakLoaderForType(enum encodePeakType peakType)
+/* Return the loader that reads a SQL row of the given peak type. */
+{
+switch(peakType)
+ {
+ case narrowPeak:
+ return (ItemLoader2)narrowPeakLoad;
+ case broadPeak:
+ return (ItemLoader2)broadPeakLoad;
+ case gappedPeak:
+ return (ItemLoader2)gappedPeakLoad;
+ case encodePeak:
+ return (ItemLoader2)encodePeakLoad;
+ default:
+ errAbort("bad value for peak type %d\n", peakType);
+ }
+return NULL;
+}
+
void doBigEncodePeak(struct trackDb *tdb, struct customTrack *ct, char *item)
/* details for encodePeak type tracks. */
{
enum encodePeakType peakType = narrowPeak;
char *chrom = cartString(cart,"c");
int start = cgiInt("o");
int end = cgiInt("t");
boolean firstTime = TRUE;
//peakType = encodePeakInferTypeFromTable(db, table, tdb->type);
if (peakType == 0)
errAbort("unrecognized peak type from table %s", tdb->table);
genericHeader(tdb, NULL); // genericClickHandlerPlus gets there first anyway (maybe except for encodePeak custom tracks).
char *fileName = bbiNameFromSettingOrTable(tdb, NULL, tdb->table);
struct bbiFile *bbi = bigBedFileOpenAlias(fileName, chromAliasFindAliases);
struct lm *lm = lmInit(0);
@@ -145,46 +194,75 @@
char *db;
char *table = tdb->table;
char *chrom = cartString(cart,"c");
int start = cgiInt("o");
int end = cgiInt("t");
int rowOffset;
boolean firstTime = TRUE;
/* connect to DB */
if (ct)
{
db = CUSTOM_TRASH;
table = ct->dbTableName;
}
else
db = database;
+
+// quickLifted tracks live in the source assembly, and tdb->table carries the hub_NNN_ prefix
+char *liftDb = cloneString(trackDbSetting(tdb, "quickLiftDb"));
+if (liftDb != NULL)
+ {
+ quickLiftResolveTable(tdb, trackHubSkipHubName(tdb->track), &table, &liftDb);
+ db = liftDb;
+ }
+
conn = hAllocConn(db);
peakType = encodePeakInferTypeFromTable(db, table, tdb->type);
if (peakType == 0)
errAbort("unrecognized peak type from table %s", tdb->table);
genericHeader(tdb, NULL); // genericClickHandlerPlus gets there first anyway (maybe except for encodePeak custom tracks).
+if (liftDb != NULL)
+ {
+ struct hash *chainHash = newHash(12);
+ char *quickLiftFile = cloneString(trackDbSetting(tdb, "quickLiftUrl"));
+ struct encodePeak *peakList = (struct encodePeak *)quickLiftSql(conn, quickLiftFile, table,
+ chrom, start, end, NULL, NULL, peakLoaderForType(peakType), 0, chainHash);
+ struct encodePeak *liftedPeaks = quickLiftPeaks(peakList, chainHash);
+
+ for(; liftedPeaks != NULL; liftedPeaks = liftedPeaks->next)
+ {
+ if (firstTime)
+ firstTime = FALSE;
+ else // print separator
+ printf("
\n");
+ printLiftedPeak(liftedPeaks, item, chrom, start, end, peakType);
+ }
+ }
+else
+ {
sr = hOrderedRangeQuery(conn, table, chrom, start, end,
NULL, &rowOffset);
while((row = sqlNextRow(sr)) != NULL)
{
if (firstTime)
firstTime = FALSE;
else // print separator
printf("
\n");
printPeak(row, rowOffset, item, chrom, start, end, peakType);
}
sqlFreeResult(&sr);
+ }
hFreeConn(&conn);
}
int encodeFiveCInterCmp(const void *va, const void *vb)
/* reverse sort on bed nine's reserved field which in this */
/* case is the where the strength of the interaction is stored */
{
const struct bed *a = *((struct bed **)va);
const struct bed *b = *((struct bed **)vb);
return b->itemRgb - a->itemRgb;
}
void doEncodeFiveC(struct sqlConnection *conn, struct trackDb *tdb)
/* Print details for 5C track */
{