Index: /branches/eam_branches/ipp-20111122/Ohana/src/libdvo/src/flatcorr_io.c
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/libdvo/src/flatcorr_io.c	(revision 33113)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/libdvo/src/flatcorr_io.c	(revision 33114)
@@ -104,4 +104,5 @@
     MaxID = MAX(flatcorrTable->image[i].ID, MaxID);
   }
+  MaxID ++; // we want the outer bound, not the last value
 
   // generate the index and init values to -1
@@ -126,5 +127,5 @@
     assert (seq != -1);
 
-    flatcorrTable->offset[i][x][y] = flatcorrTable->corr[i].offset;      
+    flatcorrTable->offset[seq][x][y] = flatcorrTable->corr[i].offset;      
   }
 
@@ -142,4 +143,14 @@
   FTable ftableCorr;
   FILE *f;
+
+  FlatCorrectionImage *image;
+  FlatCorrection *corr;
+
+  // these output functions byteswap their buffers. make a copy for output
+  ALLOCATE (image, FlatCorrectionImage, flatcorrTable->Nimage);
+  memcpy (image, flatcorrTable->image, flatcorrTable->Nimage*sizeof(FlatCorrectionImage));
+
+  ALLOCATE (corr, FlatCorrection, flatcorrTable->Ncorr);
+  memcpy (corr, flatcorrTable->corr, flatcorrTable->Ncorr*sizeof(FlatCorrection));
 
   /* make phu header (no matrix needed) */
@@ -150,8 +161,8 @@
 
   ftableImage.header = &theaderImage;
-  gfits_table_set_FlatCorrectionImage (&ftableImage, flatcorrTable->image, flatcorrTable->Nimage);
+  gfits_table_set_FlatCorrectionImage (&ftableImage, image, flatcorrTable->Nimage);
 
   ftableCorr.header = &theaderCorr;
-  gfits_table_set_FlatCorrection (&ftableCorr, flatcorrTable->corr, flatcorrTable->Ncorr);
+  gfits_table_set_FlatCorrection (&ftableCorr, corr, flatcorrTable->Ncorr);
 
   f = fopen (filename, "w");
Index: /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/include/uniphot.h
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/include/uniphot.h	(revision 33113)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/include/uniphot.h	(revision 33114)
@@ -77,4 +77,17 @@
 time_t 	     TSTOP;
 PhotCode    *photcode;
+
+// hard-wired values which describe the ubercal analysis
+# define NFILTER 5
+# define NSEASON 4
+# define NCHIP_X 8
+# define NCHIP_Y 8
+# define NCELL_X 2
+# define NCELL_Y 2
+
+// these are initialized by initialize_setphot (in initialize.c)
+e_time tstart    [NSEASON];
+e_time tstop     [NSEASON];
+char   filter    [NFILTER];
 
 enum {black, white, red, orange, yellow, green, blue, indigo, violet};
Index: /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/ConfigInit.c
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/ConfigInit.c	(revision 33113)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/ConfigInit.c	(revision 33114)
@@ -7,6 +7,4 @@
   double ZERO_POINT;
   char  *config, *file;
-  char CatdirPhotcodeFile[256];
-  char MasterPhotcodeFile[256];
 
   /*** load configuration info ***/
@@ -23,5 +21,4 @@
   ScanConfig (config, "CATMODE",                "%s",  0, CATMODE);
   ScanConfig (config, "CATFORMAT",              "%s",  0, CATFORMAT);
-  ScanConfig (config, "PHOTCODE_FILE",         	"%s",  0, MasterPhotcodeFile);
 
   sprintf (ImageCat, "%s/Images.dat", CATDIR);
@@ -43,12 +40,4 @@
   if (*CATMODE == 0) strcpy (CATMODE, "RAW");
   if (*CATFORMAT == 0) strcpy (CATFORMAT, "ELIXIR");
