995b57436b88ab94ba85bb54491a983fa96c7f70
braney
  Sat Aug 23 16:01:24 2014 -0700
bigGenePred support in track hubs limping along #13861
diff --git src/hg/hgTracks/bigBedTrack.c src/hg/hgTracks/bigBedTrack.c
index 31d8c59..e3789d5 100644
--- src/hg/hgTracks/bigBedTrack.c
+++ src/hg/hgTracks/bigBedTrack.c
@@ -132,59 +132,105 @@
 char* restField(struct bigBedInterval *bb, int fieldIdx) 
 /* return a given field from the bb->rest field, NULL on error */
 {
 if (fieldIdx==0) // we don't return the first(=name) field of bigBed
     return NULL;
 char *rest = cloneString(bb->rest);
 char *restFields[256];
 int restCount = chopTabs(rest, restFields);
 char *field = NULL;
 if (fieldIdx < restCount)
     field = cloneString(restFields[fieldIdx]);
 freeMem(rest);
 return field;
 }
 
+struct genePred  *genePredFromBigGenePred( char *chrom, struct bigBedInterval *bb)
+/* build a genePred from a bigGenePred */
+{
+char *extra = cloneString(bb->rest);
+int numCols = 12 + 8 - 3;
+char *row[numCols];
+int wordCount = chopByChar(extra, '\t', row, numCols);
+assert(wordCount == numCols);
+
+struct genePred *gp;
+AllocVar(gp);
+
+gp->chrom = chrom;
+gp->txStart = bb->start;
+gp->txEnd = bb->end;
+gp->name =  cloneString(row[ 0]);
+gp->strand[0] =  row[ 2][0];
+gp->strand[1] =  row[ 2][1];
+gp->cdsStart =  atoi(row[ 3]);
+gp->cdsEnd =  atoi(row[ 4]);
+gp->exonCount =  atoi(row[ 6]);
+int numBlocks;
+sqlUnsignedDynamicArray(row[ 8],  &gp->exonStarts, &numBlocks);
+assert (numBlocks == gp->exonCount);
+sqlUnsignedDynamicArray(row[ 7],  &gp->exonEnds, &numBlocks);
+assert (numBlocks == gp->exonCount);
+
+int ii;
+for(ii=0; ii < numBlocks; ii++)
+    {
+    gp->exonStarts[ii] += bb->start;
+    gp->exonEnds[ii] += gp->exonStarts[ii];
+    }
+
+gp->name2 = cloneString(row[ 9]);
+
+gp->cdsStartStat = parseCdsStat(row[ 10]);
+gp->cdsEndStat = parseCdsStat(row[ 11]);
+sqlSignedDynamicArray(row[ 12],  &gp->exonFrames, &numBlocks);
+assert (numBlocks == gp->exonCount);
+
+return gp;
+}
+
 void bigBedAddLinkedFeaturesFrom(struct track *track,
 	char *chrom, int start, int end, int scoreMin, int scoreMax, boolean useItemRgb,
 	int fieldCount, struct linkedFeatures **pLfList)
 /* Read in items in chrom:start-end from bigBed file named in track->bbiFileName, convert
  * them to linkedFeatures, and add to head of list. */
 {
 struct lm *lm = lmInit(0);
 struct trackDb *tdb = track->tdb;
 struct bigBedInterval *bb, *bbList = bigBedSelectRange(track, chrom, start, end, lm);
 char *bedRow[32];
 char startBuf[16], endBuf[16];
 char *scoreFilter = cartOrTdbString(cart, track->tdb, "scoreFilter", NULL);
 char *mouseOverField = cartOrTdbString(cart, track->tdb, "mouseOverField", NULL);
 int minScore = 0;
 if (scoreFilter)
     minScore = atoi(scoreFilter);
 
 int mouseOverIdx = bbExtraFieldIndex(tdb, mouseOverField);
 
 for (bb = bbList; bb != NULL; bb = bb->next)
     {
     char* mouseOver = restField(bb, mouseOverIdx);
     bigBedIntervalToRow(bb, chromName, startBuf, endBuf, bedRow, ArraySize(bedRow));
     struct bed *bed = bedLoadN(bedRow, fieldCount);
     struct linkedFeatures *lf = bedMungToLinkedFeatures(&bed, tdb, fieldCount,
     	scoreMin, scoreMax, useItemRgb);
     if (scoreFilter == NULL || lf->score >= minScore)
 	slAddHead(pLfList, lf);
     lf->mouseOver   = mouseOver; // leaks some memory, cloneString handles NULL ifself 
+    if (sameString(track->tdb->type, "bigGenePred"))
+	lf->original = genePredFromBigGenePred(chromName, bb); 
     }
 lmCleanup(&lm);
 }
 
 
 boolean canDrawBigBedDense(struct track *tg)
 /* Return TRUE if conditions are such that can do the fast bigBed dense data fetch and
  * draw. */
 {
 return tg->isBigBed;
 }
 
 
 void bigBedDrawDense(struct track *tg, int seqStart, int seqEnd,
         struct hvGfx *hvg, int xOff, int yOff, int width,