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("<b>CDS Start: </b> none (non-coding)<BR>\n"); printf("<b>CDS End: </b> none (non-coding)<BR>\n"); } else { printf("<b>CDS Start: </b>"); printCdsStatus((gp->strand[0] == '+') ? gp->cdsStartStat : gp->cdsEndStat); printf("<b>CDS End: </b>"); 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("<b>Prediction Class:</b> %s<br>\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("<PRE><TT>"); printf(">%s\n", itemName); faWriteNext(stdout, NULL, rnaSeq->dna, rnaSeq->size); printf("</TT></PRE>"); } 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("</TT></PRE>"); 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("<H2>Get Genomic Sequence Near Gene</H2>"); puts("<P>" "Note: if you would prefer to get DNA for more than one feature of " "this track at a time, try the "); printf("<A HREF=\"%s\" TARGET=_blank>", hgTablesUrl(FALSE, tbl)); puts("Table Browser</A> using the output format sequence."); printf("<FORM ACTION=\"%s\">\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("<PRE>"); 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("</PRE>"); } 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)