4f0b12aadc3153194c9b4c81c70adc86d621ff2b braney Fri Oct 10 12:08:26 2025 -0700 support genePred in quickLift diff --git src/hg/hgc/hgc.c src/hg/hgc/hgc.c index 0f70c63c5d2..ee4398d780f 100644 --- src/hg/hgc/hgc.c +++ src/hg/hgc/hgc.c @@ -255,30 +255,31 @@ #include "trix.h" #include "bPlusTree.h" #include "customFactory.h" #include "dupTrack.h" #include "iupac.h" #include "clinvarSubLolly.h" #include "jsHelper.h" #include "errCatch.h" #include "htslib/bgzf.h" #include "htslib/kstring.h" #include "pipeline.h" #include "genark.h" #include "chromAlias.h" #include "dotPlot.h" #include "quickLift.h" +#include "liftOver.h" static char *rootDir = "hgcData"; #define LINESIZE 70 /* size of lines in comp seq feature */ #define MAX_DISPLAY_QUERY_SEQ_SIZE 5000000 // Big enough for HLA alts struct cart *cart; /* User's settings. */ char *seqName; /* Name of sequence we're working on. */ int winStart, winEnd; /* Bounds of sequence. */ char *database; /* Name of mySQL database. */ char *organism; /* Colloquial name of organism. */ char *genome; /* common name, e.g. Mouse, Human */ char *scientificName; /* Scientific name of organism. */ /* for earlyBotCheck() function at the beginning of main() */ @@ -2969,31 +2970,31 @@ { if (ensemblSource && differentString("protein_coding",ensemblSource)) { printf("CDS Start: none (non-coding)
\n"); printf("CDS End: none (non-coding)
\n"); } else { printf("CDS Start: "); printCdsStatus((gp->strand[0] == '+') ? gp->cdsStartStat : gp->cdsEndStat); printf("CDS End: "); printCdsStatus((gp->strand[0] == '+') ? gp->cdsEndStat : gp->cdsStartStat); } } /* if a gene class table exists, get gene class and print */ - if (classTable != NULL) + if ((liftDb == NULL) && (classTable != NULL)) { if (hTableExists(db, classTable)) { sqlSafef(query, sizeof(query), "select class from %s where name = \"%s\"", classTable, name); sr = sqlGetResult(conn, query); /* print class */ if ((row = sqlNextRow(sr)) != NULL) printf("Prediction Class: %s
\n", row[0]); sqlFreeResult(&sr); if (sqlFieldIndex(conn, classTable, "level") > 0 ) { sqlSafef(query, sizeof(query), "select level from %s where name = \"%s\"", classTable, name); sr = sqlGetResult(conn, query); @@ -9504,50 +9505,80 @@ char *table = cartString(cart, "o"); /* checks both gbSeq and table */ aaSeq *seq = hGenBankGetPep(database, pepName, table); cartHtmlStart("Protein Translation"); if (seq == NULL) { warn("Predicted peptide %s is not avaliable", pepName); } else { displayProteinPrediction(pepName, seq->dna); dnaSeqFree(&seq); } } -static struct genePred *getGenePredForPositionSql(char *table, char *geneName) +static struct genePred *getGenePredForPositionSql(struct trackDb *tdb, char *geneName) /* find the genePred for the current gene using an SQL table*/ { struct genePred *gpList = NULL; char query[512]; -struct sqlConnection *conn = hAllocConn(database); +char *db = database; +char *quickLiftFile = cloneString(trackDbSetting(tdb, "quickLiftUrl")); +char *liftDb = cloneString(trackDbSetting(tdb, "quickLiftDb")); +if (liftDb != NULL) + db = liftDb; +struct sqlConnection *conn = hAllocConn(db); struct sqlResult *sr; char **row; struct genePred *gp; -int rowOffset = hOffsetPastBin(database, seqName, table); +int rowOffset = hOffsetPastBin(db, seqName, tdb->table); +if (liftDb != NULL) + { + char *table; + if (isCustomTrack(tdb->table)) + { + liftDb = CUSTOM_TRASH; + table = trackDbSetting(tdb, "dbTableName"); + } + else + table = tdb->table; + struct hash *chainHash = newHash(8); + struct sqlConnection *conn = hAllocConn(liftDb); + +// using this loader on genePred tables with less than 15 fields may be a problem. +extern struct genePred *genePredExtLoad15(char **row); -sqlSafef(query, sizeof(query), "select * from %s where name = \"%s\"", table, geneName); + char extraWhere[4096]; + sqlSafef(extraWhere, sizeof extraWhere, "name = \"%s\"", geneName); + gpList = (struct genePred *)quickLiftSql(conn, quickLiftFile, table, seqName, winStart, winEnd, NULL, extraWhere, (ItemLoader2)genePredExtLoad15, 0, chainHash); + hFreeConn(&conn); + + calcLiftOverGenePreds( gpList, chainHash, 0.0, 1.0, TRUE, NULL, NULL, TRUE, FALSE); + } +else + { + sqlSafef(query, sizeof(query), "select * from %s where name = \"%s\"", tdb->table, geneName); sr = sqlGetResult(conn, query); while ((row = sqlNextRow(sr)) != NULL) { gp = genePredLoad(row+rowOffset); slAddHead(&gpList, gp); } sqlFreeResult(&sr); + } hFreeConn(&conn); return gpList; } struct genePred *getGenePredForPositionBigGene(struct trackDb *tdb, char *geneName) /* Find the genePred to the current gene using a bigGenePred. */ { char *fileName = hReplaceGbdb(trackDbSetting(tdb, "bigDataUrl")); struct bbiFile *bbi = bigBedFileOpenAlias(fileName, chromAliasFindAliases); struct lm *lm = lmInit(0); char *quickLiftFile = cloneString(trackDbSetting(tdb, "quickLiftUrl")); struct bigBedInterval *bb, *bbList = NULL; struct hash *chainHash = NULL; if (quickLiftFile) bbList = quickLiftGetIntervals(quickLiftFile, bbi, seqName, winStart, winEnd, &chainHash); @@ -9584,43 +9615,42 @@ lmCleanup(&lm); return gpList; } static struct genePred *getGenePredForPosition(char *table, char *geneName) /* Build a genePred list for the given table and gene name. */ { struct genePred *gpList = NULL; if (isCustomTrack(table)) { struct trackDb *tdb = getCustomTrackTdb(table); gpList = getGenePredForPositionBigGene(tdb, geneName); } -else if (isHubTrack(table)) - { - struct trackDb *tdb = hubConnectAddHubForTrackAndFindTdb( database, table, NULL, trackHash); - gpList = getGenePredForPositionBigGene(tdb, geneName); - } else { - struct trackDb *tdb = hashFindVal(trackHash, table); + struct trackDb *tdb = NULL; + if (isHubTrack(table)) + tdb = hubConnectAddHubForTrackAndFindTdb( database, table, NULL, trackHash); + else + tdb = hashFindVal(trackHash, table); char *bigDataUrl = trackDbSetting(tdb, "bigDataUrl"); if (bigDataUrl) gpList = getGenePredForPositionBigGene(tdb, geneName); else - gpList = getGenePredForPositionSql(table, geneName); + gpList = getGenePredForPositionSql(tdb, geneName); } return gpList; } void htcTranslatedPredMRna(char *geneName) /* Translate virtual mRNA defined by genePred to protein and display it. */ { char *table = cartString(cart, "table"); struct genePred *gp = NULL; char protName[256]; char *prot = NULL; cartHtmlStart("Protein Translation from Genome"); gp = getGenePredForPosition(table, geneName); @@ -9864,31 +9894,31 @@ { char *table = cartString(cart, "o"); struct dnaSeq *rnaSeq = getBaseColorSequence(itemName, table ); cartHtmlStart("RefSeq mRNA Sequence"); printf("
");
 printf(">%s\n", itemName);
 faWriteNext(stdout, NULL, rnaSeq->dna, rnaSeq->size);
 printf("
"); } void htcGeneMrna(char *geneName) /* Display cDNA predicted from genome */ { -char *table = cartString(cart, "o"); +char *table = cartString(cart, "table"); cartHtmlStart("Predicted mRNA from Genome"); struct genePred *gp, *gpList = getGenePredForPosition(table, geneName), *next; int cdsStart, cdsEnd; struct dnaSeq *seq; for(gp = gpList; gp; gp = next) { next = gp->next; seq = getCdnaSeq(gp); getCdsInMrna(gp, &cdsStart, &cdsEnd); toUpperN(seq->dna + cdsStart, cdsEnd - cdsStart); if (gp->strand[0] == '-') { reverseComplement(seq->dna, seq->size); } @@ -9915,31 +9945,31 @@ printf(""); dnaSeqFree(&seq); } void cartContinueRadio(char *var, char *val, char *defaultVal) /* Put up radio button, checking it if it matches val */ { char *oldVal = cartUsualString(cart, var, defaultVal); cgiMakeRadioButton(var, val, sameString(oldVal, val)); } void htcGeneInGenome(char *geneName) /* Put up page that lets user display genomic sequence * associated with gene. */ { -char *tbl = cgiString("o"); +char *tbl = cgiString("table"); cartWebStart(cart, database, "Genomic Sequence Near Gene"); printf("

Get Genomic Sequence Near Gene

"); puts("

" "Note: if you would prefer to get DNA for more than one feature of " "this track at a time, try the "); printf("", hgTablesUrl(FALSE, tbl)); puts("Table Browser using the output format sequence."); printf("

\n\n", hgcName()); cartSaveSession(cart); cgiMakeHiddenVar("g", "htcDnaNearGene"); cgiContinueHiddenVar("i"); printf("\n"); @@ -10075,58 +10105,60 @@ hti->hasCDS = TRUE; hti->hasBlocks = TRUE; hti->rootName = tdb->table; struct bed *bedList = getBedsFromBigBedRange(tdb, geneName); int itemCount = hgSeqBed(database, hti, bedList); freez(&hti); bedFreeList(&bedList); return itemCount; } void htcDnaNearGene( char *geneName) /* Fetch DNA near a gene. */ { cartWebStart(cart, database, "%s", geneName); -char *table = cartString(cart, "o"); +char *table = cartString(cart, "table"); int itemCount; puts("
");
 struct trackDb *tdb = NULL;
 
-if (isHubTrack(table))
-    {
-    tdb = hubConnectAddHubForTrackAndFindTdb( database, table, NULL, trackHash);
-    itemCount = getSeqForBigGene(tdb, geneName);
-    }
-else if (isCustomTrack(table))
+if (isCustomTrack(table))
     {
     tdb = getCustomTrackTdb(table);
     itemCount = getSeqForBigGene(tdb, geneName);
     }
 else
     {
+    if (isHubTrack(table))
+        tdb = hubConnectAddHubForTrackAndFindTdb( database, table, NULL, trackHash);
+    else
         tdb = hashFindVal(trackHash, table);
     char *bigDataUrl = trackDbSetting(tdb, "bigDataUrl");
     if (bigDataUrl)
         {
         itemCount = getSeqForBigGene(tdb, geneName);
         }
     else
         {
         char constraints[256];
         sqlSafef(constraints, sizeof(constraints), "name = '%s'", geneName);
-        itemCount = hgSeqItemsInRange(database, table, seqName, winStart, winEnd, constraints);
+        char *db = database;
+        char *liftDb = cloneString(trackDbSetting(tdb, "quickLiftDb"));
+        if (liftDb != NULL) 
+            db = liftDb;
+        itemCount = hgSeqItemsInRange(db, trackHubSkipHubName(table), seqName, winStart, winEnd, constraints);
         }
     }
 if (itemCount == 0)
     printf("\n# No results returned from query.\n\n");
 puts("
"); } void htcTrackHtml(struct trackDb *tdb) /* Handle click to display track html */ { cartWebStart(cart, database, "%s", tdb->shortLabel); printTrackHtml(tdb); } void doViralProt(struct trackDb *tdb, char *geneName)