Index: /branches/eam_branches/ipp-20111122/Ohana/src/libautocode/def/FlatCorrection.d
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/libautocode/def/FlatCorrection.d	(revision 33102)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/libautocode/def/FlatCorrection.d	(revision 33103)
@@ -2,9 +2,8 @@
 EXTNAME FLAT_CORRECTION
 TYPE    BINTABLE
-SIZE    16
+SIZE    20
 
+FIELD   ID,	   ID,	           int
 FIELD   x,	   X,	           int
 FIELD   y,	   Y,	           int
-FIELD   offst,     OFFSET,	   float
-FIELD   photcode,  PHOTCODE,	   short
-FIELD   padding,   PADDING,	   short
+FIELD   offset,    OFFSET,	   float
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 33102)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/libdvo/src/flatcorr_io.c	(revision 33103)
@@ -12,8 +12,8 @@
 typedef struct {
     int Nimage;
-    FlatCorrectionImage *flatcorrImage;
-
-    int Nflatcorr;
-    FlatCorrection *flatcorr;
+    FlatCorrectionImage *image;
+    int Ncorr;
+    FlatCorrection *corr;
+    float ***offset; // the correction images represented as a set of arrays (same sequence as *image)
 } FlatCorrectionTable;
 
@@ -25,6 +25,6 @@
   Header theader;
   FTable ftable;
-  int i, Nflatcorr;
-  FlatCorrection *flatcorr;
+  int i;
+  FlatCorrectionTable *flatcorrTable;
   
   f = fopen (filename, "r");
@@ -47,19 +47,22 @@
     return (NULL);
   }
