Index: /branches/eam_branches/ipp-20111122/Ohana/src/opihi/cmd.data/write_vectors.c
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/opihi/cmd.data/write_vectors.c	(revision 33130)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/opihi/cmd.data/write_vectors.c	(revision 33131)
@@ -7,5 +7,5 @@
   FILE *f;
   char **fmtlist, *fmttype;
-  char *p0, *p1, *p2, *format;
+  char *p0, *p1, *p2, *format, *FITS;
   Vector **vec;
 
@@ -18,4 +18,12 @@
   }
 
+  /* option generate a FITS output table */
+  FITS = NULL;
+  if ((N = get_argument (argc, argv, "-fits"))) {
+    remove_argument (N, &argc, argv);
+    FITS = strcreate (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
   append = FALSE;
   if ((N = get_argument (argc, argv, "-append"))) {
@@ -31,7 +39,7 @@
   /* open file for outuput */
   if (append) {
-      f = fopen (argv[1], "a");
+    f = fopen (argv[1], "a");
   } else {
-      f = fopen (argv[1], "w");
+    f = fopen (argv[1], "w");
   }
   if (f == (FILE *) NULL) {
@@ -43,8 +51,8 @@
   Nvec = (argc - 2);
   if (Nvec < 1) {
-      gprint (GP_ERR, "USAGE: write (file) vector vector ...\n");
-      fclose (f);
-  fflush (f);
-      return (FALSE);
+    gprint (GP_ERR, "USAGE: write (file) vector vector ...\n");
+    fclose (f);
+    fflush (f);
+    return (FALSE);
   }
   ALLOCATE (vec, Vector *, Nvec);
@@ -57,5 +65,5 @@
       free (vec);
       fclose (f);
-  fflush (f);
+      fflush (f);
       return (FALSE);    
     }
@@ -69,7 +77,109 @@
       free (vec);
       fclose (f);
-  fflush (f);
+      fflush (f);
       return (FALSE);    
     }
+  }
+
+  if (FITS) {
+    char *tformat = NULL;
+    Header header;
+    Matrix matrix;
+    Header theader;
+    FTable ftable;
+
+    if (!append) {
+      gfits_init_header (&header);
+      header.extend = TRUE;
+      gfits_create_header (&header);
+      gfits_create_matrix (&header, &matrix);
+    }
+
+    gfits_create_table_header (&theader, "BINTABLE", FITS);
+
+    ALLOCATE (tformat, char, 2*Nvec);
+    if (format) {
+      // the bintable format string can only define the byte-width of each field.  valid output columns are currently:
+      // B (char), I (16 bit short), J (32 bit int), E (32 bit float), D (64 bit double).
+      // the format string is just the sequence of types, eg: LIIJEED
+      // validate the format string
+      char *ptr = format;
+      for (j = 0; j < Nvec; j++) {
+	while (*ptr && OHANA_WHITESPACE (*ptr)) ptr++;
+	if (*ptr == 0) {
+	  gprint (GP_ERR, "error in binary table format %s (insufficient format chars)\n", format);
+	  goto escape;
+	}
+	if ((*ptr != 'B') && (*ptr != 'I') && (*ptr != 'J') && (*ptr != 'D') && (*ptr != 'E')) {
+	  gprint (GP_ERR, "error in binary table format %s: invalid character %c\n", format, *ptr);
+	  goto escape;
+	}
+	tformat[2*j + 0] = *ptr;
+	tformat[2*j + 1] = 0; // a bit sleazy : use a 2xN string to store N 1-byte strings
+	ptr ++;
+      }
+      while (*ptr && OHANA_WHITESPACE (*ptr)) ptr++;
+      if (*ptr) {
+	gprint (GP_ERR, "error in binary table format %s (extra characters in format)\n", format);
+	goto escape;
+      }
+    } else {
+      for (j = 0; j < Nvec; j++) {
+	// if the format is not defined, just use the native byte-widths
+	tformat[2*j + 0] = (vec[j][0].type == OPIHI_FLT) ? 'D' : 'J';
+	tformat[2*j + 1] = 0;
+      }
+    }
+
+    // define the columns of the table.  XXX NOTE: we cannot have duplicate names in
+    // output table (because the data goes to the named column below).  need to enforce
+    // this somehow
+    for (j = 0; j < Nvec; j++) {
+      gfits_define_bintable_column (&theader, &tformat[2*j], vec[j][0].name, NULL, NULL, 1.0, 0.0);
+    }
+    free (tformat);
+
+    // generate the output array that carries the data
+    gfits_create_table (&theader, &ftable);
+
+    // add the vectors to the output array
+    for (j = 0; j < Nvec; j++) {
+      if (vec[j][0].type == OPIHI_FLT) {
+	gfits_set_bintable_column_reformat (&theader, &ftable, vec[j][0].name, "double", vec[j][0].elements.Flt, vec[j][0].Nelements);
+      } else {
+	gfits_set_bintable_column_reformat (&theader, &ftable, vec[j][0].name, "int", vec[j][0].elements.Int, vec[j][0].Nelements);
+      }
+    }
+
+    if (!append) {
+      gfits_fwrite_header  (f, &header);
+      gfits_fwrite_matrix  (f, &matrix);
+      gfits_free_header (&header);
+      gfits_free_matrix (&matrix);
+    }
+    gfits_fwrite_Theader (f, &theader);
+    gfits_fwrite_table  (f, &ftable);
+
+    gfits_free_header (&theader);
+    gfits_free_table (&ftable);
+
+    fclose (f);
+    free (vec);
+    fflush (f);
+    return (TRUE);
+
+  escape:
+    if (!append) {
+      gfits_free_header (&header);
+      gfits_free_matrix (&matrix);
+    }
+    gfits_free_header (&theader);
+    gfits_free_table (&ftable);
+
+    if (tformat) free (tformat);
+    fclose (f);
+    free (vec);
+    fflush (f);
+    return (FALSE);
   }
 
@@ -88,5 +198,5 @@
     fclose (f);
     free (vec);
-  fflush (f);
+    fflush (f);
     return (TRUE);
   }
@@ -111,5 +221,5 @@
       free (format);
       fclose (f);
-  fflush (f);
+      fflush (f);
       return (FALSE);
     }
