Index: /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/include/setphot.h
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/include/setphot.h	(revision 33328)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/include/setphot.h	(revision 33329)
@@ -69,2 +69,5 @@
 ZptTable     *load_zpt_ubercal_nometadata PROTO((char *filename, int *nzpts, FlatCorrectionTable *flatcorrTable));
 int           match_flatcorr_to_images    PROTO((Image *image, off_t Nimage, FlatCorrectionTable *flatcorrTable));
+
+int           parse_zpt_offsets           PROTO((char *ZPT_OFFSET_FILTERS, char *ZPT_OFFSET_VALUES));
+float         apply_zpt_offset            PROTO((short code));
Index: /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/initialize_setphot.c
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/initialize_setphot.c	(revision 33328)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/initialize_setphot.c	(revision 33329)
@@ -84,4 +84,19 @@
   }
 
+  // -zpt-offsets code[,code,etc] value[,value,etc]
+  // eg: -zpt-offsets g,r,i 0.01,0.02,-0.02
+  char *ZPT_OFFSETS_FILTERS = NULL;
+  char *ZPT_OFFSETS_VALUES = NULL;
+  if ((N = get_argument (argc, argv, "-zpt-offsets"))) {
+    remove_argument (N, &argc, argv);
+    ZPT_OFFSETS_FILTERS = strcreate (argv[N]);
+    remove_argument (N, &argc, argv);
+    ZPT_OFFSETS_VALUES = strcreate (argv[N]);
+    remove_argument (N, &argc, argv);
+    
+    parse_zpt_offsets (ZPT_OFFSETS_FILTERS, ZPT_OFFSETS_VALUES);
+  }
+  
+
   if (argc != 2) {
     fprintf (stderr, "USAGE: setphot (zptfile) [options]\n");
@@ -89,4 +104,5 @@
     fprintf (stderr, "    -v : verbose mode\n");
     fprintf (stderr, "    -ubercal : interpret zpt file as a GPC1 ubercal FITS table\n");
+    fprintf (stderr, "    -no-metadata : assume the ubercal FITS table has the layout defined by Eddie Schlafly in Dec 2011\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");
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 33328)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/load_zpt_table.c	(revision 33329)
@@ -350,2 +350,101 @@
   return zpts;
 }
+
+static short maxCode = 0;
+static short *zpt_codeval = NULL;
+static float *zpt_offsets = NULL;
+static short *zpt_index = NULL;
+
+int parse_zpt_offsets (char *ZPT_OFFSET_FILTERS, char *ZPT_OFFSET_VALUES) {
+
+  assert (ZPT_OFFSET_FILTERS);
+  assert (ZPT_OFFSET_VALUES);
+
+  char *filters = strcreate(ZPT_OFFSET_FILTERS);
+  char *values = strcreate(ZPT_OFFSET_VALUES);
+
+  char *p1 = filters;
+  char *p2 = values;
+
+  char *filter = NULL;
+  char *value = NULL;
+
+  char *s1 = NULL;
+  char *s2 = NULL;
+
+  // save an array of the zero point offsets and their photcodes
+  int Ncode = 0;
+  int NCODE = 8;
+  ALLOCATE (zpt_codeval, short, NCODE);
+  ALLOCATE (zpt_offsets, float, NCODE);
+
+  while (1) {
+    filter = strtok_r (p1, ",", &s1);
+    if (!filter) break;
+
+    value  = strtok_r (p2, ",", &s2);
+    if (!value) {
+      fprintf (stderr, "ERROR: mismatch between list of photcodes and list of offsets\n");
+      exit (1);
+    }
+
+    // do something here
+    PhotCode *code = GetPhotcodebyName (filter);
+    if (!code) {
+      fprintf (stderr, "ERROR: unknown photcode %s\n", filter);
+      exit (1);
+    }
+    if (code->type != PHOT_SEC) {
+      fprintf (stderr, "ERROR: photcode %s is not an average (SEC) type\n", filter);
+      exit (1);
+    }
+
+    zpt_codeval[Ncode] = code->code;
+    zpt_offsets[Ncode] = atof(value);
+    Ncode ++;
+
+    if (Ncode >= NCODE) {
+      NCODE += 8;
+      REALLOCATE (zpt_codeval, short, NCODE);
+      REALLOCATE (zpt_offsets, float, NCODE);
+    }
+    
+    maxCode = MAX(code->code, maxCode);
+
+    p1 = NULL;
+    p2 = NULL;
+  }
+    
+  // generate an index to the zpt offsets by the photcode
+  ALLOCATE (zpt_index, short, maxCode + 1);
+
+  int i;
+  for (i = 0; i < maxCode + 1; i++) {
+    zpt_index[i] = -1;
+  }
+
+  for (i = 0; i < Ncode; i++) {
+    short seq = zpt_codeval[i];
+    if (zpt_index[seq] != -1) {
+      fprintf (stderr, "duplicate photcode in -zpt-offset list\n");
+      exit (2);
+    }
+    zpt_index[seq] = i;
+  }
+  return TRUE;
+}
+
+float apply_zpt_offset (short code) {
+
+  if (!zpt_offsets) return 0.0;
+
+  // code is a primary photcode (but may be out of range, in which case no correction is supplied)
+  if (code <= 0) return 0.0;
+  if (code > maxCode) return 0.0;
+
+  short index = zpt_index[code];
+  if (index == -1) return 0.0;
+
+  float offset = zpt_offsets[index];
+  return offset;
+}
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 33328)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/match_zpts_to_images.c	(revision 33329)
@@ -84,4 +84,10 @@
       image[Ni].Mcal = SCALE*code[0].C - zpts[Nz].zpt;
     }
+
+    // if we have defined zero point offsets, then apply them here
+    float offset = apply_zpt_offset (code[0].equiv);
+    assert (isfinite(offset));
+    image[Ni].Mcal += offset;
+
     image[Ni].dMcal = zpts[Nz].zpt_err;
     image[Ni].flags &= ~ID_IMAGE_PHOTOM_NOCAL; // clear the NOCAL flag