-  if (!gfits_fread_ftable (f, &ftable, "FLAT_CORRECTION")) {
+
+  ALLOCATE (flatcorrTable, FlatCorrectionTable, 1);
+
+  if (!gfits_fread_ftable (f, &ftable, "FLAT_CORRECTION_IMAGE")) {
     if (VERBOSE) fprintf (stderr, "can't read Flat Correction table\n");
     gfits_free_header (&header);
     gfits_free_matrix (&matrix);
+    free (flatcorrTable);
     fclose (f);
     return (NULL);
   }
-
-  ALLOCATE (flatcorrTable, FlatCorrectionTable, 1);
-
-  flatcorrTable.images = gfits_table_get_FlatCorrectionImage (&ftable, &flatcorrTable.Nimage, NULL);
-  if (!skytable[0].regions) {
-    fprintf (stderr, "ERROR: failed to read sky regions\n");
+  flatcorrTable->image = gfits_table_get_FlatCorrectionImage (&ftable, &flatcorrTable->Nimage, NULL);
+  if (!flatcorrTable->image) {
+    fprintf (stderr, "ERROR: failed to read Flat Correction Images\n");
     exit (2);
   }
+  gfits_free_header (&theader);
+  // NOTE: do not free ftable or the data will be freed
 
   if (!gfits_fread_ftable (f, &ftable, "FLAT_CORRECTION")) {
@@ -70,8 +73,7 @@
     return (NULL);
   }
-
-  flatcorrTable.images = gfits_table_get_FlatCorrectionImage (&ftable, &flatcorrTable.Nimage, NULL);
-  if (!skytable[0].regions) {
-    fprintf (stderr, "ERROR: failed to read sky regions\n");
+  flatcorrTable->corr = gfits_table_get_FlatCorrection (&ftable, &flatcorrTable->Ncorr, NULL);
+  if (!flatcorrTable->corr) {
+    fprintf (stderr, "ERROR: failed to read Flat Corrections\n");
     exit (2);
   }
@@ -80,18 +82,55 @@
   gfits_free_matrix (&matrix);
   gfits_free_header (&theader);
+  // NOTE: do not free ftable or the data will be freed
 
-  return (flatcorr);
+  // convert the table format to map format:
+
+  // generate the arrays to hold the corrections
+  ALLOCATE (flatcorrTable->offset, float **, flatcorrTable->Nimage);
+  for (i = 0; i < flatcorrTable->Nimage; i++) {
+      ALLOCATE (flatcorrTable->offset[i], float *, flatcorrTable->image[i]->Nx);
+      for (j = 0; j < flatcorrTable->image[i]->Nx; j++) {
+	  ALLOCATE (flatcorrTable->offset[i][j], float, flatcorrTable->image[i]->Ny);
+	  memset (flatcorrTable->offset[i][j], 0.0, flatcorrTable->image[i]->Ny*sizeof(float));
+      }
+  }
+
+  // create the lookup table (ID -> Seq)
+  ALLOCATE (flatcorrTable->IDtoSeq, int, MaxID);
+  for (i = 0; i < flatcorrTable->Nimage; i++) {
+      flatcorrTable->IDtoSeq[i] = -1;
+  }
+  for (i = 0; i < flatcorrTable->Nimage; i++) {
+      ID = flatcorrTable->image[i].ID;
+      assert (flatcorrTable->IDtoSeq[ID] == -1);
+      flatcorrTable->IDtoSeq[ID] = i;
+  }
+
+  // assign the known specific correction values
+  for (i = 0; i < flatcorrTable->Ncorr; i++) {
+      ID = flatcorrTable->corr[i].ID;
+      x = flatcorrTable->corr[i].x;
+      y = flatcorrTable->corr[i].y;
+      seq = flatcorrTable->IDtoSeq[ID];
+      assert (seq != -1);
+
+      flatcorrTable->offset[i][x][y] = flatcorrTable->corr[i].offset;      
+  }
+
+  return (flatcorrTable);
 }
 
-int SkyTableSave (SkyTable *skytable, char *filename) {
+int FlatCorrectionSave (FlatCorrectionTable *flatcorrTable, char *filename) {
 
   Header header;
   Matrix matrix;
-  Header theader;
-  FTable ftable;
+  Header theaderImage;
+  FTable ftableImage;
+
+  Header theaderCorr;
+  FTable ftableCorr;
   FILE *f;
 
   /* make phu header (no matrix needed) */
-  ftable.header = &theader;
   gfits_init_header (&header);
   header.extend = TRUE;
@@ -99,5 +138,9 @@
   gfits_create_matrix (&header, &matrix);
 
-  gfits_table_set_SkyRegion (&ftable, skytable[0].regions, skytable[0].Nregions);
+  ftableImage.header = &theaderImage;
+  gfits_table_set_FlatCorrectionImage (&ftableImage, flatcorrTable->image, flatcorrTable->Nimage);
+
+  ftableCorr.header = &theaderCorr;
+  gfits_table_set_FlatCorrectionCorr (&ftableCorr, flatcorrTable->corr, flatcorrTable->Ncorr);
 
   f = fopen (filename, "w");
@@ -109,6 +152,8 @@
   gfits_fwrite_header  (f, &header);
   gfits_fwrite_matrix  (f, &matrix);
-  gfits_fwrite_Theader (f, &theader);
-  gfits_fwrite_table  (f, &ftable);
+  gfits_fwrite_Theader (f, &theaderImage);
+  gfits_fwrite_table  (f, &ftableImage);
+  gfits_fwrite_Theader (f, &theaderCorr);
+  gfits_fwrite_table  (f, &ftableCorr);
   fclose (f);
 
@@ -116,93 +161,19 @@
 }
 
-SkyTable *SkyTableLoadOptimal (char *catdir, char *skyfile, char *gscfile, int readwrite, int depth, int verbose) {
+float FlatCorrectionOffset (FlatCorrectionTable *flatcorr, int ID, int X, int Y) {
 
-  char filename[256];
-  struct stat filestat;
-  SkyTable *sky;
+    // validate the flat_id (not out of range?)
+    seq = flatcorr->IDtoSeq[ID];
 
-  /* first option: CATDIR/SkyTable.fits */
-  sprintf (filename, "%s/SkyTable.fits", catdir);
-  if (stat (filename, &filestat)) goto SKYFILE;
-  if (!check_file_access (filename, FALSE, readwrite, verbose)) goto SKYFILE;
-  sky = SkyTableLoad (filename, verbose);
-  if (sky == NULL) {
-    fprintf (stderr, "error loading sky table\n");
-    exit (1);
-  }
-  return (sky);
+    // convert X,Y to Xbin, Ybin:
+    Xbin = MAX(MIN(X / flatcorr->image[seq].DX, flatcorr->image[seq].NX - 1), 0);
+    Ybin = MAX(MIN(Y / flatcorr->image[seq].DY, flatcorr->image[seq].NY - 1), 0);
 
-SKYFILE:
-  /* second option: SKYFILE */
-  if (skyfile == NULL) goto GSCFILE;
-  if (skyfile[0] != 0) goto GSCFILE;
-  if (stat (skyfile, &filestat)) goto GSCFILE;
-  if (!check_file_access (skyfile, FALSE, readwrite, verbose)) goto GSCFILE;
-  sky = SkyTableLoad (skyfile, verbose);
-  if (sky == NULL) {
-    fprintf (stderr, "error loading sky table\n");
-    return (NULL);
-  }
-  /* set the depths to the default depth */
-  SkyTableSetDepth (sky, depth);
+    // XXX warn if X,Y are out of range? not super important unless *way* out of range
 
-  /* create CATDIR copy */
-  sprintf (filename, "%s/SkyTable.fits", catdir);
-  check_file_access (filename, FALSE, readwrite, verbose);
-  if (!SkyTableSave (sky, filename)) return NULL;
-
-  gfits_convert_SkyRegion (sky[0].regions, sizeof (SkyTable), sky[0].Nregions);
-  return (sky);
-
-GSCFILE:
-
-  /* third option: GSCFILE */
-
-  if (gscfile == NULL) {
-    fprintf (stderr, "error loading sky table from existing db (%s)\n", catdir);
-    return (NULL);
-  }
-
-  sky = SkyTableFromGSC (gscfile, depth, verbose);
-  if (sky == NULL) {
-    fprintf (stderr, "error loading sky table\n");
-    return (NULL);
-  }
-
-  /* create CATDIR copy */
-  sprintf (filename, "%s/SkyTable.fits", catdir);
-  check_file_access (filename, FALSE, readwrite, verbose);
-  if (!SkyTableSave (sky, filename)) return NULL;
-
-  gfits_convert_SkyRegion (sky[0].regions, sizeof (SkyRegion), sky[0].Nregions);
-  return (sky);
+    offset = flatcorr->offset[seq][Xbin][Ybin];
+    return offset;
 }
 
-int SkyListSetFilenames (SkyList *list, char *path, char *ext) {
-
-  int i;
-  char line[256];
-
-  // this generates the names, be sure to free when not needed
-  for (i = 0; i < list[0].Nregions; i++) {
-    sprintf (line, "%s/%s.%s", path, list[0].regions[i][0].name, ext);
-    list[0].filename[i] = strcreate (line);
-  }
-
-  return (TRUE);
-}
-
-int SkyTableSetFilenames (SkyTable *sky, char *path, char *ext) {
-
-  int i;
-  char line[256];
-
-  // this generates the names, be sure to free when not needed
-  for (i = 0; i < sky[0].Nregions; i++) {
-    sprintf (line, "%s/%s.%s", path, sky[0].regions[i].name, ext);
-    sky[0].filename[i] = strcreate (line);
-  }
-
-  return (TRUE);
-}
-
+// other needed operations:
+// * assign an image to a flatcorr (based on photcode and obs_date)
Index: /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/args.c
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/args.c	(revision 33102)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/args.c	(revision 33103)
@@ -82,4 +82,10 @@
   }
 
+  UBERCAL = FALSE;
+  if ((N = get_argument (argc, argv, "-ubercal"))) {
+    remove_argument (N, &argc, argv);
+    UBERCAL = TRUE;
+  }
+
   UPDATE = FALSE;
   if ((N = get_argument (argc, argv, "-update"))) {
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 33102)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/load_zpt_table.c	(revision 33103)
@@ -41,2 +41,86 @@
   return zpts;
 }
+
+ZptTable *load_zpt_ubercal (char *filename, int *nzpts) {
+
+  int Nzpts, NZPTS;
+  ZptTable *zpts;
+  double zpt, mjd, zpt_err;
+
+  FILE *f;
+
+  f = fopen (filename, "r");
+  if (!f) {
+    fprintf (stderr, "ERROR: cannot open zpt table file %s\n", filename);
+    exit (1);
+  }
+
+  /* load in PHU segment (ignore) */
+  ftable.header = &theader;
+  if (!gfits_fread_header (f, &header)) {
+    if (VERBOSE) fprintf (stderr, "can't read Flat Correction header\n");
+    fclose (f);
+    return (NULL);
+  }
+  if (!gfits_fread_matrix (f, &matrix, &header)) {
+    if (VERBOSE) fprintf (stderr, "can't read Flat Correction matrix\n");
+    gfits_free_header (&header);
+    fclose (f);
+    return (NULL);
+  }
+
+  Nzpts = 0;
+  NZPTS = 0;
+  ALLOCATE (zpts, ZptTable, NZPTS);
+
+  ALLOCATE (flatcorr, FlatCorrection, 4*5*X);
+
+  for (i = 0; i < 5; i++) {
+      // load data for this header 
+      if (!gfits_load_header (f, &theader)) return (FALSE);
+
+      // read the fits table bytes
+      if (gfits_fread_ftable_data (f, &table, FALSE)) return (TRUE);
+  
+      // skip over remaining bytes in data segment
+      fseeko (f, table[0].datasize - table[0].validsize, SEEK_CUR);
+
+      // load data for this header 
+      if (!gfits_load_header (f, &header)) return (FALSE);
+
+      // read the fits table bytes
+      if (gfits_fread_matrix (f, &matrix, FALSE)) return (TRUE);
+
+      // need to create and assign to flat-field correction
+      double *mjd = gfits_get_bintable_column_data (header, table, "mjd_obs", &type, &Nrow, &Ncol);
+      assert (!strcmp(type, "double"));
+
+      double *zpts = gfits_get_bintable_column_data (header, table, "zp", &type, &Nrow, &Ncol);
+      assert (!strcmp(type, "double"));
+      
+      double *zperr = gfits_get_bintable_column_data (header, table, "resid", &type, &Nrow, &Ncol);
+      assert (!strcmp(type, "double"));
+      
+      NZPTS += Nrow;
+      REALLOCATE (zpts, ZptTable, NZPTS);
+      for (i = 0; i < Nrow; i++) {
+	  zpts[i+Nzpts].time = ohana_mjd_to_sec(mjd[i]);
+	  zpts[i+Nzpts].zpt = zp[i];
+	  zpts[i+Nzpts].zpt_err = zperr[i];
+      }
+      Nzpts += Nrow;
+
+      // the image is the flat-field correction.  
+      // need to byteswap or whatever
+  }
+
+  if (status != EOF) {
+    fprintf (stderr, "unexpected formatting on line %d\n", Nzpts);
+    exit (2);
+  }
+
+  fprintf (stderr, "loaded %d zero points\n", Nzpts);
+
+  *nzpts = Nzpts;
+  return zpts;
+}
Index: /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/setphot.c
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/setphot.c	(revision 33102)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/setphot.c	(revision 33103)
@@ -17,5 +17,9 @@
   if (db.dbstate == LCK_EMPTY) Shutdown ("ERROR: No images in catalog %s (1)", db.filename);
 
-  zpts = load_zpt_table (argv[1], &Nzpts);
+  if (UBERCAL) {
+    zpts = load_zpt_ubercal (argv[1], &Nzpts);
+  } else {
+    zpts = load_zpt_table (argv[1], &Nzpts);
+  }
 
   // load images 
@@ -39,10 +43,23 @@
    setphot (zpt_table)
 
- * load text table of zpts, time (photcode?)
- * load images
- * match images to zpts
- * set zpts
- * load catalogs
- * update detection (& averages?)
+   setphot has 2 modes : basic & ubercal
+
+   * outline of basic mode:
+
+   ** load text table of zpts, time (photcode?)
+   ** load images
+   ** match images to zpts
+   ** set zpts
+   ** load catalogs
+   ** update detection (& averages?)
+
+   * outline of ubercal mode:
+
+   ** load fits table of zpts & time + table of flat-field corrections
+   ** load images
+   ** match images to zpts
+   ** set zpts
+   ** load catalogs
+   ** update detection (& averages?)
 
  */
Index: /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/update_catalog_setphot.c
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/update_catalog_setphot.c	(revision 33102)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/update_catalog_setphot.c	(revision 33103)
@@ -71,5 +71,5 @@
 }      
 
-void update_catalog_setphot (Catalog *catalog, Image *image, off_t *index, off_t Nimage) {
+void update_catalog_setphot (Catalog *catalog, Image *image, off_t *index, off_t Nimage, FlatCorrectionTable *flatcorr) {
 
   off_t i, j, m, id, idx, found;
@@ -87,6 +87,13 @@
       Mcal = image[id].Mcal;
       dMcal = image[id].dMcal;
+      Mcal_offset = 0.0;
 
-      catalog[0].measure[m].Mcal = Mcal;
+      // if we know about a flat-field correction, then we need to apply the sub-chip correction
+      flat_id = image[id].photom_map_id;
+      if (flat_id > 0) {
+	  Mcal_offset = FlatCorrectionOffset (flatcorr, flat_id, catalog[0].measure[m].Xccd, catalog[0].measure[m].Yccd);
+      }
+
+      catalog[0].measure[m].Mcal = Mcal + Mcal_offset;
       catalog[0].measure[m].dMcal = dMcal;
       found ++;
