b3c00af4551a848e3f6b83ed1e5fb41e12f039a1
braney
  Wed Feb 4 13:08:58 2015 -0800
add hgc and hgTables support for bigGenePred in custom tracks. #13861

diff --git src/hg/hgc/hgc.c src/hg/hgc/hgc.c
index 9b6ba86..bd93822 100644
--- src/hg/hgc/hgc.c
+++ src/hg/hgc/hgc.c
@@ -8029,57 +8029,75 @@
 int rowOffset = hOffsetPastBin(database, seqName, table);
 
 sqlSafef(query, sizeof(query), "select * from %s where name = \"%s\"", 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 *getGenePredForPositionBigBed(char *table, char *geneName)
-/* find the genePred to the current gene using a bigGenePred */
+struct genePred *getGenePredForPositionBigGene(struct trackDb *tdb,  char *geneName)
+/* Find the genePred to the current gene using a bigGenePred. */
 {
-struct trackDb *tdb = hubConnectAddHubForTrackAndFindTdb( database, table, NULL, trackHash);
-struct bbiFile *bbi;
 char *fileName = cloneString(trackDbSetting(tdb, "bigDataUrl"));
-bbi = bigBedFileOpen(fileName);
+struct bbiFile *bbi = bigBedFileOpen(fileName);
 struct lm *lm = lmInit(0);
 struct bigBedInterval *bb, *bbList = bigBedIntervalQuery(bbi, seqName, winStart, winEnd, 0, lm);
 struct genePred *gpList = NULL;
 for (bb = bbList; bb != NULL; bb = bb->next)
     {
     struct genePred *gp = genePredFromBigGenePred(seqName, bb); 
     if (sameString(gp->name, geneName))
 	slAddHead(&gpList, gp);
     }
 lmCleanup(&lm);
 
 return gpList;
 }
 
+static struct trackDb *getCustomTrackTdb(char *table)
+/* Find the trackDb structure for a custom track table. */
+{
+struct customTrack *ctList = getCtList();
+struct customTrack *ct = NULL;
+for (ct = ctList; ct != NULL; ct = ct->next)
+    if (sameString(table, ct->tdb->track))
+	return  ct->tdb;
+return NULL;
+}
+
 static struct genePred *getGenePredForPosition(char *table, char *geneName)
+/* Build a genePred list for the given table and gene name. */
 {
 struct genePred *gpList = NULL;
 
-if (isHubTrack(table))
-    gpList =  getGenePredForPositionBigBed(table, geneName);
+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
     gpList =  getGenePredForPositionSql(table, 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");
@@ -8364,73 +8382,87 @@
     s = gp->exonStarts[exonIx];
     e = gp->exonEnds[exonIx];
     if (s < seqStart) s = seqStart;
     if (e > seqEnd) e = seqEnd;
     if ((size = e - s) > 0)
 	{
 	s -= startOffset;
 	if (s < 0 ||  s + size > seq->size)
 	    errAbort("Out of range! %d-%d not in %d-%d", s, s+size, 0, size);
 	toUpperN(seq->dna + s, size);
 	}
     }
 }
 
 
-static struct bed *getBedsFromBigBedRange(char *table, char *geneName)
+static struct bed *getBedsFromBigBedRange(struct trackDb *tdb, char *geneName)
 /* get a list of beds from a bigBed in the current range */
 {
-struct trackDb *tdb = hubConnectAddHubForTrackAndFindTdb( database, table, NULL, trackHash);
 struct bbiFile *bbi;
 char *fileName = cloneString(trackDbSetting(tdb, "bigDataUrl"));
 bbi = bigBedFileOpen(fileName);
 struct lm *lm = lmInit(0);
 struct bigBedInterval *bb, *bbList = bigBedIntervalQuery(bbi, seqName, winStart, winEnd, 0, lm);
 struct bed *bedList = NULL;
 char *bedRow[32];
 char startBuf[16], endBuf[16];
 for (bb = bbList; bb != NULL; bb = bb->next)
     {
     bigBedIntervalToRow(bb, seqName, startBuf, endBuf, bedRow, ArraySize(bedRow));
     struct bed *bed = bedLoadN(bedRow, 12);
     if (sameString(bed->name, geneName))
 	slAddHead(&bedList, bed);
     }
 lmCleanup(&lm);
 
 return bedList;
 }
 
+static int getSeqForBigGene(struct trackDb *tdb, char *geneName)
+/* Output sequence for a gene in a bigGenePred file. */
+{
+struct hTableInfo *hti;
+AllocVar(hti);
+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. */
 {
 char *table    = cartString(cart, "o");
 int itemCount;
 char *quotedItem = makeQuotedString(geneName, '\'');
 puts("<PRE>");
+struct trackDb *tdb = NULL;
+
 if (isHubTrack(table))
     {
-    struct hTableInfo *hti;
-    AllocVar(hti);
-    hti->hasCDS = TRUE;
-    hti->hasBlocks = TRUE;
-    hti->rootName = table;
-
-    struct bed *bedList = getBedsFromBigBedRange(table, geneName);
-    itemCount = hgSeqBed(database, hti, bedList);
-    freez(&hti);
-    bedFreeList(&bedList);
+    tdb = hubConnectAddHubForTrackAndFindTdb( database, table, NULL, trackHash);
+    itemCount = getSeqForBigGene(tdb, geneName);
+    }
+else if (isCustomTrack(table))
+    {
+    tdb = getCustomTrackTdb(table);
+    itemCount = getSeqForBigGene(tdb, geneName);
     }
 else
     {
     char constraints[256];
     safef(constraints, sizeof(constraints), "name = %s", quotedItem);
     itemCount = hgSeqItemsInRange(database, table, seqName, winStart, winEnd, constraints);
     }
 if (itemCount == 0)
     printf("\n# No results returned from query.\n\n");
 puts("</PRE>");
 freeMem(quotedItem);
 }
 
 void htcTrackHtml(struct trackDb *tdb)
 /* Handle click to display track html */
@@ -20465,31 +20497,31 @@
 for (ct = ctList; ct != NULL; ct = ct->next)
     if (sameString(trackId, ct->tdb->track))
 	break;
 if (ct == NULL)
     errAbort("Couldn't find '%s' in '%s'", trackId, fileName);
 type = ct->tdb->type;
 cartWebStart(cart, database, "Custom Track: %s", ct->tdb->shortLabel);
 itemName = skipLeadingSpaces(fileItem);
 printf("<H2>%s</H2>\n", ct->tdb->longLabel);
 if (sameWord(type, "array"))
     doExpRatio(ct->tdb, fileItem, ct);
 else if (sameWord(type, "encodePeak"))
     doEncodePeak(ct->tdb, ct, fileName);
 else if (sameWord(type, "bigWig"))
     bigWigCustomClick(ct->tdb);
-else if (sameWord(type, "bigBed"))
+else if (sameWord(type, "bigBed") || sameWord(type, "bigGenePred"))
     bigBedCustomClick(ct->tdb);
 #ifdef USE_BAM
 else if (sameWord(type, "bam"))
     doBamDetails(ct->tdb, itemName);
 #endif//def USE_BAM
 #ifdef USE_TABIX
 else if (sameWord(type, "vcfTabix"))
     doVcfTabixDetails(ct->tdb, itemName);
 #endif//def USE_TABIX
 else if (sameWord(type, "vcf"))
     doVcfDetails(ct->tdb, itemName);
 else if (sameWord(type, "makeItems"))
     doMakeItemsDetails(ct, fileName);	// fileName is first word, which is, go figure, id
 else if (ct->wiggle)
     {