1f88a89d5bb7bada7c52ad89f910c6796d1340ed
braney
  Tue Jun 2 12:26:10 2026 -0700
Add note on quickLifted CCDS pages explaining the data is from the source assembly, refs #36125

When a user clicks the CCDS link on a quickLifted gene track, the CCDS page
necessarily loads from the source assembly (hg38), since CCDS tables exist
only there.  Mark the click with a one-shot quickLiftCcds CGI var carrying
the destination assembly, and on the CCDS page print a note explaining that
the CCDS gene model and coordinates shown are from the source assembly, not
the destination assembly the user was browsing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

diff --git src/hg/hgc/ccdsClick.c src/hg/hgc/ccdsClick.c
index 9eabd5ca062..9b9986b6ed4 100644
--- src/hg/hgc/ccdsClick.c
+++ src/hg/hgc/ccdsClick.c
@@ -40,30 +40,35 @@
 {
 // When the gene track is quickLifted, the CCDS tables live with the
 // source assembly, so route the click to liftDb and lift the window
 // coords back to source space.
 char *liftDb = (tdb != NULL) ? trackDbSetting(tdb, "quickLiftDb") : NULL;
 char *urlDb = (liftDb != NULL) ? liftDb : database;
 char *urlChrom = seqName;
 int urlStart = winStart, urlEnd = winEnd;
 if (liftDb != NULL)
     quickLiftLiftPos(trackHubSkipHubName(database), liftDb,
                      seqName, winStart, winEnd,
                      &urlChrom, &urlStart, &urlEnd);
 printf("../cgi-bin/hgc?%s&g=ccdsGene&i=%s&c=%s&o=%d&l=%d&r=%d&db=%s",
        cartSidUrlString(cart), ccdsInfo->ccds, urlChrom,
        urlStart, urlStart, urlEnd, urlDb);
+// Mark the click as coming from a quickLifted track so the CCDS page can
+// explain that the CCDS data shown is from the source assembly, not the
+// destination assembly the user is browsing.
+if (liftDb != NULL)
+    printf("&quickLiftCcds=%s", trackHubSkipHubName(database));
 }
 
 void printCcdsForSrcDb(struct sqlConnection *conn, struct trackDb *tdb, char *acc)
 /* Print out CCDS hgc link for a refseq, ensembl, or vega gene, if it
  * exists.  */
 {
 struct ccdsInfo *ccdsInfo = getCcdsInfoForSrcDb(conn, acc);;
 if (ccdsInfo != NULL)
     {
     printf("<B>CCDS:</B> <A href=\"");
     printCcdsUrlForSrcDb(tdb, ccdsInfo);
     printf("\">%s</A><BR>", ccdsInfo->ccds);
     }
 }
 
@@ -421,28 +426,40 @@
 struct ccdsInfo *ensCcds = ccdsInfoSelectByCcds(conn, ccdsId, ccdsInfoEnsembl);
 
 if (rsCcds == NULL)
     errAbort("database inconsistency: no NCBI ccdsInfo entries found for %s", ccdsId);
 if ((vegaCcds == NULL) && (ensCcds == NULL))
     errAbort("database inconsistency: no Hinxton ccdsInfo entries found for %s", ccdsId);
 
 ccdsInfoMRnaSort(&rsCcds);
 ccdsInfoMRnaSort(&vegaCcds);
 ccdsInfoMRnaSort(&ensCcds);
 
 cartWebStart(cart, database, "CCDS Gene");
 
 printf("<H2>Consensus CDS Gene %s</H2>\n", ccdsId);
 
+// When the user clicked through from a quickLifted gene track, the CCDS
+// data lives only on the source assembly (database here), not on the
+// destination assembly they were browsing.  Say so, so the assembly shown
+// isn't mistaken for a bug.
+char *quickLiftDestDb = cgiOptionalString("quickLiftCcds");
+if (quickLiftDestDb != NULL)
+    printf("<P><B>Note:</B> Consensus CDS (CCDS) annotations are available "
+           "only on %s. You followed this link from a QuickLift track on %s, "
+           "which has no CCDS data of its own, so the gene model and "
+           "coordinates shown below are from %s.</P>\n",
+           database, quickLiftDestDb, database);
+
 writeBasicInfoHtml(conn, ccdsId, rsCcds, vegaCcds, ensCcds);
 writeLinksHtml(conn, ccdsId, rsCcds, vegaCcds, ensCcds);
 writePublicNotesHtml(conn, ccdsId);
 writeRefSeqSummaryHtml(conn, ccdsId, rsCcds);
 htmlHorizontalLine();
 
 printTrackHtml(tdb);
 ccdsInfoFreeList(&rsCcds);
 ccdsInfoFreeList(&vegaCcds);
 ccdsInfoFreeList(&ensCcds);
 hFreeConn(&conn);
 }