9fca4abba527b0c750c062e1e6aa8cc9fe2e44a4
angie
  Fri Aug 21 12:37:41 2015 -0700
Make sure the #header line begins with a '#' and not a '\t' in the unlikely event that all fields of the primary streamer (or even of all streamers) are deselected.

diff --git src/lib/annoFormatTab.c src/lib/annoFormatTab.c
index 06259e7..bbd84b6 100644
--- src/lib/annoFormatTab.c
+++ src/lib/annoFormatTab.c
@@ -42,68 +42,70 @@
 static boolean columnIsIncluded(struct annoFormatTab *self, char *sourceName, char *colName)
 // Return TRUE if column has not been explicitly deselected.
 {
 if (self->columnVis)
     {
     char fullName[PATH_LEN];
     makeFullColumnName(fullName, sizeof(fullName), sourceName, colName);
     int vis = hashIntValDefault(self->columnVis, fullName, 1);
     if (vis == 0)
         return FALSE;
     }
 return TRUE;
 }
 
 static void printHeaderColumns(struct annoFormatTab *self, struct annoStreamer *source,
-                               boolean isFirst)
+                               boolean *pIsFirst)
 /* Print names of included columns from this source. */
 {
 FILE *f = self->f;
 char *sourceName = source->name;
+boolean isFirst = (pIsFirst && *pIsFirst);
 struct asColumn *col;
 for (col = source->asObj->columnList;  col != NULL;  col = col->next)
     {
     if (columnIsIncluded(self, sourceName, col->name))
         {
         if (isFirst)
-            {
-            fputc('#', f);
             isFirst = FALSE;
-            }
         else
             fputc('\t', f);
         char fullName[PATH_LEN];
         makeFullColumnName(fullName, sizeof(fullName), sourceName, col->name);
         fputs(fullName, f);
         }
     }
+if (pIsFirst != NULL)
+    *pIsFirst = isFirst;
 }
 
 static void aftInitialize(struct annoFormatter *vSelf, struct annoStreamer *primary,
 			  struct annoStreamer *integrators)
 /* Print header, regardless of whether we get any data after this. */
 {
 struct annoFormatTab *self = (struct annoFormatTab *)vSelf;
 if (self->needHeader)
     {
     char *primaryHeader = primary->getHeader(primary);
+    boolean isFirst = TRUE;
     if (isNotEmpty(primaryHeader))
 	fprintf(self->f, "# Header from primary input:\n%s", primaryHeader);
-    printHeaderColumns(self, primary, TRUE);
+    fputc('#', self->f);
+    printHeaderColumns(self, primary, &isFirst);
     struct annoStreamer *grator;
     for (grator = integrators;  grator != NULL;  grator = grator->next)
-	printHeaderColumns(self, grator, FALSE);
+	printHeaderColumns(self, grator, &isFirst);
     fputc('\n', self->f);
     self->needHeader = FALSE;
     }
 }
 
 static char **bed4WordsFromAnnoRow(struct annoRow *row, char *fourth)
 /* Return an array of 4 words with row's chrom, chromStart, and chromEnd, and cloned fourth. */
 {
 char **words;
 AllocArray(words, 4);
 words[0] = cloneString(row->chrom);
 char buf[PATH_LEN];
 safef(buf, sizeof(buf), "%u", row->start);
 words[1] = cloneString(buf);
 safef(buf, sizeof(buf), "%u", row->end);