-
-  /* XXX this does not yet write out the master photcode table */
-  sprintf (CatdirPhotcodeFile, "%s/Photcodes.dat", CATDIR);
-  if (!LoadPhotcodes (CatdirPhotcodeFile, MasterPhotcodeFile, TRUE)) {
-    fprintf (stderr, "error loading photcode table %s or master file %s\n", CatdirPhotcodeFile, MasterPhotcodeFile);
-    exit (1);
-  }
-
 }
 
Index: /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/args.c
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/args.c	(revision 33113)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/args.c	(revision 33114)
@@ -95,5 +95,10 @@
 
   if (argc != 2) {
-    fprintf (stderr, "ERROR: USAGE: setphot (zptfile) [options]\n");
+    fprintf (stderr, "USAGE: setphot (zptfile) [options]\n");
+    fprintf (stderr, "  options:\n");
+    fprintf (stderr, "    -v : verbose mode\n");
+    fprintf (stderr, "    -ubercal : interpret zpt file as a GPC1 ubercal FITS table\n");
+    fprintf (stderr, "    -update : actually write results to detections tables\n");
+    fprintf (stderr, "    Note that the dvo db can be specified by -D CATDIR (directory)\n");
     exit (2);
   } 
Index: /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/initialize.c
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/initialize.c	(revision 33113)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/initialize.c	(revision 33114)
@@ -23,7 +23,39 @@
 void initialize_setphot (int argc, char **argv) {
 
+  struct stat statbuffer;
+
+  char CatdirPhotcodeFile[256];
+
   /* are these set correctly? */
   ConfigInit (&argc, argv);
   args_setphot (argc, argv);
+
+  if (stat (CATDIR, &statbuffer)) {
+    fprintf (stderr, "error accessing dvo database directory '%s'\n", CATDIR);
+    exit (1);
+  }
+
+  /* XXX this does not yet write out the master photcode table */
+  sprintf (CatdirPhotcodeFile, "%s/Photcodes.dat", CATDIR);
+  if (!LoadPhotcodes (CatdirPhotcodeFile, NULL, TRUE)) {
+    fprintf (stderr, "error loading photcode table %s\n", CatdirPhotcodeFile);
+    exit (1);
+  }
+
+  // we have hard-coded the MJD season ranges from Eddie in uniphot.h
+
+  double tstart_mjd[] = {55000.0, 55296.0, 55327.0, 55662.0};
+  double tstop_mjd[]  = {55296.0, 55327.0, 55662.0, 60000.0};
+  filter[0] = 'g';
+  filter[1] = 'r';
+  filter[2] = 'i';
+  filter[3] = 'z';
+  filter[4] = 'y';
+
+  int i;
+  for (i = 0; i < NSEASON; i++) {
+    tstart[i] = ohana_mjd_to_sec(tstart_mjd[i]);
+    tstop[i]  = ohana_mjd_to_sec(tstop_mjd[i]);
+  }
 }
 
Index: /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/load_zpt_table.c
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/load_zpt_table.c	(revision 33113)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/load_zpt_table.c	(revision 33114)
@@ -41,16 +41,4 @@
   return zpts;
 }
