08aead3b5144f452ce6889352e7ea3019e4d3f38
galt
  Mon Feb 24 15:56:03 2014 -0800
Fixes #12737. Had to be more careful about custom tracks and hubs etc. This should now work on a wide variety of file types
diff --git src/hg/hgTables/gffOut.c src/hg/hgTables/gffOut.c
index bcfb57c..df3ccdc 100644
--- src/hg/hgTables/gffOut.c
+++ src/hg/hgTables/gffOut.c
@@ -373,61 +373,71 @@
 	);
     char *exonFrames = sqlQuickString(conn, sql);
     slNameAddHead(&list, exonFrames);
     dyStringFree(&exonStarts);
     dyStringFree(&exonEnds);
     }
 slReverse(&list);
 return list;
 }
 
 static struct hash *makeChromHashForTable(struct sqlConnection *conn, char *table)
 /* Get a hash of all the chroms that are actually being used for the table.
  * This is helpful for assemblies with huge numbers of chroms. */
 {
 char query[1024];
+// Make sure that the table has a chrom field.
+// a bbi table will NOT have a chrom field
+int cIdx = sqlFieldIndex(conn, table, "chrom");
+if (cIdx < 0)
+    return NULL;
 sqlSafef(query, sizeof query, "select distinct chrom, 'dummyvalue' from %s", table);
 struct hash *hash = sqlQuickHash(conn, query);
 return hash;
 }
 
 void doOutGff(char *table, struct sqlConnection *conn, boolean outputGtf)
 /* Save as GFF/GTF. */
 {
 struct hTableInfo *hti = getHti(database, table, conn);
 struct bed *bedList;
 struct slName *exonFramesList = NULL;
 char source[HDB_MAX_TABLE_STRING];
 int itemCount;
 struct region *region, *regionList = getRegions();
 
 textOpen();
 
+boolean simpleTableExists = sqlTableExists(conn, table);
+// simpleTable means not split table, not custom track
+// However it still can include bbi table with bam fileName path
 int efIdx = -1;
-if (!hti->isSplit)
+if (simpleTableExists)  // no tables having exonFrames are split tables anyway
     efIdx = sqlFieldIndex(conn, table, "exonFrames");
-
 safef(source, sizeof(source), "%s_%s", database, table);
 itemCount = 0;
-// regionList can have many thousands of items e.g. rheMac3 has 34000 chroms!
 struct hash *chromHash = NULL;
 int regionCount = slCount(regionList);
-if (!hti->isSplit && (regionCount > 400))
+// regionList can have many thousands of items e.g. rheMac3 has 34000 chroms!
+// This regionCount threshold should be just above the # chroms in the latest human assembly
+if (simpleTableExists && (regionCount > 500))  
     {
     chromHash = makeChromHashForTable(conn, table);
     };
+// Process each region
 for (region = regionList; region != NULL; region = region->next)
     {
     if (chromHash && (!hashFindVal(chromHash, region->chrom)))
 	    continue;
     struct lm *lm = lmInit(64*1024);
     int fieldCount;
     bedList = cookedBedList(conn, table, region, lm, &fieldCount);
+    // Use exonFrames field if available for better accuracy instead of calculating from coordinates
     if (efIdx != -1) 
 	exonFramesList = getExonFrames(table, conn, bedList);
     itemCount += bedToGffLines(bedList, exonFramesList, hti, fieldCount, source, outputGtf);
     lmCleanup(&lm);
     }
 if (itemCount == 0)
     hPrintf(NO_RESULTS);
 }