-
-# define NFILTER 5
-# define NSEASON 4
-
-char   filter[NFILTER] = {'g', 'r', 'i', 'z', 'y'};
-double tstart[NSEASON] = {55000.0, 55296.0, 55327.0, 55662.0};
-double tstop[NSEASON]  = {55296.0, 55327.0, 55662.0, 60000.0};
-
-# define NCHIP_X 8
-# define NCHIP_Y 8
-# define NCELL_X 2
-# define NCELL_Y 2
 
 ZptTable *load_zpt_ubercal (char *filename, int *nzpts, FlatCorrectionTable *flatcorrTable) {
@@ -97,4 +85,5 @@
   ALLOCATE (flatcorrTable->corr, FlatCorrection, flatcorrTable->Ncorr);
   ALLOCATE (flatcorrTable->image, FlatCorrectionImage, flatcorrTable->Nimage);
+  memset (flatcorrTable->corr, 0, flatcorrTable->Ncorr*sizeof(FlatCorrection));
 
   int corrID = 1;
@@ -106,5 +95,5 @@
 
     // read the fits table bytes
-    if (gfits_fread_ftable_data (f, &ftable, FALSE)) return (NULL);
+    if (!gfits_fread_ftable_data (f, &ftable, FALSE)) return (NULL);
   
     // skip over remaining bytes in data segment
@@ -118,6 +107,6 @@
     assert (!strcmp(type, "double"));
       
-    double *zperr = gfits_get_bintable_column_data (&theader, &ftable, "resid", type, &Nrow, &Ncol);
-    assert (!strcmp(type, "double"));
+    float *zperr = gfits_get_bintable_column_data (&theader, &ftable, "resid", type, &Nrow, &Ncol);
+    assert (!strcmp(type, "float"));
       
     NZPTS += Nrow;
@@ -136,9 +125,16 @@
 
     // read the fits table bytes
-    if (gfits_fread_matrix (f, &matrix, FALSE)) return (NULL);
+    if (!gfits_fread_matrix (f, &matrix, &header)) return (NULL);
 
     for (nseason = 0; nseason < NSEASON; nseason++) { // seasons
       for (iy = 0; iy < NCHIP_Y; iy++) { // y-chip
 	for (ix = 0; ix < NCHIP_X; ix++) { // x-chip
+
+	  // photcode name
+	  char photname[64];
+	  snprintf (photname, 64, "GPC1.%c.XY%d%d", filter[nfilter], ix, iy);
+	  // note that the XY00, XY07, etc, chips will have photcode values of 0
+
+	  flatcorrTable->image[Nimage].photcode = GetPhotcodeCodebyName(photname);
 	  flatcorrTable->image[Nimage].Nx = NCELL_X;
 	  flatcorrTable->image[Nimage].Ny = NCELL_Y;
@@ -146,12 +142,4 @@
 	  flatcorrTable->image[Nimage].DX = 4880;
 	  flatcorrTable->image[Nimage].DY = 4864;
-	  flatcorrTable->image[Nimage].tstart = ohana_mjd_to_sec(tstart[nseason]);
-	  flatcorrTable->image[Nimage].tstop  = ohana_mjd_to_sec(tstop[nseason]);
-	  
-	  // photcode name
-	  char photname[64];
-	  snprintf (photname, 64, "GPC1.%c.XY%d%d", filter[nfilter], ix, iy);
-	  // note that the XY00, XY07, etc, chips will have photcode values of 0
-	  flatcorrTable->image[Nimage].photcode = GetPhotcodeCodebyName(photname);
 	  flatcorrTable->image[Nimage].tstart = tstart[nseason];
 	  flatcorrTable->image[Nimage].tstop  = tstop[nseason];
@@ -160,8 +148,9 @@
 	    for (ixc = 0; ixc < NCELL_X; ixc++) {
 	      if (ix > 3) {
-		seq = nfilter*NSEASON*NCHIP_X*NCHIP_Y*NCELL_X*NCELL_Y + nseason*NCHIP_X*NCHIP_Y*NCELL_X*NCELL_Y + (iy*NCELL_Y + NCELL_Y - 1 - iyc)*NCHIP_X + (ix*NCELL_X + NCELL_X - 1 - ixc);
+		seq = nfilter*NSEASON*NCHIP_X*NCHIP_Y*NCELL_X*NCELL_Y + nseason*NCHIP_X*NCHIP_Y*NCELL_X*NCELL_Y + (iy*NCELL_Y + NCELL_Y - 1 - iyc)*NCHIP_X*NCELL_X + (ix*NCELL_X + NCELL_X - 1 - ixc);
 	      } else {
-		seq = nfilter*NSEASON*NCHIP_X*NCHIP_Y*NCELL_X*NCELL_Y + nseason*NCHIP_X*NCHIP_Y*NCELL_X*NCELL_Y + (iy*NCELL_Y + iyc)*NCHIP_X + (ix*NCELL_X + ixc);
+		seq = nfilter*NSEASON*NCHIP_X*NCHIP_Y*NCELL_X*NCELL_Y + nseason*NCHIP_X*NCHIP_Y*NCELL_X*NCELL_Y + (iy*NCELL_Y + iyc)*NCHIP_X*NCELL_X + (ix*NCELL_X + ixc);
 	      }
+	      assert (!flatcorrTable->corr[seq].ID);
 	      flatcorrTable->corr[seq].x = ixc;
 	      flatcorrTable->corr[seq].y = iyc;
Index: /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/match_flatcorr_to_images.c
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/match_flatcorr_to_images.c	(revision 33113)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/match_flatcorr_to_images.c	(revision 33114)
@@ -1,3 +1,6 @@
 # include "uniphot.h"
+
+// the date/time of the image is used to find the 'season'
+// the photcode is used to find the actual flat correction
 
 int match_flatcorr_to_images (Image *image, off_t Nimage, FlatCorrectionTable *flatcorrTable) {
@@ -5,13 +8,54 @@
   int i, j;
 
+  // make 4 lookup tables for the photcodes (one for each season)
+
+  short **index;
+
+  short maxCode = 0;
+  for (i = 0; i < flatcorrTable->Nimage; i++) {
+    maxCode = MAX (maxCode, flatcorrTable->image[i].photcode);
+  }
+  maxCode ++; // we want the outer bound, not the last value
+
+  ALLOCATE (index, short *, NSEASON);
+  for (i = 0; i < NSEASON; i++) {
+      ALLOCATE (index[i], short, maxCode);
+      for (j = 0; j < maxCode; j++) {
+	index[i][j] = -1;
+      }
+  }
+
+  for (j = 0; j < NSEASON; j++) {
+    assert (tstart[j]);
+    assert (tstop[j]);
+  }
+
+  for (i = 0; i < flatcorrTable->Nimage; i++) {
+    // the flat-field correction is defined for non-existent images (eg, XY00)
+    // these have photcode == 0, so skip them
+    if (!flatcorrTable->image[i].photcode) continue;
+
+    // which season?
+    for (j = 0; j < NSEASON; j++) {
+      if (flatcorrTable->image[i].tstart == tstart[j]) {
+	assert (index[j][flatcorrTable->image[i].photcode] == -1);
+	index[j][flatcorrTable->image[i].photcode] = i;
+	break;
+      }
+    }
+  }
+
   for (i = 0; i < Nimage; i++) {
+    if (!image[i].photcode) continue; // skip PHU images
 
     int found = FALSE;
-    for (j = 0; !found && (j < flatcorrTable->Nimage); j++) {
+    for (j = 0; !found && (j < NSEASON); j++) {
+      if (image[i].tzero < tstart[j]) continue;
+      if (image[i].tzero > tstop[j]) continue;
 
-      if (image[i].tzero < flatcorrTable->image[j].tstart) continue;
-      if (image[i].tzero > flatcorrTable->image[j].tstop) continue;
-      if (image[i].photcode != flatcorrTable->image[j].photcode) continue;
-      image[i].photom_map_id = flatcorrTable->image[j].ID;
+      int seq = index[j][image[i].photcode];
+      if (seq == -1) break;
+
+      image[i].photom_map_id = flatcorrTable->image[seq].ID;
       found = TRUE;
     }
Index: /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/match_zpts_to_images.c
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/match_zpts_to_images.c	(revision 33113)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/match_zpts_to_images.c	(revision 33114)
@@ -42,6 +42,6 @@
   for (i = Nz = 0; (i < Nimage) && (Nz < Nzpts); ) {
 
-    if (i % 1000 == 0) fprintf (stderr, ".");
-    if (Nz % 100 == 0) fprintf (stderr, "!");
+    // if (i % 1000 == 0) fprintf (stderr, ".");
+    // if (Nz % 100 == 0) fprintf (stderr, "!");
 
     Ni = index[i];
