Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/Makefile
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/Makefile	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/Makefile	(revision 37403)
@@ -78,12 +78,13 @@
 $(SRC)/parse_time.$(ARCH).o \
 $(SRC)/replace_match.$(ARCH).o \
-$(SRC)/resort_catalog.$(ARCH).o \
+$(SRC)/resort_catalogs.$(ARCH).o \
 $(SRC)/resort_threaded.$(ARCH).o \
 $(SRC)/resort_unthreaded.$(ARCH).o \
-$(SRC)/resort_unthreaded_catalogs.$(ARCH).o \
+$(SRC)/resort_catalog.$(ARCH).o \
 $(SRC)/StarOps.$(ARCH).o \
 $(SRC)/ReadStarsFITS.$(ARCH).o \
 $(SRC)/ReadStarsTEXT.$(ARCH).o \
 $(SRC)/ReadStarsSDSS.$(ARCH).o \
+$(SRC)/ReadXradFITS.$(ARCH).o \
 $(SRC)/FilterStars.$(ARCH).o \
 $(SRC)/ImageOptions.$(ARCH).o \
@@ -105,8 +106,8 @@
 $(SRC)/addstar_client.$(ARCH).o \
 $(SRC)/args_parallel_client.$(ARCH).o \
-$(SRC)/resort_catalog.$(ARCH).o \
+$(SRC)/resort_catalogs.$(ARCH).o \
 $(SRC)/resort_threaded.$(ARCH).o \
 $(SRC)/resort_unthreaded.$(ARCH).o \
-$(SRC)/resort_unthreaded_catalogs.$(ARCH).o
+$(SRC)/resort_catalog.$(ARCH).o
 
 ADDSTARD = \
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/include/addstar.h
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/include/addstar.h	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/include/addstar.h	(revision 37403)
@@ -35,12 +35,15 @@
   char *exthead;
   char *extdata;
+  char *extxrad;
   char *exttype;
   int extnum_head;
   int extnum_data;
+  int extnum_xrad;
 } HeaderSet;
 
 typedef struct {
-  Average average;
-  Measure measure;
+  Average  average;
+  Measure  measure;
+  Lensing *lensing; // optionally carry out the lensing measurements
   int found;
 } Stars;
@@ -145,4 +148,5 @@
 
 int     OLD_RESORT;
+int     READ_XRAD_DATA;
 
 int    PARALLEL;
@@ -236,9 +240,11 @@
 Stars     *rd_gsc                 PROTO((char *filename, unsigned int *nstars));
 int        replace_match          PROTO((Average *average, Measure *measure, Stars *star));
-int        resort_threaded        PROTO((AddstarClientOptions *options, SkyTable *sky));
-int        resort_unthreaded      PROTO((AddstarClientOptions *options, SkyTable *sky, int hostID, char *hostpath));
-int        resort_unthreaded_catalogs PROTO((AddstarClientOptions *options, SkyList *skylist, int hostID, char *hostpath));
+int        resort_catalogs        PROTO((AddstarClientOptions *options, SkyTable *sky));
+int        resort_catalogs_parallel PROTO((AddstarClientOptions *options, SkyList *sky));
+int        resort_threaded        PROTO((SkyList *skylist, int ForceSort));
+int        resort_unthreaded      PROTO((SkyList *skylist, int ForceSort));
 void       resort_catalog         PROTO((Catalog *catalog));
 void       resort_catalog_old     PROTO((Catalog *catalog));
+
 Stars     *ReadStarsFITS          PROTO((FILE *f, Header *header, Header *in_theader, unsigned int *nstars));
 Stars     *ReadStarsTEXT          PROTO((FILE *f, unsigned int *nstars));
@@ -247,13 +253,20 @@
 Stars     *FilterStars            PROTO((Stars *instars, Image *image, unsigned int imageID, const AddstarClientOptions *options));
 Stars     *MergeStars             PROTO((Stars *stars, unsigned int *Nstars, Stars *instars, unsigned int Ninstars));
+
+int        ReadXradFITS           PROTO((FILE *f, Header *theader, Stars *stars, unsigned int Nstars));
+
 double     scat_subpix            PROTO((double x, double y));
 void       update_coords          PROTO((Average *average, Measure *measure, off_t *next));
 off_t 	  *init_measure_links     PROTO((Average *average, off_t Naverage, Measure *measure, off_t Nmeasure));
+off_t 	  *init_lensing_links     PROTO((Average *average, off_t Naverage, Lensing *lensing, off_t Nlensing));
 off_t 	  *init_missing_links     PROTO((Average *average, off_t Naverage, Missing *missing, off_t Nmissing));
-off_t 	   add_meas_link     	  PROTO((Average *average, off_t *next_meas, off_t Nmeasure, off_t NMEASURE));
-off_t 	   add_miss_link     	  PROTO((Average *average, off_t *next_miss, off_t Nmissing));
+int 	   add_meas_link     	  PROTO((Average *average, off_t *next_meas, off_t Nmeasure, off_t NMEASURE));
+int 	   add_miss_link     	  PROTO((Average *average, off_t *next_miss, off_t Nmissing));
+int        add_lens_link          PROTO((Average *average, off_t *next_lens, off_t Nlensing, off_t NLENSING));
 off_t 	  *build_measure_links    PROTO((Average *average, off_t Naverage, Measure *measure, off_t Nmeasure));
+off_t     *build_lensing_links    PROTO((Average *average, off_t Naverage, Lensing *lensing, off_t Nlensing));
 Measure   *sort_measure     	  PROTO((Average *average, off_t Naverage, Measure *measure, off_t Nmeasure, off_t *next_meas));
 Missing   *sort_missing     	  PROTO((Average *average, off_t Naverage, Missing *missing, off_t Nmissing, off_t *next_miss));
+Lensing   *sort_lensing           PROTO((Average *average, off_t Naverage, Lensing *lensing, off_t Nlensing, off_t *next_lens));
 int        ImageOptions		  PROTO((AddstarClientOptions *options, Image *images, off_t Nimages));
 int        GetFileMode		  PROTO((Header *header));
@@ -311,4 +324,5 @@
 void *memrchr(const void *s, int c, size_t n);
 int addstar_create_ID ();
+int strextend (char *input, char *format,...);
 
 /** 
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/BoundaryTreeIO.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/BoundaryTreeIO.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/BoundaryTreeIO.c	(revision 37403)
@@ -1,3 +1,5 @@
 # include "addstar.h"
+
+/** this file is deprecated (functions moved to libdvo) ***/
 
 # define GET_COLUMN_NEW(OUT,NAME,TYPE)					\
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/FilterStars.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/FilterStars.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/FilterStars.c	(revision 37403)
@@ -9,5 +9,5 @@
 
 // the imageID supplied here is the sequence **within this set**
-// this value is updated based on the image table later
+// this value is updated based on the image table later (in UpdateImageIDs)
 Stars *FilterStars (Stars *instars, Image *image, unsigned int imageID, const AddstarClientOptions *options) {
 
@@ -99,4 +99,10 @@
       stars[N].measure.dFluxKron /= image[0].exptime;
     }
+    if (!isnan(stars[N].measure.FluxAp)) {
+      stars[N].measure.FluxAp /= image[0].exptime;
+    }
+    if (!isnan(stars[N].measure.dFluxAp)) {
+      stars[N].measure.dFluxAp /= image[0].exptime;
+    }
     
     // the external ID is supplied, but do we trust it?
@@ -120,4 +126,9 @@
 
     stars[N].measure.imageID = imageID; // this value is updated in UpdateImageIDs
+
+    // add imageID to lensing entry, if it exists
+    if (stars[N].lensing) {
+      stars[N].lensing->imageID = imageID;
+    }
 
     N ++;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/GetFileMode.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/GetFileMode.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/GetFileMode.c	(revision 37403)
@@ -10,4 +10,5 @@
   int havePHOT_VER, haveTARG_VER;
 
+  // NOTE target of %t must be int length
   gfits_scan_alt (header, "SIMPLE", "%t", 1, &simple);
   int haveNaxis = gfits_scan (header, "NAXIS",  "%d", 1, &Naxis);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/LoadData.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/LoadData.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/LoadData.c	(revision 37403)
@@ -83,4 +83,19 @@
       continue;
     }
+
+    // XRAD : if we want to read the xrad table, skip to that table here:
+    if (headerSets[i].extnum_xrad != -1) {
+      int Nxrad = headerSets[i].extnum_xrad;
+      Nskip = 0;
+      for (j = 0; j < Nxrad; j++) {
+	Nskip += extsize[j];
+      }
+      fseeko (f, Nskip, SEEK_SET); 
+      
+      if (!ReadXradFITS (f, headers[Nxrad], inStars, images[0][Nvalid].nstar)) {
+	fprintf (stderr, "problem reading the radial flux data for %s\n", headerSets[i].extdata);
+      }
+    }
+
     inStars = FilterStars (inStars, &images[0][Nvalid], Nvalid, options);
     *stars = MergeStars (*stars, Nstars, inStars, images[0][Nvalid].nstar);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/MatchHeaders.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/MatchHeaders.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/MatchHeaders.c	(revision 37403)
@@ -59,9 +59,14 @@
     if (!strcmp (exttype, "PS1_V3")) goto keep;
     if (!strcmp (exttype, "PS1_V4")) goto keep;
+    if (!strcmp (exttype, "PS1_V5")) goto keep;
+
     if (!strcmp (exttype, "PS1_SV1")) goto keep;
     if (!strcmp (exttype, "PS1_SV2")) goto keep;
-    if (!strcmp (exttype, "PS1_DV3")) {
-      goto keep;
-    }
+    if (!strcmp (exttype, "PS1_SV3")) goto keep;
+
+    if (!strcmp (exttype, "PS1_DV1")) goto keep;
+    if (!strcmp (exttype, "PS1_DV2")) goto keep;
+    if (!strcmp (exttype, "PS1_DV3")) goto keep;
+    if (!strcmp (exttype, "PS1_DV4")) goto keep;
     continue;
 
@@ -74,13 +79,33 @@
     headerSets[Nimage].extdata     = strcreate (extname);
     headerSets[Nimage].exthead     = strcreate (exthead);
+    headerSets[Nimage].extxrad     = NULL;
     headerSets[Nimage].extnum_data = i;
     headerSets[Nimage].extnum_head = -1;
+    headerSets[Nimage].extnum_xrad = -1;
+
+    // XXX a special case for fforce xrad data
+    if (READ_XRAD_DATA) {
+      // extname is foobar.psf, convert to foobar.xrad
+      int Nchar = strlen (extname); // foobar.psf : Nchar = 10
+      ALLOCATE (headerSets[Nimage].extxrad, char, Nchar + 2); // xrad is 1 longer than psf
+      memcpy   (headerSets[Nimage].extxrad, extname, Nchar - 3); // Nchar - 3 = 7
+      memcpy  (&headerSets[Nimage].extxrad[Nchar-3], "xrad", 4); 
+      headerSets[Nimage].extxrad[Nchar + 1] = 0; // put the 0 at element 11 for foobar.xrad\0
+    }
 
     // find the matching exthead entry
     for (j = 0; j < Nheaders; j++) {
       if (!gfits_scan (headers[j], ExtnameKeyword, "%s", 1, extname)) continue;
-      if (strcmp (extname, headerSets[Nimage].exthead)) continue;
-      headerSets[Nimage].extnum_head = j;
-      break;
+      if (!strcmp (extname, headerSets[Nimage].exthead)) { 
+	headerSets[Nimage].extnum_head = j;
+	if (!READ_XRAD_DATA) break;
+      }
+      if (READ_XRAD_DATA && !strcmp (extname, headerSets[Nimage].extxrad)) { 
+	headerSets[Nimage].extnum_xrad = j;
+      }
+      if ((headerSets[Nimage].extnum_head > -1) && (headerSets[Nimage].extnum_xrad > -1)) {
+	// we can only get here if READ_XRAD_DATA is true
+	break;
+      }
     }
 
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/ReadImageHeader.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/ReadImageHeader.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/ReadImageHeader.c	(revision 37403)
@@ -44,4 +44,7 @@
   image[0].NX = Nx;
   image[0].NY = Ny;
+
+  image[0].refColorBlue = NAN;
+  image[0].refColorRed = NAN;
 
   if (!gfits_scan (header, "TZERO",   "%d",  1, &image[0].tzero) && !ACCEPT_TIME) {
@@ -133,5 +136,6 @@
 
   tmp = 0;
-  gfits_scan (header, "FLIMIT",   "%lf", 1, &tmp);
+  // gfits_scan (header, "FLIMIT",   "%lf", 1, &tmp);
+  gfits_scan (header, "DETEFF.MAGREF", "%lf", 1, &tmp);
   image[0].detection_limit = tmp * 10.0;
 
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/ReadStarsFITS.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/ReadStarsFITS.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/ReadStarsFITS.c	(revision 37403)
@@ -12,8 +12,12 @@
 Stars     *Convert_PS1_V3	  PROTO((FTable *table, unsigned int *nstars));
 Stars     *Convert_PS1_V4	  PROTO((FTable *table, unsigned int *nstars));
+Stars     *Convert_PS1_V5	  PROTO((FTable *table, unsigned int *nstars));
+Stars     *Convert_PS1_V5_Lensing PROTO((FTable *table, unsigned int *nstars));
 Stars     *Convert_PS1_SV1	  PROTO((FTable *table, unsigned int *nstars));
 Stars     *Convert_PS1_SV1_Alt	  PROTO((FTable *table, unsigned int *nstars));
 Stars     *Convert_PS1_SV2	  PROTO((FTable *table, unsigned int *nstars));
+Stars     *Convert_PS1_SV3	  PROTO((FTable *table, unsigned int *nstars));
 Stars     *Convert_PS1_DV3        PROTO((FTable *table, unsigned int *nstars));
+Stars     *Convert_PS1_DV4        PROTO((FTable *table, unsigned int *nstars));
 
 // given a file with the pointer at the start of the table block and the 
@@ -73,4 +77,11 @@
     stars = Convert_PS1_V4 (&table, &Nstars);
   }
+  if (!strcmp (type, "PS1_V5")) {
+    if (table.header[0].Naxis[0] == 312) {
+      stars = Convert_PS1_V5_Lensing (&table, &Nstars);
+    } else {
+      stars = Convert_PS1_V5 (&table, &Nstars);
+    }
+  }
   if (!strcmp (type, "PS1_SV1")) {
     stars = Convert_PS1_SV1 (&table, &Nstars);
@@ -79,7 +90,13 @@
     stars = Convert_PS1_SV2 (&table, &Nstars);
   }
+  if (!strcmp (type, "PS1_SV3")) {
+    stars = Convert_PS1_SV3 (&table, &Nstars);
+  }
   if (!strcmp (type, "PS1_DV3")) {
     stars = Convert_PS1_DV3 (&table, &Nstars);
   }
+  if (!strcmp (type, "PS1_DV4")) {
+    stars = Convert_PS1_DV4 (&table, &Nstars);
+  }
   if (stars == NULL) {
     fprintf (stderr, "invalid table type %s\n", type);
@@ -91,4 +108,21 @@
 
   return stars;
+}
+
+float GetFluxFromFluxOrMag (float flux, float mag) {
+
+  if (isnan(mag) && isnan(flux)) return NAN;
+
+  if (isnan(flux)) return pow(10.0,-0.4*mag);
+  return flux;
+}
+
+float GetFluxErrFromFluxOrMag (float dFlux, float flux, float dMag) {
+
+  if (isnan(dMag) && isnan(dFlux)) return NAN;
+  if (isnan(dFlux) && isnan(flux)) return NAN;
+
+  if (isnan(dFlux)) return (fabs(dMag * flux));
+  return dFlux;
 }
 
@@ -148,5 +182,4 @@
     stars[i].measure.psfNdof    = NAN_S_INT; // not provided by SMPDATA:
     stars[i].measure.psfNpix    = NAN_S_INT; // not provided by SMPDATA:
-    stars[i].measure.crNsigma   = NAN;       // not provided by SMPDATA:
     stars[i].measure.extNsigma  = NAN;	     // not provided by SMPDATA:
 
@@ -217,5 +250,4 @@
     stars[i].measure.psfNdof    = NAN_S_INT; // not provided by PS1_DEV_0:
     stars[i].measure.psfNpix    = NAN_S_INT; // not provided by PS1_DEV_0:
-    stars[i].measure.crNsigma   = NAN;       // not provided by PS1_DEV_0:
     stars[i].measure.extNsigma  = NAN;        // not provided by PS1_DEV_0:
 
@@ -289,5 +321,4 @@
     stars[i].measure.psfNdof    = NAN_S_INT; // not provided by PS1_DEV_1:
     stars[i].measure.psfNpix    = NAN_S_INT; // not provided by PS1_DEV_1:
-    stars[i].measure.crNsigma   = ps1data[i].crNsigma;
     stars[i].measure.extNsigma  = ps1data[i].extNsigma;
 
@@ -360,4 +391,5 @@
     stars[i].measure.dMcal      = ps1data[i].dMcal;
     stars[i].measure.Map        = ps1data[i].Map + ZeroPt;
+    stars[i].measure.dMap       = ps1data[i].dM; // a proxy measure
                         
     stars[i].measure.Mkron      = NAN; // not provided by PS1_V1:
@@ -373,5 +405,4 @@
     stars[i].measure.psfNdof    = ps1data[i].psfNdof;
     stars[i].measure.psfNpix    = ps1data[i].psfNpix;
-    stars[i].measure.crNsigma   = ps1data[i].crNsigma;
     stars[i].measure.extNsigma  = ps1data[i].extNsigma;
 
@@ -445,4 +476,5 @@
     stars[i].measure.dMcal      = ps1data[i].dMcal;
     stars[i].measure.Map        = ps1data[i].Map + ZeroPt;
+    stars[i].measure.dMap       = ps1data[i].dM; // a proxy measure
                         
     stars[i].measure.Mkron      = NAN; // not provided by PS1_V1_Alt:
@@ -458,5 +490,4 @@
     stars[i].measure.psfNdof    = ps1data[i].psfNdof;
     stars[i].measure.psfNpix    = ps1data[i].psfNpix;
-    stars[i].measure.crNsigma   = ps1data[i].crNsigma;
     stars[i].measure.extNsigma  = ps1data[i].extNsigma;
 
@@ -522,4 +553,5 @@
     stars[i].measure.dMcal      = ps1data[i].dMcal;
     stars[i].measure.Map        = ps1data[i].Map + ZeroPt;
+    stars[i].measure.dMap       = ps1data[i].dM; // a proxy measure
                         
     stars[i].measure.Mkron      = NAN; // not provided by PS1_V2:
@@ -535,5 +567,4 @@
     stars[i].measure.psfNdof    = ps1data[i].psfNdof;
     stars[i].measure.psfNpix    = ps1data[i].psfNpix;
-    stars[i].measure.crNsigma   = ps1data[i].crNsigma;
     stars[i].measure.extNsigma  = ps1data[i].extNsigma;
 
@@ -595,4 +626,5 @@
     stars[i].measure.dMcal      = ps1data[i].dMcal;
     stars[i].measure.Map        = ps1data[i].Map + ZeroPt;
+    stars[i].measure.dMap       = ps1data[i].dM; // a proxy measure
                         
     stars[i].measure.Mkron      = (ps1data[i].kronFlux > 0.0) ? -2.5*log10(ps1data[i].kronFlux) + ZeroPt : NAN;
@@ -600,8 +632,10 @@
                         
     // these fluxes are converted from counts to counts/sec in FilterStars.c
-    stars[i].measure.FluxPSF    = ps1data[i].Flux;
-    stars[i].measure.dFluxPSF   = ps1data[i].dFlux;
+    stars[i].measure.FluxPSF    = GetFluxFromFluxOrMag (ps1data[i].Flux, ps1data[i].M); 
+    stars[i].measure.dFluxPSF   = GetFluxErrFromFluxOrMag (ps1data[i].dFlux, stars[i].measure.FluxPSF, ps1data[i].dM);
     stars[i].measure.FluxKron   = ps1data[i].kronFlux;
     stars[i].measure.dFluxKron  = ps1data[i].kronFluxErr;
+    stars[i].measure.FluxAp     = GetFluxFromFluxOrMag (NAN, ps1data[i].Map); 
+    stars[i].measure.dFluxAp    = GetFluxErrFromFluxOrMag (NAN, stars[i].measure.FluxAp, stars[i].measure.dMap);
 
     stars[i].measure.Sky        = ps1data[i].sky;
@@ -613,5 +647,4 @@
     stars[i].measure.psfNdof    = ps1data[i].psfNdof;
     stars[i].measure.psfNpix    = ps1data[i].psfNpix;
-    stars[i].measure.crNsigma   = ps1data[i].crNsigma;
     stars[i].measure.extNsigma  = ps1data[i].extNsigma;
 
@@ -625,4 +658,5 @@
                         
     stars[i].measure.photFlags  = ps1data[i].flags;
+    stars[i].measure.photFlags2 = ps1data[i].flags2;
 
     // this is may optionally be replaced by the internal sequence (see FilterStars.c)
@@ -676,4 +710,5 @@
     stars[i].measure.dMcal      = ps1data[i].dMcal;
     stars[i].measure.Map        = ps1data[i].Map + ZeroPt;
+    stars[i].measure.dMap       = (ps1data[i].apFlux > 0.0) ? fabs(ps1data[i].apFluxErr / ps1data[i].apFlux) : NAN;
                         
     stars[i].measure.Mkron      = (ps1data[i].kronFlux > 0.0) ? -2.5*log10(ps1data[i].kronFlux) + ZeroPt : NAN;
@@ -681,8 +716,10 @@
                         
     // these fluxes are converted from counts to counts/sec in FilterStars.c
-    stars[i].measure.FluxPSF    = ps1data[i].Flux;
-    stars[i].measure.dFluxPSF   = ps1data[i].dFlux;
+    stars[i].measure.FluxPSF    = GetFluxFromFluxOrMag (ps1data[i].Flux, ps1data[i].M); 
+    stars[i].measure.dFluxPSF   = GetFluxErrFromFluxOrMag (ps1data[i].dFlux, stars[i].measure.FluxPSF, ps1data[i].dM);
     stars[i].measure.FluxKron   = ps1data[i].kronFlux;
     stars[i].measure.dFluxKron  = ps1data[i].kronFluxErr;
+    stars[i].measure.FluxAp     = GetFluxFromFluxOrMag (ps1data[i].apFlux, ps1data[i].Map); 
+    stars[i].measure.dFluxAp    = GetFluxErrFromFluxOrMag (ps1data[i].apFluxErr, stars[i].measure.FluxAp, stars[i].measure.dMap);
 
     stars[i].measure.Sky        = ps1data[i].sky;
@@ -695,5 +732,4 @@
     stars[i].measure.psfNdof    = ps1data[i].psfNdof;
     stars[i].measure.psfNpix    = ps1data[i].psfNpix;
-    stars[i].measure.crNsigma   = ps1data[i].crNsigma;
     stars[i].measure.extNsigma  = ps1data[i].extNsigma;
 
@@ -707,4 +743,5 @@
                         
     stars[i].measure.photFlags  = ps1data[i].flags;
+    stars[i].measure.photFlags2 = ps1data[i].flags2;
 
     // this is may optionally be replaced by the internal sequence (see FilterStars.c)
@@ -724,5 +761,5 @@
 }
 
-Stars *Convert_PS1_SV1 (FTable *table, unsigned int *nstars) {
+Stars *Convert_PS1_V5 (FTable *table, unsigned int *nstars) {
 
   off_t Nstars; 
@@ -730,12 +767,7 @@
   double ZeroPt;
   Stars *stars;
-  CMF_PS1_SV1 *ps1data;
-
-  if (table[0].header[0].Naxis[0] == 196) {
-    stars = Convert_PS1_SV1_Alt (table, nstars);
-    return (stars);
-  }
-
-  ps1data = gfits_table_get_CMF_PS1_SV1 (table, &Nstars, NULL);
+  CMF_PS1_V5 *ps1data;
+
+  ps1data = gfits_table_get_CMF_PS1_V5 (table, &Nstars, NULL);
   if (!ps1data) {
     fprintf (stderr, "skipping inconsistent entry\n");
@@ -763,13 +795,16 @@
     stars[i].measure.dMcal      = ps1data[i].dMcal;
     stars[i].measure.Map        = ps1data[i].Map + ZeroPt;
+    stars[i].measure.dMap       = (ps1data[i].apFlux > 0.0) ? fabs(ps1data[i].apFluxErr / ps1data[i].apFlux) : NAN;
                         
     stars[i].measure.Mkron      = (ps1data[i].kronFlux > 0.0) ? -2.5*log10(ps1data[i].kronFlux) + ZeroPt : NAN;
     stars[i].measure.dMkron     = (ps1data[i].kronFlux > 0.0) ? ps1data[i].kronFluxErr / ps1data[i].kronFlux : NAN;
-
+                        
     // these fluxes are converted from counts to counts/sec in FilterStars.c
-    stars[i].measure.FluxPSF    = ps1data[i].Flux;
-    stars[i].measure.dFluxPSF   = ps1data[i].dFlux;
+    stars[i].measure.FluxPSF    = GetFluxFromFluxOrMag (ps1data[i].Flux, ps1data[i].M); 
+    stars[i].measure.dFluxPSF   = GetFluxErrFromFluxOrMag (ps1data[i].dFlux, stars[i].measure.FluxPSF, ps1data[i].dM);
     stars[i].measure.FluxKron   = ps1data[i].kronFlux;
     stars[i].measure.dFluxKron  = ps1data[i].kronFluxErr;
+    stars[i].measure.FluxAp     = GetFluxFromFluxOrMag (ps1data[i].apFlux, ps1data[i].Map); 
+    stars[i].measure.dFluxAp    = GetFluxErrFromFluxOrMag (ps1data[i].apFluxErr, stars[i].measure.FluxAp, stars[i].measure.dMap);
 
     stars[i].measure.Sky        = ps1data[i].sky;
@@ -782,5 +817,4 @@
     stars[i].measure.psfNdof    = ps1data[i].psfNdof;
     stars[i].measure.psfNpix    = ps1data[i].psfNpix;
-    stars[i].measure.crNsigma   = ps1data[i].crNsigma;
     stars[i].measure.extNsigma  = ps1data[i].extNsigma;
 
@@ -794,4 +828,5 @@
                         
     stars[i].measure.photFlags  = ps1data[i].flags;
+    stars[i].measure.photFlags2 = ps1data[i].flags2;
 
     // this is may optionally be replaced by the internal sequence (see FilterStars.c)
@@ -799,6 +834,9 @@
 
     // the Average fields and the following Measure fields are set in FilterStars after
-    // the image metadata is in hand:  dR, dD, Mcal, dt, airmass, az, t, imageID, extID, 
-    // averef is set in find_matches, dbFlags is zero on ingest.
+    // the image metadata is in hand:  dR, dD, Mcal, dt, airmass, az, t, imageID, extID.
+
+    // averef is set in find_matches
+
+    // dbFlags is zero on ingest.
 
     // the following fields are currently not being set anywhere: t_msec
@@ -808,5 +846,5 @@
 }
 
-Stars *Convert_PS1_SV1_Alt (FTable *table, unsigned int *nstars) {
+Stars *Convert_PS1_V5_Lensing (FTable *table, unsigned int *nstars) {
 
   off_t Nstars; 
@@ -814,9 +852,7 @@
   double ZeroPt;
   Stars *stars;
-  CMF_PS1_SV1 *ps1data;
-
-  // some test output files were produced called CMF_PS1_SV1 but with mismatch byte boundaries
-
-  ps1data = gfits_table_get_CMF_PS1_SV1_Alt (table, &Nstars, NULL);
+  CMF_PS1_V5_Lensing *ps1data;
+
+  ps1data = gfits_table_get_CMF_PS1_V5_Lensing (table, &Nstars, NULL);
   if (!ps1data) {
     fprintf (stderr, "skipping inconsistent entry\n");
@@ -844,13 +880,230 @@
     stars[i].measure.dMcal      = ps1data[i].dMcal;
     stars[i].measure.Map        = ps1data[i].Map + ZeroPt;
+    stars[i].measure.dMap       = (ps1data[i].apFlux > 0.0) ? fabs(ps1data[i].apFluxErr / ps1data[i].apFlux) : NAN;
                         
     stars[i].measure.Mkron      = (ps1data[i].kronFlux > 0.0) ? -2.5*log10(ps1data[i].kronFlux) + ZeroPt : NAN;
     stars[i].measure.dMkron     = (ps1data[i].kronFlux > 0.0) ? ps1data[i].kronFluxErr / ps1data[i].kronFlux : NAN;
-
+                        
     // these fluxes are converted from counts to counts/sec in FilterStars.c
-    stars[i].measure.FluxPSF    = ps1data[i].Flux;
-    stars[i].measure.dFluxPSF   = ps1data[i].dFlux;
+    stars[i].measure.FluxPSF    = GetFluxFromFluxOrMag (ps1data[i].Flux, ps1data[i].M); 
+    stars[i].measure.dFluxPSF   = GetFluxErrFromFluxOrMag (ps1data[i].dFlux, stars[i].measure.FluxPSF, ps1data[i].dM);
     stars[i].measure.FluxKron   = ps1data[i].kronFlux;
     stars[i].measure.dFluxKron  = ps1data[i].kronFluxErr;
+    stars[i].measure.FluxAp     = GetFluxFromFluxOrMag (ps1data[i].apFlux, ps1data[i].Map); 
+    stars[i].measure.dFluxAp    = GetFluxErrFromFluxOrMag (ps1data[i].apFluxErr, stars[i].measure.FluxAp, stars[i].measure.dMap);
+
+    stars[i].measure.Sky        = ps1data[i].sky;
+    stars[i].measure.dSky       = ps1data[i].dSky;
+                        
+    stars[i].measure.psfChisq   = ps1data[i].psfChisq;
+    stars[i].measure.psfQF      = ps1data[i].psfQF;
+    stars[i].measure.psfQFperf  = ps1data[i].psfQFperf;
+
+    stars[i].measure.psfNdof    = ps1data[i].psfNdof;
+    stars[i].measure.psfNpix    = ps1data[i].psfNpix;
+    stars[i].measure.extNsigma  = ps1data[i].extNsigma;
+
+    stars[i].measure.FWx        = ToShortPixels(ps1data[i].fx);
+    stars[i].measure.FWy        = ToShortPixels(ps1data[i].fy);
+    stars[i].measure.theta      = ToShortDegrees(ps1data[i].df);
+
+    stars[i].measure.Mxx        = ToShortPixels(ps1data[i].Mxx);
+    stars[i].measure.Mxy        = ToShortPixels(ps1data[i].Mxy);
+    stars[i].measure.Myy        = ToShortPixels(ps1data[i].Myy);
+                        
+    stars[i].measure.photFlags  = ps1data[i].flags;
+    stars[i].measure.photFlags2 = ps1data[i].flags2;
+
+    // this is may optionally be replaced by the internal sequence (see FilterStars.c)
+    stars[i].measure.detID      = ps1data[i].detID; 
+
+    ALLOCATE (stars[i].lensing, Lensing, 1);
+    dvo_lensing_init (stars[i].lensing);
+
+    stars[i].lensing->X11_sm_obj  = ps1data[i].X11_sm_obj;
+    stars[i].lensing->X12_sm_obj  = ps1data[i].X12_sm_obj;
+    stars[i].lensing->X22_sm_obj  = ps1data[i].X22_sm_obj;
+    stars[i].lensing->E1_sm_obj   = ps1data[i].E1_sm_obj;
+    stars[i].lensing->E2_sm_obj   = ps1data[i].E2_sm_obj;
+
+    stars[i].lensing->X11_sh_obj  = ps1data[i].X11_sh_obj;
+    stars[i].lensing->X12_sh_obj  = ps1data[i].X12_sh_obj;
+    stars[i].lensing->X22_sh_obj  = ps1data[i].X22_sh_obj;
+    stars[i].lensing->E1_sh_obj   = ps1data[i].E1_sh_obj;
+    stars[i].lensing->E2_sh_obj   = ps1data[i].E2_sh_obj;
+
+    stars[i].lensing->X11_sm_psf  = ps1data[i].X11_sm_psf;
+    stars[i].lensing->X12_sm_psf  = ps1data[i].X12_sm_psf;
+    stars[i].lensing->X22_sm_psf  = ps1data[i].X22_sm_psf;
+    stars[i].lensing->E1_sm_psf   = ps1data[i].E1_sm_psf;
+    stars[i].lensing->E2_sm_psf   = ps1data[i].E2_sm_psf;
+
+    stars[i].lensing->X11_sh_psf  = ps1data[i].X11_sh_psf;
+    stars[i].lensing->X12_sh_psf  = ps1data[i].X12_sh_psf;
+    stars[i].lensing->X22_sh_psf  = ps1data[i].X22_sh_psf;
+    stars[i].lensing->E1_sh_psf   = ps1data[i].E1_sh_psf;
+    stars[i].lensing->E2_sh_psf   = ps1data[i].E2_sh_psf;
+
+    // stars[i].lensing->F_ApR5    = ps1data[i].F_ApR5;
+    // stars[i].lensing->dF_ApR5   = ps1data[i].dF_ApR5;
+    // stars[i].lensing->sF_ApR5   = ps1data[i].sF_ApR5;
+    // stars[i].lensing->fF_ApR5   = ps1data[i].fF_ApR5;
+    // 
+    // stars[i].lensing->F_ApR6    = ps1data[i].F_ApR6;
+    // stars[i].lensing->dF_ApR6   = ps1data[i].dF_ApR6;
+    // stars[i].lensing->sF_ApR6   = ps1data[i].sF_ApR6;
+    // stars[i].lensing->fF_ApR6   = ps1data[i].fF_ApR6;
+
+    // this is may optionally be replaced by the internal sequence (see FilterStars.c)
+    stars[i].lensing->detID      = ps1data[i].detID; 
+
+    // the Average fields and the following Measure fields are set in FilterStars after
+    // the image metadata is in hand:  dR, dD, Mcal, dt, airmass, az, t, imageID, extID.
+
+    // averef is set in find_matches
+
+    // dbFlags is zero on ingest.
+
+    // the following fields are currently not being set anywhere: t_msec
+  }    
+  *nstars = Nstars;
+  return (stars);
+}
+
+Stars *Convert_PS1_SV1 (FTable *table, unsigned int *nstars) {
+
+  off_t Nstars; 
+  unsigned int i;
+  double ZeroPt;
+  Stars *stars;
+  CMF_PS1_SV1 *ps1data;
+
+  if (table[0].header[0].Naxis[0] == 196) {
+    stars = Convert_PS1_SV1_Alt (table, nstars);
+    return (stars);
+  }
+
+  ps1data = gfits_table_get_CMF_PS1_SV1 (table, &Nstars, NULL);
+  if (!ps1data) {
+    fprintf (stderr, "skipping inconsistent entry\n");
+    return (NULL);
+  }
+  ZeroPt = GetZeroPoint();
+
+  ALLOCATE (stars, Stars, Nstars);
+  for (i = 0; i < Nstars; i++) {
+    InitStar (&stars[i]);
+    stars[i].measure.Xccd       = ps1data[i].X;
+    stars[i].measure.Yccd       = ps1data[i].Y;
+    stars[i].measure.dXccd      = ToShortPixels(ps1data[i].dX);
+    stars[i].measure.dYccd      = ToShortPixels(ps1data[i].dY);
+
+    stars[i].measure.posangle   = ToShortDegrees(ps1data[i].posangle);
+    stars[i].measure.pltscale   = ps1data[i].pltscale;
+
+    if ((ps1data[i].M >= 0.0) || isnan(ps1data[i].M)) {
+      stars[i].measure.M      = NAN;
+    } else {
+      stars[i].measure.M      = ps1data[i].M + ZeroPt;
+    }
+    stars[i].measure.dM         = ps1data[i].dM;
+    stars[i].measure.dMcal      = ps1data[i].dMcal;
+    stars[i].measure.Map        = ps1data[i].Map + ZeroPt;
+    stars[i].measure.dMap       = ps1data[i].dM; // a proxy measure
+                        
+    stars[i].measure.Mkron      = (ps1data[i].kronFlux > 0.0) ? -2.5*log10(ps1data[i].kronFlux) + ZeroPt : NAN;
+    stars[i].measure.dMkron     = (ps1data[i].kronFlux > 0.0) ? ps1data[i].kronFluxErr / ps1data[i].kronFlux : NAN;
+
+    // these fluxes are converted from counts to counts/sec in FilterStars.c
+    stars[i].measure.FluxPSF    = GetFluxFromFluxOrMag (ps1data[i].Flux, ps1data[i].M); 
+    stars[i].measure.dFluxPSF   = GetFluxErrFromFluxOrMag (ps1data[i].dFlux, stars[i].measure.FluxPSF, ps1data[i].dM);
+    stars[i].measure.FluxKron   = ps1data[i].kronFlux;
+    stars[i].measure.dFluxKron  = ps1data[i].kronFluxErr;
+    stars[i].measure.FluxAp     = GetFluxFromFluxOrMag (NAN, ps1data[i].Map); 
+    stars[i].measure.dFluxAp    = GetFluxErrFromFluxOrMag (NAN, stars[i].measure.FluxAp, stars[i].measure.dMap);
+
+    stars[i].measure.Sky        = ps1data[i].sky;
+    stars[i].measure.dSky       = ps1data[i].dSky;
+                        
+    stars[i].measure.psfChisq   = ps1data[i].psfChisq;
+    stars[i].measure.psfQF      = ps1data[i].psfQF;
+    stars[i].measure.psfQFperf  = ps1data[i].psfQFperf;
+
+    stars[i].measure.psfNdof    = ps1data[i].psfNdof;
+    stars[i].measure.psfNpix    = ps1data[i].psfNpix;
+    stars[i].measure.extNsigma  = ps1data[i].extNsigma;
+
+    stars[i].measure.FWx        = ToShortPixels(ps1data[i].fx);
+    stars[i].measure.FWy        = ToShortPixels(ps1data[i].fy);
+    stars[i].measure.theta      = ToShortDegrees(ps1data[i].df);
+
+    stars[i].measure.Mxx        = ToShortPixels(ps1data[i].Mxx);
+    stars[i].measure.Mxy        = ToShortPixels(ps1data[i].Mxy);
+    stars[i].measure.Myy        = ToShortPixels(ps1data[i].Myy);
+                        
+    stars[i].measure.photFlags  = ps1data[i].flags;
+    stars[i].measure.photFlags2 = ps1data[i].flags2;
+
+    // this is may optionally be replaced by the internal sequence (see FilterStars.c)
+    stars[i].measure.detID      = ps1data[i].detID; 
+
+    // the Average fields and the following Measure fields are set in FilterStars after
+    // the image metadata is in hand:  dR, dD, Mcal, dt, airmass, az, t, imageID, extID, 
+    // averef is set in find_matches, dbFlags is zero on ingest.
+
+    // the following fields are currently not being set anywhere: t_msec
+  }    
+  *nstars = Nstars;
+  return (stars);
+}
+
+Stars *Convert_PS1_SV1_Alt (FTable *table, unsigned int *nstars) {
+
+  off_t Nstars; 
+  unsigned int i;
+  double ZeroPt;
+  Stars *stars;
+  CMF_PS1_SV1 *ps1data;
+
+  // some test output files were produced called CMF_PS1_SV1 but with mismatch byte boundaries
+
+  ps1data = gfits_table_get_CMF_PS1_SV1_Alt (table, &Nstars, NULL);
+  if (!ps1data) {
+    fprintf (stderr, "skipping inconsistent entry\n");
+    return (NULL);
+  }
+  ZeroPt = GetZeroPoint();
+
+  ALLOCATE (stars, Stars, Nstars);
+  for (i = 0; i < Nstars; i++) {
+    InitStar (&stars[i]);
+    stars[i].measure.Xccd       = ps1data[i].X;
+    stars[i].measure.Yccd       = ps1data[i].Y;
+    stars[i].measure.dXccd      = ToShortPixels(ps1data[i].dX);
+    stars[i].measure.dYccd      = ToShortPixels(ps1data[i].dY);
+
+    stars[i].measure.posangle   = ToShortDegrees(ps1data[i].posangle);
+    stars[i].measure.pltscale   = ps1data[i].pltscale;
+
+    if ((ps1data[i].M >= 0.0) || isnan(ps1data[i].M)) {
+      stars[i].measure.M      = NAN;
+    } else {
+      stars[i].measure.M      = ps1data[i].M + ZeroPt;
+    }
+    stars[i].measure.dM         = ps1data[i].dM;
+    stars[i].measure.dMcal      = ps1data[i].dMcal;
+    stars[i].measure.Map        = ps1data[i].Map + ZeroPt;
+    stars[i].measure.dMap       = ps1data[i].dM; // a proxy measure
+                        
+    stars[i].measure.Mkron      = (ps1data[i].kronFlux > 0.0) ? -2.5*log10(ps1data[i].kronFlux) + ZeroPt : NAN;
+    stars[i].measure.dMkron     = (ps1data[i].kronFlux > 0.0) ? ps1data[i].kronFluxErr / ps1data[i].kronFlux : NAN;
+
+    // these fluxes are converted from counts to counts/sec in FilterStars.c
+    stars[i].measure.FluxPSF    = GetFluxFromFluxOrMag (ps1data[i].Flux, ps1data[i].M); 
+    stars[i].measure.dFluxPSF   = GetFluxErrFromFluxOrMag (ps1data[i].dFlux, stars[i].measure.FluxPSF, ps1data[i].dM);
+    stars[i].measure.FluxKron   = ps1data[i].kronFlux;
+    stars[i].measure.dFluxKron  = ps1data[i].kronFluxErr;
+    stars[i].measure.FluxAp     = GetFluxFromFluxOrMag (NAN, ps1data[i].Map); 
+    stars[i].measure.dFluxAp    = GetFluxErrFromFluxOrMag (NAN, stars[i].measure.FluxAp, stars[i].measure.dMap);
 
     stars[i].measure.Sky        = ps1data[i].sky;
@@ -861,5 +1114,4 @@
     stars[i].measure.psfNdof    = ps1data[i].psfNdof;
     stars[i].measure.psfNpix    = ps1data[i].psfNpix;
-    stars[i].measure.crNsigma   = ps1data[i].crNsigma;
     stars[i].measure.extNsigma  = ps1data[i].extNsigma;
 
@@ -873,4 +1125,5 @@
                         
     stars[i].measure.photFlags  = ps1data[i].flags;
+    stars[i].measure.photFlags2 = ps1data[i].flags2;
 
     // this is may optionally be replaced by the internal sequence (see FilterStars.c)
@@ -921,4 +1174,5 @@
     stars[i].measure.dMcal      = ps1data[i].dMcal;
     stars[i].measure.Map        = ps1data[i].Map + ZeroPt;
+    stars[i].measure.dMap       = (ps1data[i].apFlux > 0.0) ? fabs(ps1data[i].apFluxErr / ps1data[i].apFlux) : NAN;
                         
     stars[i].measure.Mkron      = (ps1data[i].kronFlux > 0.0) ? -2.5*log10(ps1data[i].kronFlux) + ZeroPt : NAN;
@@ -926,8 +1180,10 @@
 
     // these fluxes are converted from counts to counts/sec in FilterStars.c
-    stars[i].measure.FluxPSF    = ps1data[i].Flux;
-    stars[i].measure.dFluxPSF   = ps1data[i].dFlux;
+    stars[i].measure.FluxPSF    = GetFluxFromFluxOrMag (ps1data[i].Flux, ps1data[i].M); 
+    stars[i].measure.dFluxPSF   = GetFluxErrFromFluxOrMag (ps1data[i].dFlux, stars[i].measure.FluxPSF, ps1data[i].dM);
     stars[i].measure.FluxKron   = ps1data[i].kronFlux;
     stars[i].measure.dFluxKron  = ps1data[i].kronFluxErr;
+    stars[i].measure.FluxAp     = GetFluxFromFluxOrMag (ps1data[i].apFlux, ps1data[i].Map); 
+    stars[i].measure.dFluxAp    = GetFluxErrFromFluxOrMag (ps1data[i].apFluxErr, stars[i].measure.FluxAp, stars[i].measure.dMap);
 
     stars[i].measure.Sky        = ps1data[i].sky;
@@ -940,5 +1196,4 @@
     stars[i].measure.psfNdof    = ps1data[i].psfNdof;
     stars[i].measure.psfNpix    = ps1data[i].psfNpix;
-    stars[i].measure.crNsigma   = ps1data[i].crNsigma;
     stars[i].measure.extNsigma  = ps1data[i].extNsigma;
 
@@ -952,4 +1207,5 @@
                         
     stars[i].measure.photFlags  = ps1data[i].flags;
+    stars[i].measure.photFlags2 = ps1data[i].flags2;
 
     // this is may optionally be replaced by the internal sequence (see FilterStars.c)
@@ -966,5 +1222,5 @@
 }
 
-Stars *Convert_PS1_DV3 (FTable *table, unsigned int *nstars) {
+Stars *Convert_PS1_SV3 (FTable *table, unsigned int *nstars) {
 
   off_t Nstars; 
@@ -972,7 +1228,7 @@
   double ZeroPt;
   Stars *stars;
-  CMF_PS1_DV3 *ps1data;
-
-  ps1data = gfits_table_get_CMF_PS1_DV3 (table, &Nstars, NULL);
+  CMF_PS1_SV3 *ps1data;
+
+  ps1data = gfits_table_get_CMF_PS1_SV3 (table, &Nstars, NULL);
   if (!ps1data) {
     fprintf (stderr, "skipping inconsistent entry\n");
@@ -1000,13 +1256,98 @@
     stars[i].measure.dMcal      = ps1data[i].dMcal;
     stars[i].measure.Map        = ps1data[i].Map + ZeroPt;
+    stars[i].measure.dMap       = (ps1data[i].apFlux > 0.0) ? fabs(ps1data[i].apFluxErr / ps1data[i].apFlux) : NAN;
                         
     stars[i].measure.Mkron      = (ps1data[i].kronFlux > 0.0) ? -2.5*log10(ps1data[i].kronFlux) + ZeroPt : NAN;
     stars[i].measure.dMkron     = (ps1data[i].kronFlux > 0.0) ? ps1data[i].kronFluxErr / ps1data[i].kronFlux : NAN;
-                        
+
     // these fluxes are converted from counts to counts/sec in FilterStars.c
-    stars[i].measure.FluxPSF    = ps1data[i].Flux;
-    stars[i].measure.dFluxPSF   = ps1data[i].dFlux;
+    stars[i].measure.FluxPSF    = GetFluxFromFluxOrMag (ps1data[i].Flux, ps1data[i].M); 
+    stars[i].measure.dFluxPSF   = GetFluxErrFromFluxOrMag (ps1data[i].dFlux, stars[i].measure.FluxPSF, ps1data[i].dM);
     stars[i].measure.FluxKron   = ps1data[i].kronFlux;
     stars[i].measure.dFluxKron  = ps1data[i].kronFluxErr;
+    stars[i].measure.FluxAp     = GetFluxFromFluxOrMag (ps1data[i].apFlux, ps1data[i].Map); 
+    stars[i].measure.dFluxAp    = GetFluxErrFromFluxOrMag (ps1data[i].apFluxErr, stars[i].measure.FluxAp, stars[i].measure.dMap);
+
+    stars[i].measure.Sky        = ps1data[i].sky;
+    stars[i].measure.dSky       = ps1data[i].dSky;
+                        
+    stars[i].measure.psfChisq   = ps1data[i].psfChisq;
+    stars[i].measure.psfQF      = ps1data[i].psfQF;
+    stars[i].measure.psfQFperf  = ps1data[i].psfQFperf;
+
+    stars[i].measure.psfNdof    = ps1data[i].psfNdof;
+    stars[i].measure.psfNpix    = ps1data[i].psfNpix;
+    stars[i].measure.extNsigma  = ps1data[i].extNsigma;
+
+    stars[i].measure.FWx        = ToShortPixels(ps1data[i].fx);
+    stars[i].measure.FWy        = ToShortPixels(ps1data[i].fy);
+    stars[i].measure.theta      = ToShortDegrees(ps1data[i].df);
+
+    stars[i].measure.Mxx        = ToShortPixels(ps1data[i].Mxx);
+    stars[i].measure.Mxy        = ToShortPixels(ps1data[i].Mxy);
+    stars[i].measure.Myy        = ToShortPixels(ps1data[i].Myy);
+                        
+    stars[i].measure.photFlags  = ps1data[i].flags;
+    stars[i].measure.photFlags2 = ps1data[i].flags2;
+
+    // this is may optionally be replaced by the internal sequence (see FilterStars.c)
+    stars[i].measure.detID      = ps1data[i].detID; 
+
+    // the Average fields and the following Measure fields are set in FilterStars after
+    // the image metadata is in hand:  dR, dD, Mcal, dt, airmass, az, t, imageID, extID, 
+    // averef is set in find_matches, dbFlags is zero on ingest.
+
+    // the following fields are currently not being set anywhere: t_msec
+  }    
+  *nstars = Nstars;
+  return (stars);
+}
+
+Stars *Convert_PS1_DV3 (FTable *table, unsigned int *nstars) {
+
+  off_t Nstars; 
+  unsigned int i;
+  double ZeroPt;
+  Stars *stars;
+  CMF_PS1_DV3 *ps1data;
+
+  ps1data = gfits_table_get_CMF_PS1_DV3 (table, &Nstars, NULL);
+  if (!ps1data) {
+    fprintf (stderr, "skipping inconsistent entry\n");
+    return (NULL);
+  }
+  ZeroPt = GetZeroPoint();
+
+  ALLOCATE (stars, Stars, Nstars);
+  for (i = 0; i < Nstars; i++) {
+    InitStar (&stars[i]);
+    stars[i].measure.Xccd       = ps1data[i].X;
+    stars[i].measure.Yccd       = ps1data[i].Y;
+    stars[i].measure.dXccd      = ToShortPixels(ps1data[i].dX);
+    stars[i].measure.dYccd      = ToShortPixels(ps1data[i].dY);
+
+    stars[i].measure.posangle   = ToShortDegrees(ps1data[i].posangle);
+    stars[i].measure.pltscale   = ps1data[i].pltscale;
+
+    if ((ps1data[i].M >= 0.0) || isnan(ps1data[i].M)) {
+      stars[i].measure.M      = NAN;
+    } else {
+      stars[i].measure.M      = ps1data[i].M + ZeroPt;
+    }
+    stars[i].measure.dM         = ps1data[i].dM;
+    stars[i].measure.dMcal      = ps1data[i].dMcal;
+    stars[i].measure.Map        = ps1data[i].Map + ZeroPt;
+    stars[i].measure.dMap       = (ps1data[i].apFlux > 0.0) ? fabs(ps1data[i].apFluxErr / ps1data[i].apFlux) : NAN;
+                        
+    stars[i].measure.Mkron      = (ps1data[i].kronFlux > 0.0) ? -2.5*log10(ps1data[i].kronFlux) + ZeroPt : NAN;
+    stars[i].measure.dMkron     = (ps1data[i].kronFlux > 0.0) ? ps1data[i].kronFluxErr / ps1data[i].kronFlux : NAN;
+                        
+    // these fluxes are converted from counts to counts/sec in FilterStars.c
+    stars[i].measure.FluxPSF    = GetFluxFromFluxOrMag (ps1data[i].Flux, ps1data[i].M); 
+    stars[i].measure.dFluxPSF   = GetFluxErrFromFluxOrMag (ps1data[i].dFlux, stars[i].measure.FluxPSF, ps1data[i].dM);
+    stars[i].measure.FluxKron   = ps1data[i].kronFlux;
+    stars[i].measure.dFluxKron  = ps1data[i].kronFluxErr;
+    stars[i].measure.FluxAp     = GetFluxFromFluxOrMag (ps1data[i].apFlux, ps1data[i].Map); 
+    stars[i].measure.dFluxAp    = GetFluxErrFromFluxOrMag (ps1data[i].apFluxErr, stars[i].measure.FluxAp, stars[i].measure.dMap);
 
     stars[i].measure.Sky        = ps1data[i].sky;
@@ -1018,5 +1359,4 @@
     stars[i].measure.psfNdof    = ps1data[i].psfNdof;
     stars[i].measure.psfNpix    = ps1data[i].psfNpix;
-    stars[i].measure.crNsigma   = ps1data[i].crNsigma;
     stars[i].measure.extNsigma  = ps1data[i].extNsigma;
 
@@ -1030,4 +1370,5 @@
                         
     stars[i].measure.photFlags  = ps1data[i].flags;
+    stars[i].measure.photFlags2 = ps1data[i].flags2;
 
     // this is may optionally be replaced by the internal sequence (see FilterStars.c)
@@ -1047,4 +1388,90 @@
 }
 
-
-
+Stars *Convert_PS1_DV4 (FTable *table, unsigned int *nstars) {
+
+  off_t Nstars; 
+  unsigned int i;
+  double ZeroPt;
+  Stars *stars;
+  CMF_PS1_DV4 *ps1data;
+
+  ps1data = gfits_table_get_CMF_PS1_DV4 (table, &Nstars, NULL);
+  if (!ps1data) {
+    fprintf (stderr, "skipping inconsistent entry\n");
+    return (NULL);
+  }
+  ZeroPt = GetZeroPoint();
+
+  fprintf (stderr, "WARNING: Convert_PS1_DV4 not yet updated to match real format\n");
+
+  ALLOCATE (stars, Stars, Nstars);
+  for (i = 0; i < Nstars; i++) {
+    InitStar (&stars[i]);
+    stars[i].measure.Xccd       = ps1data[i].X;
+    stars[i].measure.Yccd       = ps1data[i].Y;
+    stars[i].measure.dXccd      = ToShortPixels(ps1data[i].dX);
+    stars[i].measure.dYccd      = ToShortPixels(ps1data[i].dY);
+
+    stars[i].measure.posangle   = ToShortDegrees(ps1data[i].posangle);
+    stars[i].measure.pltscale   = ps1data[i].pltscale;
+
+    if ((ps1data[i].M >= 0.0) || isnan(ps1data[i].M)) {
+      stars[i].measure.M      = NAN;
+    } else {
+      stars[i].measure.M      = ps1data[i].M + ZeroPt;
+    }
+    stars[i].measure.dM         = ps1data[i].dM;
+    stars[i].measure.dMcal      = ps1data[i].dMcal;
+    stars[i].measure.Map        = ps1data[i].Map + ZeroPt;
+    stars[i].measure.dMap       = (ps1data[i].apFlux > 0.0) ? fabs(ps1data[i].apFluxErr / ps1data[i].apFlux) : NAN;
+                        
+    stars[i].measure.Mkron      = (ps1data[i].kronFlux > 0.0) ? -2.5*log10(ps1data[i].kronFlux) + ZeroPt : NAN;
+    stars[i].measure.dMkron     = (ps1data[i].kronFlux > 0.0) ? ps1data[i].kronFluxErr / ps1data[i].kronFlux : NAN;
+                        
+    // these fluxes are converted from counts to counts/sec in FilterStars.c
+    stars[i].measure.FluxPSF    = GetFluxFromFluxOrMag (ps1data[i].Flux, ps1data[i].M); 
+    stars[i].measure.dFluxPSF   = GetFluxErrFromFluxOrMag (ps1data[i].dFlux, stars[i].measure.FluxPSF, ps1data[i].dM);
+    stars[i].measure.FluxKron   = ps1data[i].kronFlux;
+    stars[i].measure.dFluxKron  = ps1data[i].kronFluxErr;
+    stars[i].measure.FluxAp     = GetFluxFromFluxOrMag (ps1data[i].apFlux, ps1data[i].Map); 
+    stars[i].measure.dFluxAp    = GetFluxErrFromFluxOrMag (ps1data[i].apFluxErr, stars[i].measure.FluxAp, stars[i].measure.dMap);
+
+    stars[i].measure.Sky        = ps1data[i].sky;
+    stars[i].measure.dSky       = ps1data[i].dSky;
+                        
+    stars[i].measure.psfChisq   = ps1data[i].psfChisq;
+    stars[i].measure.psfQF      = ps1data[i].psfQF;
+    stars[i].measure.psfQFperf  = ps1data[i].psfQFperf;
+    stars[i].measure.psfNdof    = ps1data[i].psfNdof;
+    stars[i].measure.psfNpix    = ps1data[i].psfNpix;
+    stars[i].measure.extNsigma  = ps1data[i].extNsigma;
+
+    stars[i].measure.FWx        = ToShortPixels(ps1data[i].fx);
+    stars[i].measure.FWy        = ToShortPixels(ps1data[i].fy);
+    stars[i].measure.theta      = ToShortDegrees(ps1data[i].df);
+
+    stars[i].measure.Mxx        = ToShortPixels(ps1data[i].Mxx);
+    stars[i].measure.Mxy        = ToShortPixels(ps1data[i].Mxy);
+    stars[i].measure.Myy        = ToShortPixels(ps1data[i].Myy);
+                        
+    stars[i].measure.photFlags  = ps1data[i].flags;
+    stars[i].measure.photFlags2 = ps1data[i].flags2;
+
+    // this is may optionally be replaced by the internal sequence (see FilterStars.c)
+    stars[i].measure.detID      = ps1data[i].detID; 
+
+    // the Average fields and the following Measure fields are set in FilterStars after
+    // the image metadata is in hand:  dR, dD, Mcal, dt, airmass, az, t, imageID, extID.
+
+    // averef is set in find_matches
+
+    // dbFlags is zero on ingest.
+
+    // the following fields are currently not being set anywhere: t_msec
+  }    
+  *nstars = Nstars;
+  return (stars);
+}
+
+
+
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/ReadXradFITS.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/ReadXradFITS.c	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/ReadXradFITS.c	(revision 37403)
@@ -0,0 +1,88 @@
+# include "addstar.h"
+
+// given a file with the pointer at the start of the table block and the 
+// corresponding image header, load the xrad data from the table
+int ReadXradFITS (FILE *f, Header *theader, Stars *stars, unsigned int Nstars) {
+
+  FTable table;
+  
+  // we've already read in the header
+  table.header = theader;
+  off_t Nskip = theader[0].datasize;
+  fseeko (f, Nskip, SEEK_CUR); 
+
+  /* load the table data */
+  if (!gfits_fread_ftable_data (f, &table, FALSE)) {
+    fprintf (stderr, "ERROR: can't read table header\n");
+    exit (1);
+  }
+
+  // I want to read the following columns from this table:
+  
+  off_t Nrow, NrowAlt;
+  int Ncol, NcolAlt;
+  char type[16], name[80];
+
+  strcpy (name, "APER_FLUX");
+  float *AperFlux = gfits_get_bintable_column_data (theader, &table, name, type, &Nrow, &Ncol);
+  myAssert (!strcmp(type, "float"), "wrong column type for %s\n", name);
+
+  strcpy (name, "APER_FLUX_ERR");
+  float *AperFluxErr = gfits_get_bintable_column_data (theader, &table, name, type, &NrowAlt, &NcolAlt);
+  myAssert (!strcmp(type, "float"), "wrong column type for %s\n", name); 
+  myAssert (Nrow == NrowAlt, "column mismatch?");
+  myAssert (Ncol == NcolAlt, "column mismatch?");
+
+  strcpy (name, "APER_FLUX_STDEV");
+  float *AperFluxStd = gfits_get_bintable_column_data (theader, &table, name, type, &NrowAlt, &NcolAlt);
+  myAssert (!strcmp(type, "float"), "wrong column type for %s\n", name);
+  myAssert (Nrow == NrowAlt, "column mismatch?");
+  myAssert (Ncol == NcolAlt, "column mismatch?");
+
+  strcpy (name, "APER_FILL");
+  float *AperFill = gfits_get_bintable_column_data (theader, &table, name, type, &NrowAlt, &NcolAlt);
+  myAssert (!strcmp(type, "float"), "wrong column type for %s\n", name);
+  myAssert (Nrow == NrowAlt, "column mismatch?");
+  myAssert (Ncol == NcolAlt, "column mismatch?");
+
+  strcpy (name, "IPP_IDET");
+  int *RadID = gfits_get_bintable_column_data (theader, &table, name, type, &NrowAlt, &NcolAlt);
+  myAssert (!strcmp(type, "int"), "wrong column type for %s\n", name);
+  myAssert (Nrow == NrowAlt, "column mismatch?");
+
+  if (Nrow > Nstars) {
+    myAbort("more radial measurements than stars?  seems like a bug\n");
+  }
+
+  int i;
+  int Nap = 0;
+  for (i = 0; i < Nstars; i++) {
+    if (stars[i].measure.detID < RadID[Nap]) {
+      continue; // this star does not have an aperture
+    }
+    if (stars[i].measure.detID > RadID[Nap]) {
+      myAbort("radial apertures out of order?  seems like a bug\n");
+    }
+
+    // we could allocate here, or just insist this is an error?
+    if (!stars[i].lensing) {
+      fprintf (stderr, "!");
+      ALLOCATE (stars[i].lensing, Lensing, 1);
+      dvo_lensing_init (stars[i].lensing);
+    }
+
+    stars[i].lensing-> F_ApR5 = AperFlux   [Nap*Ncol + 3];
+    stars[i].lensing->dF_ApR5 = AperFluxErr[Nap*Ncol + 3];
+    stars[i].lensing->sF_ApR5 = AperFluxStd[Nap*Ncol + 3];
+    stars[i].lensing->fF_ApR5 = AperFill   [Nap*Ncol + 3];
+
+    stars[i].lensing-> F_ApR6 = AperFlux   [Nap*Ncol + 4];
+    stars[i].lensing->dF_ApR6 = AperFluxErr[Nap*Ncol + 4];
+    stars[i].lensing->sF_ApR6 = AperFluxStd[Nap*Ncol + 4];
+    stars[i].lensing->fF_ApR6 = AperFill   [Nap*Ncol + 4];
+    Nap ++;
+  }
+
+  return TRUE;
+}
+
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/SEDfit.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/SEDfit.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/SEDfit.c	(revision 37403)
@@ -162,9 +162,12 @@
     }
 
+    double R = incat[0].average[i].R;
+    double D = incat[0].average[i].D;
+
     for (j = 0; valid && (j < Nmodel); j++) {
       n = modelRow[j];
       dvo_measure_init (&outcat[0].measure[Nmeas]);
-      outcat[0].measure[Nmeas].dR        = 0.0;
-      outcat[0].measure[Nmeas].dD        = 0.0;
+      outcat[0].measure[Nmeas].R         = R;
+      outcat[0].measure[Nmeas].D         = D;
       outcat[0].measure[Nmeas].M         = table[0].row[minFit.row][0].mags[n] + minFit.Md;
       outcat[0].measure[Nmeas].dM        = 0.0;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/StarOps.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/StarOps.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/StarOps.c	(revision 37403)
@@ -8,4 +8,5 @@
     star[0].found = -1; // found == -1 -> not yet found (use enums?)
 
+    star[0].lensing = NULL; // we only populate this if needed
     return TRUE;
 }
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/UpdateImageIDs.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/UpdateImageIDs.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/UpdateImageIDs.c	(revision 37403)
@@ -55,4 +55,7 @@
   for (i = 0; i < Nstars; i++) {
     stars[i].measure.imageID += imageID;
+    if (stars[i].lensing) {
+      stars[i].lensing->imageID += imageID;
+    }
   }
 
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/addstar.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/addstar.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/addstar.c	(revision 37403)
@@ -1,3 +1,5 @@
 # include "addstar.h"
+
+# define RESETTIME { gettimeofday (&startTimer, (void *) NULL); }
 
 // LARGEFILES: this program currently limits Nstars (input file) to < 2^31
@@ -7,5 +9,5 @@
   int Nmatch, status, loadObjects;
   off_t i, Nimages;
-  off_t Naverage, Nmeasure;
+  off_t Naverage, Nmeasure, Nlensing;
   Stars *stars, **subset;
   Image *images;
@@ -18,8 +20,8 @@
   SkyList *newlist = NULL;
 
-  double dtime;
-  struct timeval start, stop;
-
-  gettimeofday (&start, NULL);
+  struct timeval startAddstar, stopAddstar;
+  gettimeofday (&startAddstar, (void *) NULL);
+
+  INITTIME;
 
   SetSignals ();
@@ -40,11 +42,9 @@
   
   if (options.mode == ADDSTAR_MODE_RESORT) {
-    if (NTHREADS == 0) {
-      resort_unthreaded (&options, sky, 0, NULL);
-    } else {
-      resort_threaded (&options, sky);
-    }
+    resort_catalogs (&options, sky);
     exit (0);
   }
+
+  MARKTIME ("init and config: %f sec\n", dtime); RESETTIME; 
 
   stars = NULL;
@@ -54,4 +54,5 @@
     case ADDSTAR_MODE_IMAGE:
       stars = LoadStars (argv[1], &Nstars, &images, &Nimages, &options);
+      MARKTIME ("load smf: %f sec\n", dtime); RESETTIME; 
 
       // set and update the imageID sequence
@@ -71,5 +72,4 @@
       skylist = SkyListForStars (sky, -1, stars, Nstars);
       break;
-    case ADDSTAR_MODE_RESORT:
     case ADDSTAR_MODE_REFCAT:
       skylist = SkyListByPatch (sky, -1, &UserPatch);
@@ -100,5 +100,5 @@
 
   /* match stars to existing catalog data (or otherwise manipulate catalog data) */
-  Nmatch = Naverage = Nmeasure = 0;
+  Nmatch = Naverage = Nmeasure = Nlensing = 0;
   for (i = 0; loadObjects && (i < skylist[0].Nregions); i++) {
 
@@ -107,5 +107,5 @@
     catalog.catformat = dvo_catalog_catformat (CATFORMAT);  // set the default catformat from config data
     catalog.catmode   = dvo_catalog_catmode (CATMODE);      // set the default catmode from config data
-    catalog.catflags  = LOAD_AVES | LOAD_MEAS | LOAD_MISS | LOAD_SECF;
+    catalog.catflags  = LOAD_AVES | LOAD_MEAS | LOAD_MISS | LOAD_SECF | LOAD_LENSING;
     catalog.Nsecfilt  = GetPhotcodeNsecfilt ();
 
@@ -132,4 +132,5 @@
       }
     }
+    MARKTIME ("load cpt: %f sec\n", dtime); RESETTIME; 
 
     // Naves_disk == 0 implies an empty catalog file
@@ -161,25 +162,11 @@
 	if (Nsubset) free (subset);
 	break;
-      case ADDSTAR_MODE_RESORT:
-	if (options.nosort == 3) catalog.sorted = FALSE;
-
-	// no need to resort empty catalogs
-	if (catalog.Naves_disk == 0) {
-	  dvo_catalog_unlock (&catalog);
-	  dvo_catalog_free (&catalog);
-	  continue;
-	}
-
-	if (OLD_RESORT) { 
-	  resort_catalog_old (&catalog);
-	} else {
-	  resort_catalog (&catalog);
-	}
-	Nsubset = 1;
-	break;
-    }
+    }
+    MARKTIME ("match stars: %f sec\n", dtime); RESETTIME; 
+
     /* report total updated values */
     Naverage += catalog.Naverage;
     Nmeasure += catalog.Nmeasure;
+    Nlensing += catalog.Nlensing;
 
     // write out catalog, if appropriate
@@ -187,5 +174,5 @@
       SetProtect (TRUE);
       if (options.update) {
-	catalog.catflags  = LOAD_AVES | LOAD_MEAS | LOAD_MISS | LOAD_SECF;
+	catalog.catflags  = LOAD_AVES | LOAD_MEAS | LOAD_MISS | LOAD_SECF | LOAD_LENSING;
 	dvo_catalog_update (&catalog, VERBOSE);
       } else {
@@ -196,4 +183,5 @@
     dvo_catalog_unlock (&catalog);
     dvo_catalog_free (&catalog);
+    MARKTIME ("save cpt: %f sec\n", dtime); RESETTIME; 
 
     if (options.mode == ADDSTAR_MODE_REFCAT) free (stars);
@@ -229,7 +217,7 @@
   dvo_image_unlock (&db); /* unlock? */
 
-  gettimeofday (&stop, NULL);
-  dtime = DTIME (stop, start);
-  fprintf (stderr, "SUCCESS: elapsed time %9.4f sec for %5d stars (%5d matches), "OFF_T_FMT" average, "OFF_T_FMT" measure\n", dtime, Nstars, Nmatch,  Naverage,  Nmeasure);
+  gettimeofday (&stopAddstar, (void *) NULL);
+  float dtime = DTIME (stopAddstar, startAddstar);
+  fprintf (stderr, "SUCCESS: elapsed time %9.4f sec for %5d stars (%5d matches), "OFF_T_FMT" average, "OFF_T_FMT" measure, "OFF_T_FMT" lensing\n", dtime, Nstars, Nmatch,  Naverage,  Nmeasure, Nlensing);
 
   exit (0);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/addstar_client.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/addstar_client.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/addstar_client.c	(revision 37403)
@@ -25,5 +25,5 @@
 
   if (options.mode == ADDSTAR_MODE_RESORT) {
-    resort_unthreaded (&options, sky, HOST_ID, HOSTDIR);
+    resort_catalogs (&options, sky);
     exit (0);
   }
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/args.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/args.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/args.c	(revision 37403)
@@ -34,4 +34,10 @@
     remove_argument (N, &argc, argv);
   }
+  OLD_RESORT = FALSE;
+  if ((N = get_argument (argc, argv, "-old-resort"))) {
+    remove_argument (N, &argc, argv);
+    OLD_RESORT = TRUE;
+  }
+
   if ((N = get_argument (argc, argv, "-create-id"))) {
     options.mode = ADDSTAR_MODE_CREATE_ID;
@@ -75,4 +81,10 @@
     PMM_CCD_TABLE = strcreate (argv[N]);
     remove_argument (N, &argc, argv);
+  }
+
+  READ_XRAD_DATA = FALSE;
+  if ((N = get_argument (argc, argv, "-xrad"))) {
+    remove_argument (N, &argc, argv);
+    READ_XRAD_DATA = TRUE;
   }
 
@@ -350,4 +362,6 @@
   // XXX for the moment, make this selection manual.  it needs to be automatic 
   // based on the state of the SkyTable
+  HOST_ID = 0;
+  HOSTDIR = NULL;
   PARALLEL = FALSE;
   if ((N = get_argument (argc, argv, "-parallel"))) {
@@ -466,4 +480,17 @@
 }
 
+int strextend (char *input, char *format,...) {
+
+  char tmpextra[1024], tmpline[1024];
+  va_list argp;
+
+  va_start (argp, format);
+  vsnprintf (tmpextra, 1024, format, argp);
+  snprintf (tmpline, 1024, "%s %s", input, tmpextra);
+  strcpy (input, tmpline);
+
+  return TRUE;
+}
+
 /** addstar modes:
  
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/args_parallel_client.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/args_parallel_client.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/args_parallel_client.c	(revision 37403)
@@ -87,4 +87,10 @@
   }
 
+  OLD_RESORT = FALSE;
+  if ((N = get_argument (argc, argv, "-old-resort"))) {
+    remove_argument (N, &argc, argv);
+    OLD_RESORT = TRUE;
+  }
+
   /* extra error messages */
   VERBOSE = FALSE;
@@ -118,2 +124,16 @@
   exit (2);
 }
+
+int strextend (char *input, char *format,...) {
+
+  char tmpextra[1024], tmpline[1024];
+  va_list argp;
+
+  va_start (argp, format);
+  vsnprintf (tmpextra, 1024, format, argp);
+  snprintf (tmpline, 1024, "%s %s", input, tmpextra);
+  strcpy (input, tmpline);
+
+  return TRUE;
+}
+
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/build_links.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/build_links.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/build_links.c	(revision 37403)
@@ -1,3 +1,5 @@
 # include "addstar.h"
+
+# define myAbortF(FORMAT,...) { fprintf (stderr, FORMAT, __VA_ARGS__); abort(); }
 
 /* 
@@ -47,6 +49,5 @@
 
     if (N >= Nmeasure) {
-      fprintf (stderr, "overflow in init_measure_links\n");
-      abort ();
+      myAbort ("overflow in init_measure_links\n");
     }
   }
@@ -102,5 +103,5 @@
 
 /* average[].measureOffset, average[].Nmeasure are valid within an addstar run */
-off_t add_meas_link (Average *average, off_t *next_meas, off_t Nmeasure, off_t NMEASURE) {
+int add_meas_link (Average *average, off_t *next_meas, off_t Nmeasure, off_t NMEASURE) {
 
   off_t k, m;
@@ -134,10 +135,7 @@
 }
 
-/* Missing does not carry enough information to reconstruct the links
-   we must always save the missing table, if it exists */
-
 Measure *sort_measure (Average *average, off_t Naverage, Measure *measure, off_t Nmeasure, off_t *next_meas) {
 
-  off_t i, k, n, N;
+  int i, k, n, N;
   Measure *tmpmeasure;
 
@@ -149,7 +147,7 @@
     average[i].measureOffset = N;
     for (k = 0; k < average[i].Nmeasure; k++, N++) {
-      if (n == -1) abort();
+      if (n == -1) myAbortF("invalid measureOffset for ave %d, measureOffset %d, measure %d\n", i, average[i].measureOffset, k);
       tmpmeasure[N] = measure[n]; 
-      if (measure[n].averef != i) abort();
+      if (measure[n].averef != i) myAbortF("invalid averef for ave %d, measureOffset %d, measure %d, averef %d\n", i, average[i].measureOffset, k, measure[n].averef);
       tmpmeasure[N].averef = i;
       n = next_meas[n];
@@ -159,4 +157,6 @@
   return (tmpmeasure);
 }
+
+/*******************************************************************************************/
 
 /* build the initial links assuming the table is sorted */
@@ -176,6 +176,5 @@
       next_miss[N] = -1;
       if (N >= Nmissing) {
-	fprintf (stderr, "overflow in init_missing_links");
-	abort ();
+	myAbort ("overflow in init_missing_links");
       }
       N++;
@@ -186,5 +185,5 @@
 }
 
-off_t add_miss_link (Average *average, off_t *next_miss, off_t Nmissing) {
+int add_miss_link (Average *average, off_t *next_miss, off_t Nmissing) {
 
   off_t k, m;
@@ -205,4 +204,7 @@
 }
 
+/* Missing does not carry enough information to reconstruct the links
+   we must always save the missing table, if it exists */
+
 Missing *sort_missing (Average *average, off_t Naverage, Missing *missing, off_t Nmissing, off_t *next_miss) {
 
@@ -225,2 +227,140 @@
 }
 
+/*******************************************************************************************/
+
+/* build the initial links assuming the table is sorted, 
+   not partial, and has a correct set of average[].lensingOffset,Nlensing values */
+off_t *init_lensing_links (Average *average, off_t Naverage, Lensing *lensing, off_t Nlensing) {
+
+  off_t i, j, N;
+  off_t *next_lens;
+
+  N = 0;
+
+  ALLOCATE (next_lens, off_t, Nlensing);
+  for (i = 0; i < Naverage; i++) {
+    if (!average[i].Nlensing) continue;
+    for (j = 0; j < average[i].Nlensing - 1; j++, N++) {
+      next_lens[N] = N + 1;
+      if (N >= Nlensing) {
+	fprintf (stderr, "WARNING: N out of bounds (1)\n");
+      }
+    }
+    next_lens[N] = -1;
+    if (N >= Nlensing) {
+      fprintf (stderr, "WARNING: N out of bounds (2)\n");
+    }
+
+    if (N >= Nlensing) {
+      myAbort ("overflow in init_lensing_links\n");
+    }
+    N++;
+  }
+  return (next_lens);
+}
+
+/* construct lensing links which are valid FOR THIS LOAD
+ * - if we have a full load, we will get links which can
+ *   be used by other programs (eg, relphot, etc)
+ * - if we have a partial load, the links are only valid
+ *   for that partial load
+ */ 
+
+off_t *build_lensing_links (Average *average, off_t Naverage, Lensing *lensing, off_t Nlensing) {
+
+  off_t i, m, k, Nm, averef;
+  off_t *next_lens;
+
+  ALLOCATE (next_lens, off_t, Nlensing);
+
+  /* reset the Nm, offset values for average */
+  for (i = 0; i < Naverage; i++) {
+    average[i].lensingOffset = -1;
+    average[i].Nlensing     =  0;
+  }
+
+  for (Nm = 0; Nm < Nlensing; Nm++) {
+    averef = lensing[Nm].averef;
+    m = average[averef].lensingOffset;  
+    next_lens[Nm] = -1;
+
+    if (m == -1) { /* no links yet for source */
+      average[averef].lensingOffset = Nm;
+      average[averef].Nlensing     = 1;
+      continue;
+    }
+
+    for (k = 0; next_lens[m] != -1; k++) {
+      m = next_lens[m];
+      if (m >= Nlensing) {
+	fprintf (stderr, "WARNING: m out of bounds (1)\n");
+      }
+    }
+
+    average[averef].Nlensing = k + 2;
+    next_lens[m] = Nm;
+    if (m >= Nlensing) {
+      fprintf (stderr, "WARNING: m out of bounds (2)\n");
+    }
+  }
+  return (next_lens);
+}
+
+/* average[].lensingOffset, average[].Nlensing are valid within an addstar run */
+int add_lens_link (Average *average, off_t *next_lens, off_t Nlensing, off_t NLENSING) {
+
+  off_t k, m;
+
+  /* if we have trouble, check validity of next_lens[m] : m < Nlensing */
+  m = average[0].lensingOffset;  
+
+  for (k = 0; k < average[0].Nlensing - 1; k++)  {
+    m = next_lens[m];
+    if (m >= NLENSING) {
+      fprintf (stderr, "WARNING: m out of bounds (3)\n");
+    }
+  }
+
+  /* set up references */
+  next_lens[Nlensing] = -1;
+  if (Nlensing >= NLENSING) {
+    fprintf (stderr, "WARNING: Nlensing out of bounds (1)\n");
+  }
+
+  if (m == -1) {
+    average[0].lensingOffset = Nlensing;
+  } else {
+    next_lens[m] = Nlensing;
+    if (m >= NLENSING) {
+      fprintf (stderr, "WARNING: m out of bounds (4)\n");
+    }
+  }
+
+  return (TRUE);
+}
+
+Lensing *sort_lensing (Average *average, off_t Naverage, Lensing *lensing, off_t Nlensing, off_t *next_lens) {
+
+  int i, k, n, N;
+  Lensing *tmplensing;
+
+  /* fix order of Lensing (memory intensive, but fast) */
+  N = 0; 
+  ALLOCATE (tmplensing, Lensing, Nlensing);
+  for (i = 0; i < Naverage; i++) {
+    if (!average[i].Nlensing) continue;
+    n = average[i].lensingOffset;
+    average[i].lensingOffset = N;
+    for (k = 0; k < average[i].Nlensing; k++, N++) {
+      if (n == -1) myAbortF("invalid lensingOffset for ave %d, lensingOffset %d, lensing %d\n", i, average[i].lensingOffset, k);
+      tmplensing[N] = lensing[n]; 
+      if (lensing[n].averef != i) myAbortF("invalid averef for ave %d, lensingOffset %d, lensing %d, averef %d\n", i, average[i].lensingOffset, k, lensing[n].averef);
+      tmplensing[N].averef = i;
+      n = next_lens[n];
+    }
+  }
+  free (lensing);
+  return (tmplensing);
+}
+
+
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/fakeimage.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/fakeimage.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/fakeimage.c	(revision 37403)
@@ -6,5 +6,4 @@
   double pltscale, pixscale;
   double Rmin, Rmax, Dmin, Dmax;
-  // double Xmin, Xmax, Ymin, Ymax;
   double dX, dY, r, d;
   char chipname[80], chipdata[256], name[80];
@@ -168,6 +167,4 @@
   image[0].cerror = 0.0;
     
-  // RD_to_XY (&Xmax, &Ymax, Rmax, Dmax, MOSAIC);
-  // RD_to_XY (&Xmin, &Ymin, Rmin, Dmin, MOSAIC);
   image[0].NX = Rmax - Rmin;
   image[0].NY = Dmax - Dmin;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/find_matches.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/find_matches.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/find_matches.c	(revision 37403)
@@ -14,6 +14,6 @@
 
   if (NSTAR_GROUP <= 0) {
-      fprintf (stderr, "ERROR: NSTAR_GROUP NOT SET!\n");
-      exit (1);
+    fprintf (stderr, "ERROR: NSTAR_GROUP NOT SET!\n");
+    exit (1);
   }
 
@@ -36,5 +36,5 @@
   ALLOCATE (Y2, double, NAVE);
   ALLOCATE (N2, off_t,  NAVE);
-  ALLOCATE (catalog[0].found, off_t, NAVE);
+  ALLOCATE (catalog[0].found_t, off_t, NAVE);
   /* for secfilt j and star i, secfilt[i*Nsecfilt+j] */
 
@@ -77,5 +77,4 @@
   if (Nstars < 1) {
     if (VERBOSE) fprintf (stderr, "skipping %s, no overlapping stars\n", catalog[0].filename);
-    free (catalog[0].found);
     free (X1);
     free (Y1);
@@ -92,5 +91,5 @@
     RD_to_XY (&X2[i], &Y2[i], catalog[0].average[i].R, catalog[0].average[i].D, &tcoords);
     N2[i] = i;
-    catalog[0].found[N2[i]] = -1;
+    catalog[0].found_t[N2[i]] = -1;
   }
   if (Nave > 1) sort_coords_index (X2, Y2, N2, Nave);
@@ -160,6 +159,6 @@
 
       // the following measure elements cannot be set until here:
-      catalog[0].measure[Nmeas].dR       = 3600.0*(catalog[0].average[n].R - stars[N].average.R);
-      catalog[0].measure[Nmeas].dD       = 3600.0*(catalog[0].average[n].D - stars[N].average.D);
+      catalog[0].measure[Nmeas].R        = stars[N].average.R;
+      catalog[0].measure[Nmeas].D        = stars[N].average.D;
       catalog[0].measure[Nmeas].dbFlags  = 0;
       catalog[0].measure[Nmeas].averef   = n; // this must be an absolute sequence number, if partial average is loaded 
@@ -167,16 +166,21 @@
       catalog[0].measure[Nmeas].catID    = catalog[0].catID;
 
-      // rationalize dR:
-      if (catalog[0].measure[Nmeas].dR > +180.0*3600.0) {
-	  // average on high end of boundary, move star up
-	  stars[N].average.R += 360.0;
-	  catalog[0].measure[Nmeas].dR = 3600.0*(catalog[0].average[n].R - stars[N].average.R);
-      }
-      if (catalog[0].measure[Nmeas].dR < -180.0*3600.0) {
-	  // average on low end of boundary, move star down
-	  stars[N].average.R -= 360.0;
-	  catalog[0].measure[Nmeas].dR = 3600.0*(catalog[0].average[n].R - stars[N].average.R);
-      }
-      if (fabs(catalog[0].measure[Nmeas].dR) > 10*RADIUS) {
+      float dRoff = dvoOffsetR(&catalog[0].measure[Nmeas], &catalog[0].average[n]);
+
+      // rationalize R:
+      if (dRoff > +180.0*3600.0) {
+	// average on high end of boundary, move star up
+	catalog[0].measure[Nmeas].R += 360.0;
+	dRoff -= 360.0*3600.0;
+      }
+      if (dRoff < -180.0*3600.0) {
+	// average on low end of boundary, move star down
+	catalog[0].measure[Nmeas].R -= 360.0;
+	dRoff += 360.0*3600.0;
+      }
+      if (fabs(dRoff) > 10*RADIUS) {
+	// take declination into account and check again.
+	double cosD = cos(RAD_DEG*catalog[0].average[n].D);
+	if (fabs(dRoff*cosD) > 10*RADIUS) {
 	  fprintf (stderr, "error: %10.6f,%10.6f vs %10.6f,%10.6f (%f,%f vs %f,%f)\n", 
 		   catalog[0].average[n].R, catalog[0].average[n].D, 
@@ -184,4 +188,5 @@
 		   X1[i], X2[J], 
 		   Y1[i], Y2[J]);
+	}
       }
 
@@ -196,5 +201,5 @@
       if (Nsec > -1) { 
 	if (isnan(catalog[0].secfilt[n*Nsecfilt+Nsec].M)) {
-	  catalog[0].secfilt[n*Nsecfilt+Nsec].M = PhotCat (&catalog[0].measure[Nmeas]);
+	  catalog[0].secfilt[n*Nsecfilt+Nsec].M = PhotCat (&catalog[0].measure[Nmeas], MAG_CLASS_PSF);
 	}
       }
@@ -213,9 +218,9 @@
       }
       /* this catalog star matches more than one image star */
-      if (catalog[0].found[n] > -1) {
-	catalog[0].measure[catalog[0].found[n]].dbFlags |= ID_MEAS_BLEND_OBJ;
+      if (catalog[0].found_t[n] > -1) {
+	catalog[0].measure[catalog[0].found_t[n]].dbFlags |= ID_MEAS_BLEND_OBJ;
 	catalog[0].measure[Nmeas].dbFlags |= ID_MEAS_BLEND_OBJ;
       } else {
-	catalog[0].found[n] = Nmeas;
+	catalog[0].found_t[n] = Nmeas;
       }
       /* Nm is updated, but not written out in -update mode (for existing entries)
@@ -232,6 +237,6 @@
   }
 
-  /* incorporate unmatched image stars, if this star is in field of this catalog */
-  /* these new entries are all written out in UPDATE mode */ 
+/* incorporate unmatched image stars, if this star is in field of this catalog */
+/* these new entries are all written out in UPDATE mode */ 
   for (i = 0; (i < Nstars) && !options.only_match; i += NSTAR_GROUP) {
     /* make sure there is space for next entry */
@@ -260,5 +265,5 @@
 
     if (PSPS_ID) {
-        catalog[0].average[Nave].extID = CreatePSPSObjectID(catalog[0].average[Nave].R, catalog[0].average[Nave].D);
+      catalog[0].average[Nave].extID = CreatePSPSObjectID(catalog[0].average[Nave].R, catalog[0].average[Nave].D);
     }
 
@@ -274,6 +279,6 @@
 
       // the following measure elements cannot be set until here:
-      catalog[0].measure[Nmeas].dR       	= 0.0;
-      catalog[0].measure[Nmeas].dD       	= 0.0;
+      catalog[0].measure[Nmeas].R       	= stars[i].average.R;
+      catalog[0].measure[Nmeas].D       	= stars[i].average.D;
       catalog[0].measure[Nmeas].dbFlags 	= 0;
       catalog[0].measure[Nmeas].averef   	= Nave; // XXX EAM : must be absolute Nave if partial read
@@ -284,9 +289,9 @@
       /* in UPDATE mode, this value is not saved; use relphot to recalculate */
       if (Nsec > -1) { 
-          catalog[0].secfilt[Nave*Nsecfilt+Nsec].M = PhotCat (&catalog[0].measure[Nmeas]);
+	catalog[0].secfilt[Nave*Nsecfilt+Nsec].M = PhotCat (&catalog[0].measure[Nmeas], MAG_CLASS_PSF);
       }
 
       /* next[Nmeas] should always be -1 in this context (it is always the only
-         measurement for the star) */
+	 measurement for the star) */
       stars[i].found = Nmeas;
       next_meas[Nmeas] = -1;  // initial value here update below
@@ -309,5 +314,5 @@
   }
 
-  /* note stars which have been found in this catalog */
+/* note stars which have been found in this catalog */
   for (i = 0; i < NstarsIn; i++) {
     if (stars[i].found > -1) {
@@ -316,5 +321,5 @@
   }
 
-  /* check if the catalog has changed?  if no change, no need to write */
+/* check if the catalog has changed?  if no change, no need to write */
   catalog[0].objID    = objID; // new max value, save on catalog close
   catalog[0].Naverage = Nave;
@@ -323,5 +328,4 @@
   if (VERBOSE) fprintf (stderr, "Nstars, Nave, Nmeas: "OFF_T_FMT" "OFF_T_FMT" "OFF_T_FMT", ("OFF_T_FMT" matches)\n",  Nstars,  Nave,  Nmeas,  Nmatch);
 
-  free (catalog[0].found);
   free (X1);
   free (Y1);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/find_matches_closest.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/find_matches_closest.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/find_matches_closest.c	(revision 37403)
@@ -7,6 +7,6 @@
   double *X1, *Y1, *X2, *Y2;
   double dX, dY, dR;
-  off_t *N1, *N2, *next_meas;
-  off_t Nave, NAVE, Nmeas, NMEAS, Nmatch;
+  off_t *N1, *N2, *next_meas, *next_lens;
+  off_t Nave, NAVE, Nmeas, NMEAS, Nmatch, Nlens, NLENS;
   int Nsecfilt, Nsec;
   unsigned int objID, catID;
@@ -36,5 +36,5 @@
   ALLOCATE (Y2, double, NAVE);
   ALLOCATE (N2, off_t,  NAVE);
-  ALLOCATE (catalog[0].found, off_t, NAVE);
+  ALLOCATE (catalog[0].found_t, off_t, NAVE);
   /* for secfilt j and star i, secfilt[i*Nsecfilt+j] */
 
@@ -42,4 +42,5 @@
   Nmatch = 0;
   NMEAS = Nmeas = catalog[0].Nmeasure;
+  NLENS = Nlens = catalog[0].Nlensing;
 
   // current max obj ID for this catalog
@@ -76,5 +77,4 @@
   if (Nstars < 1) {
     if (VERBOSE) fprintf (stderr, "skipping %s, no overlapping stars\n", catalog[0].filename);
-    free (catalog[0].found);
     free (X1);
     free (Y1);
@@ -91,5 +91,5 @@
     RD_to_XY (&X2[i], &Y2[i], catalog[0].average[i].R, catalog[0].average[i].D, &tcoords);
     N2[i] = i;
-    catalog[0].found[N2[i]] = -1;
+    catalog[0].found_t[N2[i]] = -1;
   }
   if (Nave > 1) sort_coords_index (X2, Y2, N2, Nave);
@@ -100,6 +100,8 @@
     // is sorted while processed
     next_meas = init_measure_links (catalog[0].average, Nave, catalog[0].measure, Nmeas);
+    next_lens = init_lensing_links (catalog[0].average, Nave, catalog[0].lensing, Nlens);
   } else {
     next_meas = build_measure_links (catalog[0].average, Nave, catalog[0].measure, Nmeas);
+    next_lens = build_lensing_links (catalog[0].average, Nave, catalog[0].lensing, Nlens);
   }    
 
@@ -177,4 +179,9 @@
       REALLOCATE (catalog[0].measure, Measure, NMEAS);
     }
+    if (Nlens >= NLENS) {
+      NLENS = Nlens + 1000;
+      REALLOCATE (next_lens, off_t, NLENS);
+      REALLOCATE (catalog[0].lensing, Lensing, NLENS);
+    }
 
     /* add to end of measurement list */
@@ -186,7 +193,8 @@
     catalog[0].measure[Nmeas]          = stars[N].measure;
 
-    /** dR,dD now represent arcsec **/
-    catalog[0].measure[Nmeas].dR       = 3600.0*(catalog[0].average[n].R - stars[N].average.R);
-    catalog[0].measure[Nmeas].dD       = 3600.0*(catalog[0].average[n].D - stars[N].average.D);
+    // measure now carries R,D (not dR,dD) 
+    // note that ReadStarsFITS does not set measure.R,D and average.R,D
+    catalog[0].measure[Nmeas].R        = stars[N].average.R;
+    catalog[0].measure[Nmeas].D        = stars[N].average.D;
     catalog[0].measure[Nmeas].dbFlags  = 0;
     catalog[0].measure[Nmeas].averef   = n;
@@ -194,22 +202,40 @@
     catalog[0].measure[Nmeas].catID    = catalog[0].catID;
 
+    float dRoff = dvoOffsetR(&catalog[0].measure[Nmeas], &catalog[0].average[n]);
+
     // rationalize dR
-    if (catalog[0].measure[Nmeas].dR > +180.0*3600.0) {
+    if (dRoff > +180.0*3600.0) {
       // average on high end of boundary, move star up
-      stars[N].average.R += 360.0;
-      catalog[0].measure[Nmeas].dR = 3600.0*(catalog[0].average[n].R - stars[N].average.R);
-    }
-    if (catalog[0].measure[Nmeas].dR < -180.0*3600.0) {
+      catalog[0].measure[Nmeas].R += 360.0;
+      dRoff -= 360.0*3600.0;
+    }
+    if (dRoff < -180.0*3600.0) {
       // average on low end of boundary, move star down
-      stars[N].average.R -= 360.0;
-      catalog[0].measure[Nmeas].dR = 3600.0*(catalog[0].average[n].R - stars[N].average.R);
-    }
-    if (fabs(catalog[0].measure[Nmeas].dR) > 10*RADIUS) {
-      fprintf (stderr, "error: %10.6f,%10.6f vs %10.6f,%10.6f (%f,%f vs %f,%f)\n", 
-	       catalog[0].average[n].R, catalog[0].average[n].D, 
-	       stars[N].average.R, stars[N].average.D,
-	       X1[i], X2[Jmin], 
-	       Y1[i], Y2[Jmin]);
-	// XXX abort on this? -- this is a bad failure...
+      catalog[0].measure[Nmeas].R -= 360.0;
+      dRoff += 360.0*3600.0;
+    }
+    if (fabs(dRoff) > 10*RADIUS) {
+	// take declination into account and check again.
+	double cosD = cos(RAD_DEG*catalog[0].average[n].D);
+	if (fabs(dRoff*cosD) > 10*RADIUS) {
+	    fprintf (stderr, "error: %10.6f,%10.6f vs %10.6f,%10.6f (%f,%f vs %f,%f)\n", 
+		     catalog[0].average[n].R, catalog[0].average[n].D, 
+		     stars[N].average.R, stars[N].average.D,
+		     X1[i], X2[Jmin], 
+		     Y1[i], Y2[Jmin]);
+	    // XXX abort on this? -- this is a bad failure...
+	}
+    }
+
+    // add the lensing values if they exist
+    if (stars[N].lensing) {
+      add_lens_link (&catalog[0].average[n], next_lens, Nlens, NLENS); // ?
+      catalog[0].lensing[Nlens] = stars[N].lensing[0];
+      
+      catalog[0].lensing[Nlens].averef = n;
+      catalog[0].lensing[Nlens].objID = catalog[0].average[n].objID;
+      catalog[0].lensing[Nlens].catID = catalog[0].catID;
+      catalog[0].average[n].Nlensing ++;
+      Nlens ++;
     }
 
@@ -224,5 +250,5 @@
     if (Nsec > -1) { 
       if (isnan(catalog[0].secfilt[n*Nsecfilt+Nsec].M)) {
-	catalog[0].secfilt[n*Nsecfilt+Nsec].M = PhotCat (&catalog[0].measure[Nmeas]);
+	catalog[0].secfilt[n*Nsecfilt+Nsec].M = PhotCat (&catalog[0].measure[Nmeas], MAG_CLASS_PSF);
       }
     }
@@ -234,5 +260,5 @@
        Nm is recalculated in build_meas_links if loaded table is not sorted */
     stars[N].found = Nmeas;
-    catalog[0].found[n] = Nmeas;
+    catalog[0].found_t[n] = Nmeas;
     catalog[0].average[n].Nmeasure ++;
     Nmeas ++;
@@ -249,4 +275,9 @@
       REALLOCATE (catalog[0].measure, Measure, NMEAS);
     }
+    if (Nlens >= NLENS - NSTAR_GROUP) {
+      NLENS = Nlens + 1000;
+      REALLOCATE (next_lens, off_t, NLENS);
+      REALLOCATE (catalog[0].lensing, Lensing, NLENS);
+    }
     if (Nave >= NAVE) {
       NAVE = Nave + 1000;
@@ -278,30 +309,54 @@
 
     for (j = 0; j < NSTAR_GROUP; j++) {
-        // supply the measurments from this detection
-        catalog[0].measure[Nmeas]           = stars[i + j].measure;
-
-        // the following measure elements cannot be set until here:
-        catalog[0].measure[Nmeas].dR       = 0.0; // astrometric offset, not error
-        catalog[0].measure[Nmeas].dD       = 0.0; // astrometric offset, not error
-        catalog[0].measure[Nmeas].dbFlags  = 0;
-        catalog[0].measure[Nmeas].averef   = Nave;
-        catalog[0].measure[Nmeas].objID    = catalog[0].average[Nave].objID;
-        catalog[0].measure[Nmeas].catID    = catalog[0].catID;
-
-        /* set the average magnitude if not already set and the photcode.equiv is not 0 */
-        /* in UPDATE mode, this value is not saved; use relphot to recalculate */
-        if (Nsec > -1) { 
-            catalog[0].secfilt[Nave*Nsecfilt+Nsec].M = PhotCat (&catalog[0].measure[Nmeas]);
-        }
-
-        /* next[Nmeas] should always be -1 in this context (it is always the only
-           measurement for the star) */
-        stars[i+j].found = Nmeas;
-        next_meas[Nmeas] = -1;  // inital value here update below
-        Nmeas ++;
+      // supply the measurments from this detection
+      dvo_measure_init (&catalog[0].measure[Nmeas]);
+      catalog[0].measure[Nmeas]           = stars[i + j].measure;
+
+      // the following measure elements cannot be set until here:
+      catalog[0].measure[Nmeas].R        = stars[i].average.R;
+      catalog[0].measure[Nmeas].D        = stars[i].average.D;
+      catalog[0].measure[Nmeas].dbFlags  = 0;
+      catalog[0].measure[Nmeas].averef   = Nave;
+      catalog[0].measure[Nmeas].objID    = catalog[0].average[Nave].objID;
+      catalog[0].measure[Nmeas].catID    = catalog[0].catID;
+
+      /* set the average magnitude if not already set and the photcode.equiv is not 0 */
+      /* in UPDATE mode, this value is not saved; use relphot to recalculate */
+      if (Nsec > -1) { 
+	catalog[0].secfilt[Nave*Nsecfilt+Nsec].M = PhotCat (&catalog[0].measure[Nmeas], MAG_CLASS_PSF);
+      }
+
+      /* next[Nmeas] should always be -1 in this context (it is always the only
+	 measurement for the star) */
+      stars[i+j].found = Nmeas;
+      next_meas[Nmeas] = -1;  // inital value here update below
+      Nmeas ++;
     }
     for (j = 0; j < NSTAR_GROUP - 1; j++) {
-        next_meas[Nmeas - NSTAR_GROUP + j] = Nmeas - NSTAR_GROUP + j + 1;
-    }
+      next_meas[Nmeas - NSTAR_GROUP + j] = Nmeas - NSTAR_GROUP + j + 1;
+    }
+
+    // if we have lensing data, insert that as well
+    if (stars[i].lensing) {
+      catalog[0].average[Nave].Nlensing = NSTAR_GROUP;
+      catalog[0].average[Nave].lensingOffset = Nlens;
+      for (j = 0; j < NSTAR_GROUP; j++) {
+	// add the lensing values if they exist
+	if (stars[i + j].lensing) {
+	  dvo_lensing_init (&catalog[0].lensing[Nlens]);
+	  catalog[0].lensing[Nlens] = stars[i + j].lensing[0];
+	  
+	  catalog[0].lensing[Nlens].averef = Nave;
+	  catalog[0].lensing[Nlens].objID = catalog[0].average[Nave].objID;
+	  catalog[0].lensing[Nlens].catID = catalog[0].catID;
+	  next_lens[Nlens] = -1; 
+	  Nlens ++;
+	}
+      }
+      for (j = 0; j < NSTAR_GROUP - 1; j++) {
+	next_lens[Nlens - NSTAR_GROUP + j] = Nlens - NSTAR_GROUP + j + 1;
+      }
+    }
+
     Nave ++;
   }
@@ -309,4 +364,5 @@
   REALLOCATE (catalog[0].average, Average, Nave);
   REALLOCATE (catalog[0].measure, Measure, Nmeas);
+  REALLOCATE (catalog[0].lensing, Lensing, Nlens);
  
   if (options.nosort) {
@@ -315,4 +371,5 @@
     catalog[0].sorted = TRUE;
     catalog[0].measure = sort_measure (catalog[0].average, Nave, catalog[0].measure, Nmeas, next_meas);
+    catalog[0].lensing = sort_lensing (catalog[0].average, Nave, catalog[0].lensing, Nlens, next_lens);
   }
 
@@ -328,8 +385,8 @@
   catalog[0].Naverage = Nave;
   catalog[0].Nmeasure = Nmeas;
+  catalog[0].Nlensing = Nlens;
   catalog[0].Nsecf_mem = Nave*Nsecfilt;
-  if (VERBOSE) fprintf (stderr, "Nstars, Nave, Nmeas: "OFF_T_FMT" "OFF_T_FMT" "OFF_T_FMT", ("OFF_T_FMT" matches)\n",  Nstars,  Nave,  Nmeas,  Nmatch);
-
-  free (catalog[0].found);
+  if (VERBOSE) fprintf (stderr, "Nstars, Nave, Nmeas, Nlens: "OFF_T_FMT" "OFF_T_FMT" "OFF_T_FMT" "OFF_T_FMT", ("OFF_T_FMT" matches)\n",  Nstars,  Nave,  Nmeas,  Nlens, Nmatch);
+
   free (X1);
   free (Y1);
@@ -339,4 +396,5 @@
   free (Y2);
   free (next_meas);
+  free (next_lens);
 
   return (Nmatch);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/find_matches_closest_refstars.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/find_matches_closest_refstars.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/find_matches_closest_refstars.c	(revision 37403)
@@ -31,5 +31,5 @@
   ALLOCATE (Y2, double, NAVE);
   ALLOCATE (N2, off_t,  NAVE);
-  ALLOCATE (catalog[0].found, off_t, NAVE);
+  ALLOCATE (catalog[0].found_t, off_t, NAVE);
   /* for secfilt j and star i, secfilt[i*Nsecfilt+j] */
 
@@ -71,5 +71,4 @@
   if (Nstars < 1) {
     if (VERBOSE) fprintf (stderr, "skipping %s, no overlapping stars\n", catalog[0].filename);
-    free (catalog[0].found);
     free (X1);
     free (Y1);
@@ -86,5 +85,5 @@
     RD_to_XY (&X2[i], &Y2[i], catalog[0].average[i].R, catalog[0].average[i].D, &tcoords);
     N2[i] = i;
-    catalog[0].found[N2[i]] = -1;
+    catalog[0].found_t[N2[i]] = -1;
   }
   if (Nave > 1) sort_coords_index (X2, Y2, N2, Nave);
@@ -180,6 +179,6 @@
 
     /** *** dR,dD now in arcsec *** **/
-    catalog[0].measure[Nmeas].dR       = 3600.0*(catalog[0].average[n].R - stars[N][0].average.R);
-    catalog[0].measure[Nmeas].dD       = 3600.0*(catalog[0].average[n].D - stars[N][0].average.D);
+    catalog[0].measure[Nmeas].R        = stars[N][0].average.R;
+    catalog[0].measure[Nmeas].D        = stars[N][0].average.D;
     catalog[0].measure[Nmeas].dbFlags  = 0;
     catalog[0].measure[Nmeas].averef   = n;
@@ -187,14 +186,16 @@
     catalog[0].measure[Nmeas].catID    = catalog[0].catID;
 
+    float dRoff = dvoOffsetR(&catalog[0].measure[Nmeas], &catalog[0].average[n]);
+
     // rationalize dR:
-    if (catalog[0].measure[Nmeas].dR > +180.0*3600.0) {
+    if (dRoff > +180.0*3600.0) {
       // average on high end of boundary, move star up
-      stars[N][0].average.R += 360.0;
-      catalog[0].measure[Nmeas].dR = 3600.0*(catalog[0].average[n].R - stars[N][0].average.R);
-    }
-    if (catalog[0].measure[Nmeas].dR < -180.0*3600.0) {
+      catalog[0].measure[Nmeas].R += 360.0;
+      dRoff -= 360.0*3600.0;
+    }
+    if (dRoff < -180.0*3600.0) {
       // average on low end of boundary, move star down
-      stars[N][0].average.R -= 360.0;
-      catalog[0].measure[Nmeas].dR = 3600.0*(catalog[0].average[n].R - stars[N][0].average.R);
+      catalog[0].measure[Nmeas].R -= 360.0;
+      dRoff += 360.0*3600.0;
     }
 
@@ -218,9 +219,9 @@
     /* this catalog star matches more than one image star */
     // XXX should this be an average flag?
-    if (catalog[0].found[n] > -1) {
-      catalog[0].measure[catalog[0].found[n]].dbFlags |= ID_MEAS_BLEND_OBJ;
+    if (catalog[0].found_t[n] > -1) {
+      catalog[0].measure[catalog[0].found_t[n]].dbFlags |= ID_MEAS_BLEND_OBJ;
       catalog[0].measure[Nmeas].dbFlags |= ID_MEAS_BLEND_OBJ;
     } else {
-      catalog[0].found[n] = Nmeas;
+      catalog[0].found_t[n] = Nmeas;
     }
 
@@ -290,6 +291,6 @@
       catalog[0].measure[Nmeas]          = stars[N][0].measure;
 
-      catalog[0].measure[Nmeas].dR       = 0.0; // astrometric offset, not error
-      catalog[0].measure[Nmeas].dD       = 0.0; // astrometric offset, not error
+      catalog[0].measure[Nmeas].R       = catalog[0].average[Nave].R;
+      catalog[0].measure[Nmeas].D       = catalog[0].average[Nave].D;
       catalog[0].measure[Nmeas].dbFlags  = 0;
       catalog[0].measure[Nmeas].averef   = Nave;
@@ -329,5 +330,4 @@
   if (VERBOSE) fprintf (stderr, "Nstars, Nave, Nmeas: "OFF_T_FMT" "OFF_T_FMT" "OFF_T_FMT", ("OFF_T_FMT" matches)\n",  Nstars,  Nave,  Nmeas,  Nmatch);
 
-  free (catalog[0].found);
   free (X1);
   free (Y1);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/find_matches_refstars.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/find_matches_refstars.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/find_matches_refstars.c	(revision 37403)
@@ -37,5 +37,5 @@
   ALLOCATE (Y2, double, NAVE);
   ALLOCATE (N2, off_t,  NAVE);
-  ALLOCATE (catalog[0].found, off_t, NAVE);
+  ALLOCATE (catalog[0].found_t, off_t, NAVE);
   REALLOCATE (catalog[0].average, Average, NAVE);
   REALLOCATE (catalog[0].secfilt, SecFilt, NAVE*catalog[0].Nsecfilt);
@@ -69,5 +69,5 @@
     RD_to_XY (&X2[i], &Y2[i], catalog[0].average[i].R, catalog[0].average[i].D, &tcoords);
     N2[i] = i;
-    catalog[0].found[N2[i]] = -1;
+    catalog[0].found_t[N2[i]] = -1;
   }
   if (Nave > 1) sort_coords_index (X2, Y2, N2, Nave);
@@ -141,7 +141,7 @@
       catalog[0].measure[Nmeas]          = stars[N][0].measure;
 
-      /** *** dR,dD now in arcsec *** **/
-      catalog[0].measure[Nmeas].dR       = 3600.0*(catalog[0].average[n].R - stars[N][0].average.R);
-      catalog[0].measure[Nmeas].dD       = 3600.0*(catalog[0].average[n].D - stars[N][0].average.D);
+      /** measure now stores R,D **/
+      catalog[0].measure[Nmeas].R        = stars[N][0].average.R;
+      catalog[0].measure[Nmeas].D        = stars[N][0].average.D;
       catalog[0].measure[Nmeas].dbFlags  = 0;
       catalog[0].measure[Nmeas].averef   = n;
@@ -149,14 +149,16 @@
       catalog[0].measure[Nmeas].catID    = catalog[0].catID;
 
+      float dRoff = dvoOffsetR(&catalog[0].measure[Nmeas], &catalog[0].average[n]);
+
       // rationalize dR:
-      if (catalog[0].measure[Nmeas].dR > +180.0*3600.0) {
+      if (dRoff > +180.0*3600.0) {
 	  // average on high end of boundary, move star up
-	  stars[N][0].average.R += 360.0;
-	  catalog[0].measure[Nmeas].dR = 3600.0*(catalog[0].average[n].R - stars[N][0].average.R);
-      }
-      if (catalog[0].measure[Nmeas].dR < -180.0*3600.0) {
+	  catalog[0].measure[Nmeas].R += 360.0;
+	  dRoff -= 360.0*3600.0;
+      }
+      if (dRoff < -180.0*3600.0) {
 	  // average on low end of boundary, move star down
-	  stars[N][0].average.R -= 360.0;
-	  catalog[0].measure[Nmeas].dR = 3600.0*(catalog[0].average[n].R - stars[N][0].average.R);
+	  catalog[0].measure[Nmeas].R -= 360.0;
+	  dRoff += 360.0*3600.0;
       }
 
@@ -188,9 +190,9 @@
       }
       /* this catalog star matches more than one image star */
-      if (catalog[0].found[n] > -1) {
-	catalog[0].measure[catalog[0].found[n]].dbFlags |= ID_MEAS_BLEND_OBJ;
+      if (catalog[0].found_t[n] > -1) {
+	catalog[0].measure[catalog[0].found_t[n]].dbFlags |= ID_MEAS_BLEND_OBJ;
 	catalog[0].measure[Nmeas].dbFlags |= ID_MEAS_BLEND_OBJ;
       } else {
-	catalog[0].found[n] = Nmeas;
+	catalog[0].found_t[n] = Nmeas;
       }
 
@@ -262,6 +264,6 @@
       catalog[0].measure[Nmeas]          = stars[N][0].measure;
 
-      catalog[0].measure[Nmeas].dR       = 0.0;
-      catalog[0].measure[Nmeas].dD       = 0.0;
+      catalog[0].measure[Nmeas].R        = stars[N][0].average.R;
+      catalog[0].measure[Nmeas].D        = stars[N][0].average.D;
 
       catalog[0].measure[Nmeas].t        = (stars[N][0].measure.t == 0) ? TIMEREF : stars[N][0].measure.t;      /** careful : time_t vs e_time **/
@@ -303,5 +305,4 @@
   if (VERBOSE) fprintf (stderr, "Nstars, Nave, Nmeas: %d "OFF_T_FMT" "OFF_T_FMT", ("OFF_T_FMT" matches)\n",  Nstars,  Nave,  Nmeas,  Nmatch);
 
-  free (catalog[0].found);
   free (X1);
   free (Y1);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/findskycell.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/findskycell.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/findskycell.c	(revision 37403)
@@ -27,7 +27,7 @@
 int apply_tree (char *treefile, char *datafile);
 
-float SCALE = 1.0;
-int NX_SUB = 1;
-int NY_SUB = 1;
+float SCALE  = 1.0;
+float NX_SUB = 1.0;
+float NY_SUB = 1.0;
 
 double R_MIN = 0.0;
@@ -162,10 +162,4 @@
 }
 
-# define MARKTIME(MSG,...) {			\
-    float dtime;				\
-    gettimeofday (&stop, (void *) NULL);	\
-    dtime = DTIME (stop, start);		\
-    fprintf (stderr, MSG, __VA_ARGS__); }
-
 int mktree (char *treefile, char *catdir) {
 
@@ -223,6 +217,6 @@
   ALLOCATE (tree.Xo,   double *, tree.Nzone);
   ALLOCATE (tree.Yo,   double *, tree.Nzone);
-  ALLOCATE (tree.dX,      int *, tree.Nzone);
-  ALLOCATE (tree.dY,      int *, tree.Nzone);
+  ALLOCATE (tree.dX,    float *, tree.Nzone);
+  ALLOCATE (tree.dY,    float *, tree.Nzone);
   ALLOCATE (tree.cell,    int *, tree.Nzone);
   ALLOCATE (tree.name,  char **, tree.Nzone);
@@ -257,6 +251,6 @@
     ALLOCATE (tree.Xo[zone],   double, tree.NBAND[zone]);
     ALLOCATE (tree.Yo[zone],   double, tree.NBAND[zone]);
-    ALLOCATE (tree.dX[zone],      int, tree.NBAND[zone]);
-    ALLOCATE (tree.dY[zone],      int, tree.NBAND[zone]);
+    ALLOCATE (tree.dX[zone],    float, tree.NBAND[zone]);
+    ALLOCATE (tree.dY[zone],    float, tree.NBAND[zone]);
     ALLOCATE (tree.cell[zone], int,    tree.NBAND[zone]);
     ALLOCATE (tree.name[zone], char *, tree.NBAND[zone]);
@@ -266,6 +260,6 @@
       tree.Xo[zone][band] = NAN;
       tree.Yo[zone][band] = NAN;
-      tree.dX[zone][band] = -1;
-      tree.dY[zone][band] = -1;
+      tree.dX[zone][band] = NAN;
+      tree.dY[zone][band] = NAN;
       tree.cell[zone][band] = -1;
       ALLOCATE (tree.name[zone][band], char, BOUNDARY_TREE_NAME_LENGTH);
@@ -292,6 +286,6 @@
       REALLOCATE (tree.Xo[zone],   double, tree.NBAND[zone]);
       REALLOCATE (tree.Yo[zone],   double, tree.NBAND[zone]);
-      REALLOCATE (tree.dX[zone],      int, tree.NBAND[zone]);
-      REALLOCATE (tree.dY[zone],      int, tree.NBAND[zone]);
+      REALLOCATE (tree.dX[zone],    float, tree.NBAND[zone]);
+      REALLOCATE (tree.dY[zone],    float, tree.NBAND[zone]);
       REALLOCATE (tree.cell[zone],    int, tree.NBAND[zone]);
       REALLOCATE (tree.name[zone], char *, tree.NBAND[zone]);
@@ -301,6 +295,6 @@
 	tree.Xo[zone][band] = NAN;
 	tree.Yo[zone][band] = NAN;
-	tree.dX[zone][band] = -1;
-	tree.dY[zone][band] = -1;
+	tree.dX[zone][band] = NAN;
+	tree.dY[zone][band] = NAN;
 	tree.cell[zone][j] = -1;
 	ALLOCATE (tree.name[zone][j], char, BOUNDARY_TREE_NAME_LENGTH);
@@ -402,6 +396,5 @@
   }
 
-  struct timeval start, stop;
-  gettimeofday (&start, (void *) NULL);
+  INITTIME;
 
   int Npts = 10000000;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/load2mass_catalog.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/load2mass_catalog.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/load2mass_catalog.c	(revision 37403)
@@ -17,10 +17,13 @@
   for (i = 0; i < Nstars; i+=3) {
 
+    double R = stars[i].average.R;
+    double D = stars[i].average.D;
+
     // construct an average object for this object
     // XXX for now, the output objects will have limited astrometric interpretation...
     // XXX every 3 stars represents 3 measurements and 1 average
     dvo_average_init (&catalog[0].average[Nave]);
-    catalog[0].average[Nave].R     = stars[i].average.R;
-    catalog[0].average[Nave].D     = stars[i].average.D;
+    catalog[0].average[Nave].R     = R;
+    catalog[0].average[Nave].D     = D;
     catalog[0].average[Nave].measureOffset = Nmeas;
 
@@ -33,6 +36,6 @@
       catalog[0].measure[Nmeas]           = stars[i+j].measure;
 
-      catalog[0].measure[Nmeas].dR        = 0.0;
-      catalog[0].measure[Nmeas].dD        = 0.0;
+      catalog[0].measure[Nmeas].R         = R;
+      catalog[0].measure[Nmeas].D         = D;
       catalog[0].measure[Nmeas].dt        = NAN_S_SHORT;
 
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/loadsupercos_ops.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/loadsupercos_ops.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/loadsupercos_ops.c	(revision 37403)
@@ -1,7 +1,4 @@
 # include "addstar.h"
 # include "supercos.h"
-
-// this is defined in libohana/src/string.c but not generally exposed
-char *_parse_nextword_csv (char *string);
 
 int loadsupercos_getFilterInfo (char *line, char *emulsion, char *filterID) {
@@ -13,5 +10,5 @@
   // emulsion is field 11, filterID is field 12
   for (i = 1; i < 11; i++) {
-    p1 = _parse_nextword_csv (p1);
+    p1 = parse_nextword_csv (p1);
     if (!p1) {
       fprintf (stderr, "error parsing filter info for line %s\n", line);
@@ -24,5 +21,5 @@
   }
 
-  char *p2 = _parse_nextword_csv (p1);
+  char *p2 = parse_nextword_csv (p1);
   if (!p2) {
     fprintf (stderr, "error parsing filter info for line %s\n", line);
@@ -34,5 +31,5 @@
   }
 
-  char *p3 = _parse_nextword_csv (p2);
+  char *p3 = parse_nextword_csv (p2);
   if (!p3) {
     fprintf (stderr, "error parsing filter info for line %s\n", line);
@@ -60,5 +57,5 @@
   // lstObs is field 20
   for (i = 1; i < 20; i++) {
-    p1 = _parse_nextword_csv (p1);
+    p1 = parse_nextword_csv (p1);
     if (!p1) {
       fprintf (stderr, "error parsing filter info for line %s\n", line);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/mkcmf.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/mkcmf.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/mkcmf.c	(revision 37403)
@@ -1,4 +1,5 @@
 # include "mkcmf.h"
 
+# define ZERO_POINT 25.0
 # define SKY 100.0
 # define DSKY 2.0
@@ -14,8 +15,11 @@
 void gauss_init (int Nbin);
 double rnd_gauss (double mean, double sigma);
+void writeStars_PS1_V5_Lensing (FTable *ftable, double *X, double *Y, double *M, unsigned int *Flag, int Nstars);
+void writeStars_PS1_V5 (FTable *ftable, double *X, double *Y, double *M, unsigned int *Flag, int Nstars);
 void writeStars_PS1_V4 (FTable *ftable, double *X, double *Y, double *M, unsigned int *Flag, int Nstars);
 void writeStars_PS1_V3 (FTable *ftable, double *X, double *Y, double *M, unsigned int *Flag, int Nstars);
 void writeStars_PS1_V2 (FTable *ftable, double *X, double *Y, double *M, unsigned int *Flag, int Nstars);
 void writeStars_PS1_V1 (FTable *ftable, double *X, double *Y, double *M, int Nstars);
+void writeStars_PS1_SV3 (FTable *ftable, double *X, double *Y, double *M, unsigned int *Flag, int Nstars);
 void writeStars_PS1_DEV_1 (FTable *ftable, double *X, double *Y, double *M, int Nstars);
 void writeStars_PS1_DEV_0 (FTable *ftable, double *X, double *Y, double *M, int Nstars);
@@ -23,4 +27,9 @@
 int ADDNOISE = TRUE;
 float BAD_PSFQF_FRAC = 0.0;
+
+static float exptime = 1.0;
+static Coords coords;
+
+static char reserved[] =  "Reserved space.  This line can be used to add a new FITS card.";
 
 int main (int argc, char **argv) {
@@ -38,5 +47,4 @@
   Matrix matrix;
   FTable ftable;
-  Coords coords;
 
   int APPEND = FALSE;
@@ -105,5 +113,4 @@
   }
 
-  float exptime = 1.0;
   if ((N = get_argument (argc, argv, "-exptime"))) {
     remove_argument (N, &argc, argv);
@@ -288,5 +295,5 @@
     gfits_modify (&header, "UTC-OBS",  "%s", 1, time);
   }
-  gfits_modify (&header, "ZERO_PT", "%lf", 1, 25.0);
+  gfits_modify (&header, "ZERO_PT", "%lf", 1, ZERO_POINT);
   gfits_modify (&header, "EXPTIME", "%lf", 1, exptime);
   gfits_modify (&header, "AIRMASS", "%lf", 1, airmass);
@@ -300,4 +307,9 @@
   PutCoords (&coords, &header);
   gfits_modify (&header, "EXTNAME",   "%s", 1, exthead);
+
+  int i;
+  for (i = 1; i < 32; i++) {
+    gfits_modify_alt (&header, "COMMENT", "%C", i, reserved);
+  }
 
   ftable.header = &theader;
@@ -327,4 +339,16 @@
   if (!strcmp(type, "PS1_V4")) {
     writeStars_PS1_V4 (&ftable, X, Y, M, Flag, Nstars); 
+    found = TRUE;
+  }
+  if (!strcmp(type, "PS1_V5")) {
+    writeStars_PS1_V5 (&ftable, X, Y, M, Flag, Nstars); 
+    found = TRUE;
+  }
+  if (!strcmp(type, "PS1_V5_Lensing")) {
+    writeStars_PS1_V5_Lensing (&ftable, X, Y, M, Flag, Nstars); 
+    found = TRUE;
+  }
+  if (!strcmp(type, "PS1_SV3")) {
+    writeStars_PS1_SV3 (&ftable, X, Y, M, Flag, Nstars); 
     found = TRUE;
   }
@@ -764,2 +788,353 @@
 }
 
+void writeStars_PS1_V5 (FTable *ftable, double *X, double *Y, double *M, unsigned int *Flag, int Nstars) {
+
+  int i;
+  CMF_PS1_V5 *stars;
+  float flux, fSN;
+
+  // XXX add gaussian-distributed noise based on counts
+  // this needs to make different output 'stars' entries depending on the desired type
+  ALLOCATE (stars, CMF_PS1_V5, Nstars);
+  for (i = 0; i < Nstars; i++) {
+
+    flux = pow (10.0, -0.4*M[i]);
+    fSN = 1.0 / sqrt(flux);
+
+    stars[i].detID = i;
+    stars[i].X = X[i];
+    stars[i].Y = Y[i];
+    stars[i].dX = FX * fSN;
+    stars[i].dY = FY * fSN;
+
+    stars[i].posangle = 10.0;
+    stars[i].pltscale = 0.25;
+
+    stars[i].M = M[i];
+    stars[i].dM = fSN;
+
+    stars[i].Flux = flux;
+    stars[i].dFlux = flux * fSN;
+
+    stars[i].Map = M[i] - 0.05;
+    stars[i].MapRaw = M[i] - 0.10;
+
+    stars[i].apRadius = 8.0;
+
+    stars[i].apFlux = pow(10.0, -0.4*stars[i].Map);
+    stars[i].apFluxErr = stars[i].apFlux * fSN;
+
+    stars[i].Mcalib = M[i] + ZERO_POINT + 2.5*log10(exptime);
+    stars[i].dMcal = 0.05;
+
+    XY_to_RD (&stars[i].RA, &stars[i].DEC, X[i], Y[i], &coords);
+    stars[i].apNpix = 3.14*8.0*8.0;
+
+    stars[i].Mpeak     = M[i] + 1.0;
+    stars[i].sky       = SKY;
+    stars[i].dSky      = DSKY;
+    stars[i].psfChisq  = PSFCHI;
+    stars[i].crNsigma  = CRN;
+    stars[i].extNsigma = EXTN;
+    stars[i].fx        = FX;
+    stars[i].fy        = FY;
+    stars[i].df        = DF;
+
+    stars[i].k         = 1.0;
+    stars[i].fwhmMaj   = FX*2.8;
+    stars[i].fwhmMin   = FY*2.8;
+
+    // randomly give poor PSFQF values
+    if ((BAD_PSFQF_FRAC > 0.0) && (drand48() < BAD_PSFQF_FRAC)) {
+      stars[i].psfQF     = 0.25;
+      stars[i].psfQFperf = 0.24;
+    } else {
+      stars[i].psfQF     = PSFQUAL;
+      stars[i].psfQFperf = MAX(PSFQUAL - 0.01, 0.0);
+    }
+
+    stars[i].psfNdof   = 1;
+    stars[i].psfNpix   = 2;
+
+    stars[i].Mxx       = FX;
+    stars[i].Mxy       = 0.01;
+    stars[i].Myy       = FX;
+    stars[i].M3c       = FX;
+    stars[i].M3s       = FX;
+    stars[i].M4c       = FX;
+    stars[i].M4s       = FX;
+    stars[i].Mr1       = FX;
+    stars[i].Mrh       = FX;
+
+    stars[i].kronFlux  = flux * 1.25;
+    stars[i].kronFluxErr = fSN * flux * 1.25;
+
+    stars[i].kronInner = fSN * flux * 0.9;
+    stars[i].kronOuter = fSN * flux * 1.5;
+
+    stars[i].skyLimitRad = 1;
+    stars[i].skyLimitFlux = 2;
+    stars[i].skyLimitSlope = 0.2;
+
+    stars[i].flags     = Flag[i];
+    stars[i].flags2    = 0x80;
+
+    stars[i].nFrames   = 1;
+
+    if (ADDNOISE) {
+      stars[i].X += FX * fSN * rnd_gauss(0.0, 1.0);
+      stars[i].Y += FY * fSN * rnd_gauss(0.0, 1.0);
+      float Moff = fSN*rnd_gauss(0.0, 1.0);
+      stars[i].M += Moff;
+      stars[i].Map += Moff;
+      stars[i].MapRaw += Moff;
+      stars[i].Mcalib += Moff;
+    }
+  }
+
+  gfits_table_set_CMF_PS1_V5 (ftable, stars, Nstars);
+  gfits_modify (ftable->header, "EXTTYPE",   "%s", 1, "PS1_V5");
+}
+
+void writeStars_PS1_SV3 (FTable *ftable, double *X, double *Y, double *M, unsigned int *Flag, int Nstars) {
+
+  int i;
+  CMF_PS1_SV3 *stars;
+  float flux, fSN;
+
+  // XXX add gaussian-distributed noise based on counts
+  // this needs to make different output 'stars' entries depending on the desired type
+  ALLOCATE (stars, CMF_PS1_SV3, Nstars);
+  for (i = 0; i < Nstars; i++) {
+
+    flux = pow (10.0, -0.4*M[i]);
+    fSN = 1.0 / sqrt(flux);
+
+    stars[i].detID = i;
+    stars[i].X = X[i];
+    stars[i].Y = Y[i];
+    stars[i].dX = FX * fSN;
+    stars[i].dY = FY * fSN;
+
+    stars[i].posangle = 10.0;
+    stars[i].pltscale = 0.25;
+
+    stars[i].M = M[i];
+    stars[i].dM = fSN;
+
+    stars[i].Flux = flux;
+    stars[i].dFlux = flux * fSN;
+
+    stars[i].Map = M[i] - 0.05;
+    stars[i].MapRaw = M[i] - 0.10;
+
+    stars[i].apRadius = 8.0;
+
+    stars[i].apFlux = pow(10.0, -0.4*stars[i].Map);
+    stars[i].apFluxErr = stars[i].apFlux * fSN;
+
+    stars[i].Mcalib = M[i] + ZERO_POINT + 2.5*log10(exptime);
+    stars[i].dMcal = 0.05;
+
+    XY_to_RD (&stars[i].RA, &stars[i].DEC, X[i], Y[i], &coords);
+    stars[i].apNpix = 3.14*8.0*8.0;
+
+    stars[i].Mpeak     = M[i] + 1.0;
+    stars[i].sky       = SKY;
+    stars[i].dSky      = DSKY;
+    stars[i].psfChisq  = PSFCHI;
+    stars[i].crNsigma  = CRN;
+    stars[i].extNsigma = EXTN;
+    stars[i].fx        = FX;
+    stars[i].fy        = FY;
+    stars[i].df        = DF;
+
+    stars[i].k         = 1.0;
+    stars[i].fwhmMaj   = FX*2.8;
+    stars[i].fwhmMin   = FY*2.8;
+
+    // randomly give poor PSFQF values
+    if ((BAD_PSFQF_FRAC > 0.0) && (drand48() < BAD_PSFQF_FRAC)) {
+      stars[i].psfQF     = 0.25;
+      stars[i].psfQFperf = 0.24;
+    } else {
+      stars[i].psfQF     = PSFQUAL;
+      stars[i].psfQFperf = MAX(PSFQUAL - 0.01, 0.0);
+    }
+
+    stars[i].psfNdof   = 1;
+    stars[i].psfNpix   = 2;
+
+    stars[i].Mxx       = FX;
+    stars[i].Mxy       = 0.01;
+    stars[i].Myy       = FX;
+    stars[i].M3c       = FX;
+    stars[i].M3s       = FX;
+    stars[i].M4c       = FX;
+    stars[i].M4s       = FX;
+    stars[i].Mr1       = FX;
+    stars[i].Mrh       = FX;
+
+    stars[i].kronFlux  = flux * 1.25;
+    stars[i].kronFluxErr = fSN * flux * 1.25;
+
+    stars[i].kronInner = fSN * flux * 0.9;
+    stars[i].kronOuter = fSN * flux * 1.5;
+
+    // stars[i].skyLimitRad = 1;
+    // stars[i].skyLimitFlux = 2;
+    // stars[i].skyLimitSlope = 0.2;
+
+    stars[i].flags     = Flag[i];
+    stars[i].flags2    = 0x80;
+
+    stars[i].nFrames   = 1;
+
+    if (ADDNOISE) {
+      stars[i].X += FX * fSN * rnd_gauss(0.0, 1.0);
+      stars[i].Y += FY * fSN * rnd_gauss(0.0, 1.0);
+      float Moff = fSN*rnd_gauss(0.0, 1.0);
+      stars[i].M += Moff;
+      stars[i].Map += Moff;
+      stars[i].MapRaw += Moff;
+      stars[i].Mcalib += Moff;
+    }
+  }
+
+  gfits_table_set_CMF_PS1_SV3 (ftable, stars, Nstars);
+  gfits_modify (ftable->header, "EXTTYPE",   "%s", 1, "PS1_SV3");
+}
+
+void writeStars_PS1_V5_Lensing (FTable *ftable, double *X, double *Y, double *M, unsigned int *Flag, int Nstars) {
+
+  int i;
+  CMF_PS1_V5_Lensing *stars;
+  float flux, fSN;
+
+  // XXX add gaussian-distributed noise based on counts
+  // this needs to make different output 'stars' entries depending on the desired type
+  ALLOCATE (stars, CMF_PS1_V5_Lensing, Nstars);
+  for (i = 0; i < Nstars; i++) {
+
+    flux = pow (10.0, -0.4*M[i]);
+    fSN = 1.0 / sqrt(flux);
+
+    stars[i].detID = i;
+    stars[i].X = X[i];
+    stars[i].Y = Y[i];
+    stars[i].dX = FX * fSN;
+    stars[i].dY = FY * fSN;
+
+    stars[i].posangle = 10.0;
+    stars[i].pltscale = 0.25;
+
+    stars[i].M = M[i];
+    stars[i].dM = fSN;
+
+    stars[i].Flux = flux;
+    stars[i].dFlux = flux * fSN;
+
+    stars[i].Map = M[i] - 0.05;
+    stars[i].MapRaw = M[i] - 0.10;
+
+    stars[i].apRadius = 8.0;
+
+    stars[i].apFlux = pow(10.0, -0.4*stars[i].Map);
+    stars[i].apFluxErr = stars[i].apFlux * fSN;
+
+    stars[i].Mcalib = M[i] + ZERO_POINT + 2.5*log10(exptime);
+    stars[i].dMcal = 0.05;
+
+    XY_to_RD (&stars[i].RA, &stars[i].DEC, X[i], Y[i], &coords);
+    stars[i].apNpix = 3.14*8.0*8.0;
+
+    stars[i].Mpeak     = M[i] + 1.0;
+    stars[i].sky       = SKY;
+    stars[i].dSky      = DSKY;
+    stars[i].psfChisq  = PSFCHI;
+    stars[i].crNsigma  = CRN;
+    stars[i].extNsigma = EXTN;
+    stars[i].fx        = FX;
+    stars[i].fy        = FY;
+    stars[i].df        = DF;
+
+    stars[i].k         = 1.0;
+    stars[i].fwhmMaj   = FX*2.8;
+    stars[i].fwhmMin   = FY*2.8;
+
+    // randomly give poor PSFQF values
+    if ((BAD_PSFQF_FRAC > 0.0) && (drand48() < BAD_PSFQF_FRAC)) {
+      stars[i].psfQF     = 0.25;
+      stars[i].psfQFperf = 0.24;
+    } else {
+      stars[i].psfQF     = PSFQUAL;
+      stars[i].psfQFperf = MAX(PSFQUAL - 0.01, 0.0);
+    }
+
+    stars[i].psfNdof   = 1;
+    stars[i].psfNpix   = 2;
+
+    stars[i].Mxx       = FX;
+    stars[i].Mxy       = 0.01;
+    stars[i].Myy       = FX;
+    stars[i].M3c       = FX;
+    stars[i].M3s       = FX;
+    stars[i].M4c       = FX;
+    stars[i].M4s       = FX;
+    stars[i].Mr1       = FX;
+    stars[i].Mrh       = FX;
+
+    stars[i].X11_sm_obj = FX;
+    stars[i].X12_sm_obj = FX;
+    stars[i].X22_sm_obj = FY;
+    stars[i].E1_sm_obj  = FX;
+    stars[i].E2_sm_obj  = FX;
+
+    stars[i].X11_sh_obj = FX;
+    stars[i].X12_sh_obj = 0.2;
+    stars[i].X22_sh_obj = FY;
+    stars[i].E1_sh_obj  = FX*0.9;
+    stars[i].E2_sh_obj  = FX*0.8;
+
+    stars[i].X11_sm_psf = FX;
+    stars[i].X12_sm_psf = FX;
+    stars[i].X22_sm_psf = FX;
+    stars[i].E1_sm_psf  = FX;
+    stars[i].E2_sm_psf  = FX;
+
+    stars[i].X11_sh_psf = FX;
+    stars[i].X12_sh_psf = FX;
+    stars[i].X22_sh_psf = FX;
+    stars[i].E1_sh_psf  = FX;
+    stars[i].E2_sh_psf  = FX;
+
+    stars[i].kronFlux  = flux * 1.25;
+    stars[i].kronFluxErr = fSN * flux * 1.25;
+
+    stars[i].kronInner = fSN * flux * 0.9;
+    stars[i].kronOuter = fSN * flux * 1.5;
+
+    stars[i].skyLimitRad = 1;
+    stars[i].skyLimitFlux = 2;
+    stars[i].skyLimitSlope = 0.2;
+
+    stars[i].flags     = Flag[i];
+    stars[i].flags2    = 0x80;
+
+    stars[i].nFrames   = 1;
+
+    if (ADDNOISE) {
+      stars[i].X += FX * fSN * rnd_gauss(0.0, 1.0);
+      stars[i].Y += FY * fSN * rnd_gauss(0.0, 1.0);
+      float Moff = fSN*rnd_gauss(0.0, 1.0);
+      stars[i].M += Moff;
+      stars[i].Map += Moff;
+      stars[i].MapRaw += Moff;
+      stars[i].Mcalib += Moff;
+    }
+  }
+
+  gfits_table_set_CMF_PS1_V5_Lensing (ftable, stars, Nstars);
+  gfits_modify (ftable->header, "EXTTYPE",   "%s", 1, "PS1_V5");
+}
+
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/replace_match.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/replace_match.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/replace_match.c	(revision 37403)
@@ -12,6 +12,6 @@
     j = i + m;
     if (measure[j].photcode != star[0].measure.photcode) continue;
-    measure[j].dR = 3600.0*(average[0].R - star[0].average.R);
-    measure[j].dD = 3600.0*(average[0].D - star[0].average.D);
+    measure[j].R = star[0].average.R;
+    measure[j].D = star[0].average.D;
     measure[j].M  = star[0].measure.M;
     measure[j].dM = star[0].measure.dM;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/resort_catalog.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/resort_catalog.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/resort_catalog.c	(revision 37403)
@@ -1,55 +1,44 @@
 # include "addstar.h"
 
+void SortAveMatch (off_t *MEAS, off_t *AVE, off_t N);
+void resort_catalog_measure (Catalog *catalog);
+void resort_catalog_lensing (Catalog *catalog);
+
 void resort_catalog_old (Catalog *catalog) {
 
-  off_t *next_meas;
-  off_t Naves, Nmeas;
-  double dtime;
-  struct timeval start, stop;
+  off_t *next_meas, *next_lens;
+  off_t Naves, Nmeas, Nlens;
 
   if (catalog[0].sorted == TRUE) return;
 
-  gettimeofday (&start, NULL);
+  INITTIME;
 
   /* internal counters */
   Nmeas = catalog[0].Nmeasure;
+  Nlens = catalog[0].Nlensing;
   Naves = catalog[0].Naverage;
   
   /* set up pointers for linked list of measure, missing */
   next_meas = build_measure_links (catalog[0].average, Naves, catalog[0].measure, Nmeas);
+  next_lens = build_lensing_links (catalog[0].average, Naves, catalog[0].lensing, Nlens);
 
   catalog[0].sorted = TRUE;
   catalog[0].measure = sort_measure (catalog[0].average, Naves, catalog[0].measure, Nmeas, next_meas);
-
-  gettimeofday (&stop, NULL);
-  dtime = DTIME (stop, start);
-  fprintf (stderr, "  match time %9.4f sec for %7lld measures, %6lld average\n", dtime, (long long) Nmeas, (long long) Naves);
+  catalog[0].lensing = sort_lensing (catalog[0].average, Naves, catalog[0].lensing, Nlens, next_lens);
+
+  MARKTIME ("  match time %9.4f sec for %7lld measures, %6lld average\n", dtime, (long long) Nmeas, (long long) Naves);
 
   return;
 }
 
-// sort the measure Sequence based on the average Sequence entries
-void SortAveMeasMatch (off_t *MEAS, off_t *AVE, off_t N) {
-
-# define SWAPFUNC(A,B){ off_t tmp_meas; off_t tmp_ave;		\
-    tmp_meas = MEAS[A]; MEAS[A] = MEAS[B]; MEAS[B] = tmp_meas;	\
-    tmp_ave  = AVE[A];  AVE[A]  = AVE[B];  AVE[B]  = tmp_ave;	\
-  }
-# define COMPARE(A,B)(AVE[A] < AVE[B])
-  OHANA_SORT (N, COMPARE, SWAPFUNC);
-# undef SWAPFUNC
-# undef COMPARE
-}
-
-# define MARKTIME(MSG,...) {			\
-    float dtime;				\
-    gettimeofday (&stop, (void *) NULL);	\
-    dtime = DTIME (stop, start); start = stop;	\
-    fprintf (stderr, MSG, __VA_ARGS__); }
-
-// XXX : where is the time going?  perhaps the ALLOCATE?
-// XXX : I don't thnk his is getting the right answer yet.
-
 void resort_catalog (Catalog *catalog) {
+
+  if (catalog[0].sorted == TRUE) return;
+
+  resort_catalog_measure (catalog);
+  resort_catalog_lensing (catalog);
+}
+
+void resort_catalog_measure (Catalog *catalog) {
 
   off_t Naverage, Nmeasure;
@@ -62,6 +51,4 @@
   Measure *measureTMP = NULL;
 
-  if (catalog[0].sorted == TRUE) return;
-
   // struct timeval start, stop;
   // gettimeofday (&start, NULL);
@@ -70,4 +57,6 @@
   Nmeasure = catalog[0].Nmeasure;
   Naverage = catalog[0].Naverage;
+
+  if (!Nmeasure) return;
 
   measure = catalog[0].measure;
@@ -93,5 +82,26 @@
       myAssert(average[averageSeq[i]].catID == measure[measureSeq[i]].catID, "object / detection mismatch");
 # if (1)
-      myAssert(average[averageSeq[i]].objID == measure[measureSeq[i]].objID, "object / detection mismatch");
+      // myAssert(average[averageSeq[i]].objID == measure[measureSeq[i]].objID, "object / detection mismatch");
+      // check if the objID is correct. if not, check if it is byte-swapped (this has happened) and repair if so.  
+      // otherwise, abort
+      if (average[averageSeq[i]].objID != measure[measureSeq[i]].objID) {
+	fprintf (stderr, "object / detection mismatch average.objID = %d, measure.objID = %d, catID: %d, detID: %d", 
+		 average[averageSeq[i]].objID, measure[measureSeq[i]].objID, 
+		 measure[measureSeq[i]].catID, measure[measureSeq[i]].detID);
+	int objIDalt = measure[measureSeq[i]].objID;
+	char *byte = (char *) &objIDalt;
+	char tmp;
+	tmp = byte[0]; byte[0] = byte[3]; byte[3] = tmp;
+	tmp = byte[1]; byte[1] = byte[2]; byte[2] = tmp;
+	if (average[averageSeq[i]].objID == objIDalt) {
+	  fprintf (stderr, "objID is byte-swapped, repairing\n");
+	  measure[measureSeq[i]].objID = average[averageSeq[i]].objID; // XXX I don't really like this...
+	} else if (measure[measureSeq[i]].objID == 0) {
+	  fprintf (stderr, "objID is 0, repairing\n");
+	  measure[measureSeq[i]].objID = average[averageSeq[i]].objID; // XXX I don't really like this...
+	} else {
+	  myAbort ("objID is NOT byte-swapped, aborting\n");
+	}
+      }
 # else
       // for reasons I do not understand, the mini dvodbs generated on stsci1X had a handful of detections with an inconsistency between averef and objID.  
@@ -113,5 +123,5 @@
   // fprintf (stderr, "\n");
 
-  SortAveMeasMatch(measureSeq, averageSeq, Nmeasure);
+  SortAveMatch(measureSeq, averageSeq, Nmeasure);
   // MARKTIME("sort : %f sec\n", dtime);
 
@@ -188,2 +198,152 @@
 }
 
+void resort_catalog_lensing (Catalog *catalog) {
+
+  off_t Naverage, Nlensing;
+  Lensing *lensing;
+  Average *average;
+  off_t i, j, N, currentAve;
+
+  off_t *lensingSeq = NULL;
+  off_t *averageSeq = NULL;
+  Lensing *lensingTMP = NULL;
+
+  // struct timeval start, stop;
+  // gettimeofday (&start, NULL);
+
+  /* internal counters */
+  Nlensing = catalog[0].Nlensing;
+  Naverage = catalog[0].Naverage;
+
+  if (!Nlensing) return;
+
+  lensing = catalog[0].lensing;
+  average = catalog[0].average;
+  
+  // we have a table of average objects and an unsorted table of measurements.  each measurement
+  // has a reference to the average object sequence (as well as an ID)
+  // lensing[i].averef -> average[averef]
+  // lensing[i].objID = average[averef].objID
+  // lensing[i].catID = average[averef].catID
+
+  // we want a sorted lensing array with all averef entries in sequence
+
+  ALLOCATE (lensingSeq, off_t,   Nlensing);
+  ALLOCATE (averageSeq, off_t,   Nlensing);
+
+  for (i = 0; i < Nlensing; i++) {
+    lensingSeq[i] = i;
+    averageSeq[i] = lensing[i].averef;
+    
+    if (catalog[0].catformat >= DVO_FORMAT_PS1_V1) {
+      // earlier formats did not carry the objID or catID, so they are not available (we could assign on load, but we don't)
+      myAssert(average[averageSeq[i]].catID == lensing[lensingSeq[i]].catID, "object / detection mismatch");
+# if (1)
+      myAssert(average[averageSeq[i]].objID == lensing[lensingSeq[i]].objID, "object / detection mismatch");
+# else
+      // for reasons I do not understand, the mini dvodbs generated on stsci1X had a handful of detections with an inconsistency between averef and objID.  
+      // this happened for 28 detections in the dbs on /data/stsci1?.0/eugene/dvo3pi.20130616, but not at all (as far as I know) in the rest of LAP DVO
+      if (average[averageSeq[i]].objID != lensing[lensingSeq[i]].objID) {
+	fprintf (stderr, "R");
+	lensing[lensingSeq[i]].objID = average[averageSeq[i]].objID; // XXX I don't really like this...
+      }
+# endif
+    }
+  }
+  
+  // check that averageSeq is now in order
+  // for (i = 1; i < Nlensing; i++) {
+  //   if (averageSeq[i] < averageSeq[i-1]) {
+  //     fprintf (stderr, "%d ", (int) i);
+  //   }
+  // }
+  // fprintf (stderr, "\n");
+
+  SortAveMatch(lensingSeq, averageSeq, Nlensing);
+  // MARKTIME("sort : %f sec\n", dtime);
+
+  // check that averageSeq is now in order
+  // for (i = 1; i < Nlensing; i++) {
+  //   if (averageSeq[i] < averageSeq[i-1]) {
+  //     fprintf (stderr, "%d ", (int) i);
+  //   }
+  // }
+  // fprintf (stderr, "\n");
+
+  // copy the lensing entries in the sorted order
+  ALLOCATE (lensingTMP, Lensing, Nlensing);
+  for (i = 0; i < Nlensing; i++) {
+    j = lensingSeq[i];
+    lensingTMP[i] = lensing[j];
+  }
+  // MARKTIME("assign lensing : %f sec\n", dtime);
+
+  // update the values of average.lensingOffset and average.Nlensing
+  FREE(lensing);
+  catalog[0].lensing = lensingTMP;
+
+  N = 0;
+  currentAve = averageSeq[0];
+  average[currentAve].lensingOffset = 0;
+  for (i = 0; i < Nlensing; i++) {
+    if (averageSeq[i] != currentAve) {
+      // we have hit the next entry in the list
+      average[currentAve].Nlensing = N;
+      N = 0;
+      currentAve = averageSeq[i];
+      average[currentAve].lensingOffset = i;
+    }
+    N++;
+  }
+  // N++;
+  average[currentAve].Nlensing = N;
+  // MARKTIME("update Nlensing : %f sec\n", dtime);
+
+  int NlensingTotal = 0;
+  int lensingOffsetOK = TRUE;
+  for (i = 0; i < Naverage; i++) {
+    NlensingTotal += catalog[0].average[i].Nlensing;
+    if (VERBOSE && !(NlensingTotal <= catalog[0].Nlensing)) {
+      fprintf (stderr, "too few lensing: %d %d %d\n", (int) i, NlensingTotal, (int) catalog[0].Nlensing);
+    }
+    lensingOffsetOK &= (catalog[0].average[i].lensingOffset < catalog[0].Nlensing);
+    if (VERBOSE && !(catalog[0].average[i].lensingOffset < catalog[0].Nlensing)) {
+      fprintf (stderr, "offset too large: %d %d %d\n", (int) i, catalog[0].average[i].Nlensing, (int) catalog[0].Nlensing);
+    }
+    lensingOffsetOK &= (catalog[0].average[i].lensingOffset + catalog[0].average[i].Nlensing <= catalog[0].Nlensing);
+    if (VERBOSE && !(catalog[0].average[i].lensingOffset + catalog[0].average[i].Nlensing <= catalog[0].Nlensing)) {
+      fprintf (stderr, "orrset + Nlensing too large: %d + %d > %d %d\n", (int) i, catalog[0].average[i].lensingOffset, catalog[0].average[i].Nlensing, (int) catalog[0].Nlensing);
+    }
+  }
+
+  if (!lensingOffsetOK) {
+    fprintf (stderr, "ERROR: catalog %s has an invalid lensingOffset\n", catalog[0].filename);
+  }
+
+  if (NlensingTotal != catalog[0].Nlensing) {
+    fprintf (stderr, "ERROR: catalog %s has an invalid Nlensing\n", catalog[0].filename);
+  }
+
+  // MARKTIME("  match time %9.4f sec for %7lld lensings, %6lld average\n", dtime, (long long) Nlensing, (long long) Naverage);
+
+  catalog[0].sorted = TRUE;
+
+  FREE (lensingSeq);
+  FREE (averageSeq);
+
+  return;
+}
+
+// sort the measure or lensing Sequence based on the average Sequence entries
+void SortAveMatch (off_t *MEAS, off_t *AVE, off_t N) {
+
+# define SWAPFUNC(A,B){ off_t tmp_meas; off_t tmp_ave;		\
+    tmp_meas = MEAS[A]; MEAS[A] = MEAS[B]; MEAS[B] = tmp_meas;	\
+    tmp_ave  = AVE[A];  AVE[A]  = AVE[B];  AVE[B]  = tmp_ave;	\
+  }
+# define COMPARE(A,B)(AVE[A] < AVE[B])
+  OHANA_SORT (N, COMPARE, SWAPFUNC);
+# undef SWAPFUNC
+# undef COMPARE
+}
+
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/resort_catalogs.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/resort_catalogs.c	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/resort_catalogs.c	(revision 37403)
@@ -0,0 +1,120 @@
+# include "addstar.h"
+
+// pass in options and skylist?
+int resort_catalogs (AddstarClientOptions *options, SkyTable *sky) {
+
+  INITTIME;
+
+  if (options->only_images) {
+    fprintf (stderr, "-image (only images) makes no sense with -resort\n");
+    exit (2);
+  }
+  if (options->only_match) {
+    fprintf (stderr, "-only-match makes no sense with -resort\n");
+    exit (2);
+  }
+  if (options->nosort == 1) {
+    fprintf (stderr, "-nosort makes no sense with -resort\n");
+    exit (2);
+  }
+  if (options->update) {
+    fprintf (stderr, "-update makes no sense with -resort\n");
+    exit (2);
+  }
+  if (options->calibrate) {
+    fprintf (stderr, "-cal (calibrate) makes no sense with -resort\n");
+    exit (2);
+  }
+
+  SkyList *skylist = SkyListByPatch (sky, -1, &UserPatch);
+  
+  // in these cases, limit the sky catalogs to an existing subset
+  if (options->existing_regions) {
+    SkyList *tmp;
+    tmp = SkyListExistingSubset (skylist, CATDIR);
+    SkyListFree (skylist);
+    skylist = tmp;
+  }
+  if (VERBOSE) fprintf (stderr, "writing to "OFF_T_FMT" regions\n",  skylist[0].Nregions);
+
+  if (PARALLEL && !HOST_ID) {
+    resort_catalogs_parallel (options, skylist);
+    return TRUE;
+  }
+
+  int ForceSort = (options->nosort == 3);
+
+  if (NTHREADS == 0) {
+    resort_unthreaded (skylist, ForceSort);
+  } else {
+    resort_threaded (skylist, ForceSort);
+  }
+
+  MARKTIME ("SUCCESS: elapsed time %9.4f sec\n", dtime);
+  return TRUE;
+}
+
+// CATDIR is supplied globally
+# define DEBUG 1
+int resort_catalogs_parallel (AddstarClientOptions *options, SkyList *sky) {
+
+  // load the list of hosts
+  HostTable *table = HostTableLoad (CATDIR, sky->hosts);
+  if (!table) {
+    fprintf (stderr, "ERROR: failure reading Host Table %s for database %s\n", sky->hosts, CATDIR);
+    exit (1);
+  }    
+
+  int i;
+  for (i = 0; i < table->Nhosts; i++) {
+
+    // ensure that the paths are absolute path names
+    char *tmppath = abspath (table->hosts[i].pathname, DVO_MAX_PATH);
+    free (table->hosts[i].pathname);
+    table->hosts[i].pathname = tmppath;
+
+    char command[1024];
+    snprintf (command, 1024, "addstar_client -resort");
+    strextend (command, "-D CATDIR %s", CATDIR);
+    strextend (command, "-hostID %d", table->hosts[i].hostID);
+    strextend (command, "-hostdir %s", table->hosts[i].pathname);
+    strextend (command, "-region %f %f %f %f", UserPatch.Rmin, UserPatch.Rmax, UserPatch.Dmin, UserPatch.Dmax);
+
+    if (VERBOSE)                   strextend (command, "%s -v");
+    if (NTHREADS)                  strextend (command, "%s -threads %d", NTHREADS);
+    if (OLD_RESORT)                strextend (command, "%s -old-resort");
+    if (options->nosort == 3)      strextend (command, "%s -force-sort");
+    if (options->existing_regions) strextend (command, "%s -existing-regions");
+
+    fprintf (stderr, "command: %s\n", command);
+
+    if (PARALLEL_MANUAL) continue;
+
+    if (PARALLEL_SERIAL) {
+      int status = system (command);
+      if (status) {
+	fprintf (stderr, "ERROR running addstar_client\n");
+	exit (2);
+      }
+    } else {
+      // launch the job on the remote machine (no handshake)
+      int errorInfo = 0;
+      int pid = rconnect ("ssh", table->hosts[i].hostname, command, table->hosts[i].stdio, &errorInfo, FALSE);
+      if (!pid) {
+	if (DEBUG) fprintf (stderr, "failure to start %s (error %d)\n", table->hosts[i].hostname, errorInfo);
+	exit (1);
+      }
+      table->hosts[i].pid = pid; // save for future reference
+    }
+  }
+
+  if (PARALLEL_MANUAL) {
+    fprintf (stderr, "run the addstar_client commands above.  when these are done, hit return\n");
+    getchar();
+  }
+  if (!PARALLEL_MANUAL && !PARALLEL_SERIAL) {
+    HostTableWaitJobsGetIO (table, __FILE__, __LINE__, VERBOSE);
+  }
+
+  return TRUE;
+}      
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/resort_threaded.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/resort_threaded.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/resort_threaded.c	(revision 37403)
@@ -13,5 +13,5 @@
   int iThread;
   int state;
-  int nosort;
+  int forcesort;
   char *filename;
   SkyRegion *region;
@@ -37,9 +37,13 @@
     }
 
+    // chose the catalog file (local or remote?)
+    char hostfile[1024];
+    snprintf (hostfile, 1024, "%s/%s.cpt", HOSTDIR, threadData->region->name);
+    catalog.filename  = HOST_ID ? hostfile : threadData->filename;
+
     // set the parameters which guide catalog open/load/create
-    catalog.filename  = threadData->filename;
     catalog.catformat = dvo_catalog_catformat (CATFORMAT);  // set the default catformat from config data
     catalog.catmode   = dvo_catalog_catmode (CATMODE);      // set the default catmode from config data
-    catalog.catflags  = LOAD_AVES | LOAD_MEAS;
+    catalog.catflags  = LOAD_AVES | LOAD_MEAS | LOAD_LENSING;
     catalog.Nsecfilt  = GetPhotcodeNsecfilt ();
   
@@ -64,5 +68,5 @@
 
     // this is an overloaded value to mean 'force sort'
-    if (threadData->nosort == 3) catalog.sorted = FALSE;
+    if (threadData->forcesort) catalog.sorted = FALSE;
 
     if (OLD_RESORT) { 
@@ -88,5 +92,5 @@
 }
 
-int resort_threaded (AddstarClientOptions *options, SkyTable *sky) {
+int resort_threaded (SkyList *skylist, int ForceSort) {
 
   int j, launched, done, Nwait, Nrun;
@@ -97,40 +101,4 @@
   ThreadData *threadData;
   pthread_t *threads;
-
-  double dtime;
-  struct timeval start, stop;
-  gettimeofday (&start, NULL);
-
-  SkyList *skylist = SkyListByPatch (sky, -1, &UserPatch);
-  
-  // in these cases, limit the sky catalogs to an existing subset
-  if (options->existing_regions) {
-    SkyList *tmp;
-    tmp = SkyListExistingSubset (skylist, CATDIR);
-    SkyListFree (skylist);
-    skylist = tmp;
-  }
-  if (VERBOSE) fprintf (stderr, "writing to "OFF_T_FMT" regions\n",  skylist[0].Nregions);
-
-  if (options->only_images) {
-    fprintf (stderr, "-image (only images) makes no sense with -resort\n");
-    exit (2);
-  }
-  if (options->only_match) {
-    fprintf (stderr, "-only-match makes no sense with -resort\n");
-    exit (2);
-  }
-  if (options->nosort == 1) {
-    fprintf (stderr, "-nosort makes no sense with -resort\n");
-    exit (2);
-  }
-  if (options->update) {
-    fprintf (stderr, "-update makes no sense with -resort\n");
-    exit (2);
-  }
-  if (options->calibrate) {
-    fprintf (stderr, "-cal (calibrate) makes no sense with -resort\n");
-    exit (2);
-  }
 
   ALLOCATE(threads, pthread_t, NTHREADS);
@@ -148,4 +116,7 @@
   Naverage = Nmeasure = 0;
   for (i = 0; i < skylist[0].Nregions; i++) {
+
+    // does this host ID match the desired location for the table?
+    if (!HostTableTestHost(skylist[0].regions[i], HOST_ID)) continue;
 
     launched = FALSE;
@@ -166,5 +137,5 @@
 	if (threadData[j].state == TS_FAIL) goto failure;
 	if (threadData[j].state != TS_WAIT) continue;
-	threadData[j].nosort = options->nosort;
+	threadData[j].forcesort = ForceSort;
 	threadData[j].filename = skylist[0].filename[i];
 	threadData[j].region = skylist[0].regions[i];
@@ -203,8 +174,4 @@
   }
 
-  gettimeofday (&stop, NULL);
-  dtime = DTIME (stop, start);
-  fprintf (stderr, "SUCCESS: elapsed time %9.4f sec for, "OFF_T_FMT" average, "OFF_T_FMT" measure\n", dtime, Naverage, Nmeasure);
-
   // for (i = 0; i < NTHREADS; i++) {
   //   pthread_cancel(threads[i]);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/resort_unthreaded.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/resort_unthreaded.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/resort_unthreaded.c	(revision 37403)
@@ -1,50 +1,64 @@
 # include "addstar.h"
 
-int resort_unthreaded (AddstarClientOptions *options, SkyTable *sky, int hostID, char *hostpath) {
+// pass in options and skylist?
+int resort_unthreaded (SkyList *skylist, int ForceSort) {
 
-  double dtime;
-  struct timeval start, stop;
+  off_t i;
+  off_t Naverage, Nmeasure;
+  Catalog catalog;
 
-  gettimeofday (&start, NULL);
+  /* match stars to existing catalog data (or otherwise manipulate catalog data) */
+  Naverage = Nmeasure = 0;
+  for (i = 0; i < skylist[0].Nregions; i++) {
 
-  SkyList *skylist = SkyListByPatch (sky, -1, &UserPatch);
-  
-  // in these cases, limit the sky catalogs to an existing subset
-  if (options->existing_regions) {
-    SkyList *tmp;
-    tmp = SkyListExistingSubset (skylist, CATDIR);
-    SkyListFree (skylist);
-    skylist = tmp;
+    // does this host ID match the desired location for the table?
+    if (!HostTableTestHost(skylist[0].regions[i], HOST_ID)) continue;
+
+    // chose the catalog file (local or remote?)
+    char hostfile[1024];
+    snprintf (hostfile, 1024, "%s/%s.cpt", HOSTDIR, skylist[0].regions[i]->name);
+    catalog.filename  = HOST_ID ? hostfile : skylist[0].filename[i];
+
+    // set the parameters which guide catalog open/load/create
+    catalog.catformat = dvo_catalog_catformat (CATFORMAT);  // set the default catformat from config data
+    catalog.catmode   = dvo_catalog_catmode (CATMODE);      // set the default catmode from config data
+    catalog.catflags  = LOAD_AVES | LOAD_MEAS | LOAD_LENSING;
+    catalog.Nsecfilt  = GetPhotcodeNsecfilt ();
+
+    // an error exit status here is a significant error (disk I/O or file access)
+    if (!dvo_catalog_open (&catalog, skylist[0].regions[i], VERBOSE, "w")) {
+      fprintf (stderr, "ERROR: failure to open/create catalog file %s\n", catalog.filename);
+      exit (2);
+    }
+
+    // Naves_disk == 0 implies an empty catalog file, skip empty catalogs
+    if (catalog.Naves_disk == 0) {
+      dvo_catalog_unlock (&catalog);
+      dvo_catalog_free (&catalog);
+      continue;
+    }
+
+    // this is an overloaded value to mean 'force sort'
+    if (ForceSort) catalog.sorted = FALSE;
+
+    if (OLD_RESORT) { 
+      resort_catalog_old (&catalog);
+    } else {
+      resort_catalog (&catalog);
+    }
+
+    // report total updated values 
+    Naverage += catalog.Naverage;
+    Nmeasure += catalog.Nmeasure;
+
+    // write out catalog, if appropriate
+    SetProtect (TRUE);
+    dvo_catalog_save (&catalog, VERBOSE);
+    SetProtect (FALSE);
+    dvo_catalog_unlock (&catalog);
+    dvo_catalog_free (&catalog);
   }
-  if (VERBOSE) fprintf (stderr, "writing to "OFF_T_FMT" regions\n",  skylist[0].Nregions);
-
-  if (options->only_images) {
-    fprintf (stderr, "-image (only images) makes no sense with -resort\n");
-    exit (2);
-  }
-  if (options->only_match) {
-    fprintf (stderr, "-only-match makes no sense with -resort\n");
-    exit (2);
-  }
-  if (options->nosort == 1) {
-    fprintf (stderr, "-nosort makes no sense with -resort\n");
-    exit (2);
-  }
-  if (options->update) {
-    fprintf (stderr, "-update makes no sense with -resort\n");
-    exit (2);
-  }
-  if (options->calibrate) {
-    fprintf (stderr, "-cal (calibrate) makes no sense with -resort\n");
-    exit (2);
-  }
-
-  resort_unthreaded_catalogs (options, skylist, hostID, hostpath);
-
-  gettimeofday (&stop, NULL);
-  dtime = DTIME (stop, start);
-  fprintf (stderr, "SUCCESS: elapsed time %9.4f sec\n", dtime);
-
   return TRUE;
 }
 
+
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/resort_unthreaded_catalogs.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/resort_unthreaded_catalogs.c	(revision 37401)
+++ 	(revision )
@@ -1,132 +1,0 @@
-# include "addstar.h"
-
-int resort_unthreaded_parallel (AddstarClientOptions *options, SkyList *sky);
-
-// pass in options and skylist?
-int resort_unthreaded_catalogs (AddstarClientOptions *options, SkyList *skylist, int hostID, char *hostpath) {
-
-  off_t i;
-  off_t Naverage, Nmeasure;
-  Catalog catalog;
-
-  if (PARALLEL && !hostID) {
-    resort_unthreaded_parallel (options, skylist);
-    return TRUE;
-  }
-
-  /* match stars to existing catalog data (or otherwise manipulate catalog data) */
-  Naverage = Nmeasure = 0;
-  for (i = 0; i < skylist[0].Nregions; i++) {
-
-    // does this host ID match the desired location for the table?
-    if (!HostTableTestHost(skylist[0].regions[i], hostID)) continue;
-
-    // chose the catalog file (local or remote?)
-    char hostfile[1024];
-    snprintf (hostfile, 1024, "%s/%s.cpt", hostpath, skylist[0].regions[i]->name);
-    catalog.filename  = hostID ? hostfile : skylist[0].filename[i];
-
-    // set the parameters which guide catalog open/load/create
-    catalog.catformat = dvo_catalog_catformat (CATFORMAT);  // set the default catformat from config data
-    catalog.catmode   = dvo_catalog_catmode (CATMODE);      // set the default catmode from config data
-    catalog.catflags  = LOAD_AVES | LOAD_MEAS;
-    catalog.Nsecfilt  = GetPhotcodeNsecfilt ();
-
-    // an error exit status here is a significant error (disk I/O or file access)
-    if (!dvo_catalog_open (&catalog, skylist[0].regions[i], VERBOSE, "w")) {
-      fprintf (stderr, "ERROR: failure to open/create catalog file %s\n", catalog.filename);
-      exit (2);
-    }
-
-    // Naves_disk == 0 implies an empty catalog file, skip empty catalogs
-    if (catalog.Naves_disk == 0) {
-      dvo_catalog_unlock (&catalog);
-      dvo_catalog_free (&catalog);
-      continue;
-    }
-
-    // this is an overloaded value to mean 'force sort'
-    if (options->nosort == 3) catalog.sorted = FALSE;
-
-    if (OLD_RESORT) { 
-      resort_catalog_old (&catalog);
-    } else {
-      resort_catalog (&catalog);
-    }
-
-    // report total updated values 
-    Naverage += catalog.Naverage;
-    Nmeasure += catalog.Nmeasure;
-
-    // write out catalog, if appropriate
-    SetProtect (TRUE);
-    dvo_catalog_save (&catalog, VERBOSE);
-    SetProtect (FALSE);
-    dvo_catalog_unlock (&catalog);
-    dvo_catalog_free (&catalog);
-  }
-  return TRUE;
-}
-
-// CATDIR is supplied globally
-# define DEBUG 1
-int resort_unthreaded_parallel (AddstarClientOptions *options, SkyList *sky) {
-
-  // load the list of hosts
-  HostTable *table = HostTableLoad (CATDIR, sky->hosts);
-  if (!table) {
-    fprintf (stderr, "ERROR: failure reading Host Table %s for database %s\n", sky->hosts, CATDIR);
-    exit (1);
-  }    
-
-  int i;
-  for (i = 0; i < table->Nhosts; i++) {
-
-    // ensure that the paths are absolute path names
-    char *tmppath = abspath (table->hosts[i].pathname, DVO_MAX_PATH);
-    free (table->hosts[i].pathname);
-    table->hosts[i].pathname = tmppath;
-
-    char command[1024];
-    snprintf (command, 1024, "addstar_client -resort -hostID %d -D CATDIR %s -hostdir %s -region %f %f %f %f", 
-	      table->hosts[i].hostID, CATDIR, table->hosts[i].pathname, 
-	      UserPatch.Rmin, UserPatch.Rmax, UserPatch.Dmin, UserPatch.Dmax);
-
-    char tmpline[1024];
-    if (VERBOSE)                   { snprintf (tmpline, 1024, "%s -v",                command); strcpy (command, tmpline); }
-    if (options->nosort == 3)      { snprintf (tmpline, 1024, "%s -force-sort",       command); strcpy (command, tmpline); }
-    if (options->existing_regions) { snprintf (tmpline, 1024, "%s -existing-regions", command); strcpy (command, tmpline); }
-
-    fprintf (stderr, "command: %s\n", command);
-
-    if (PARALLEL_MANUAL) continue;
-
-    if (PARALLEL_SERIAL) {
-      int status = system (command);
-      if (status) {
-	fprintf (stderr, "ERROR running addstar_client\n");
-	exit (2);
-      }
-    } else {
-      // launch the job on the remote machine (no handshake)
-      int errorInfo = 0;
-      int pid = rconnect ("ssh", table->hosts[i].hostname, command, table->hosts[i].stdio, &errorInfo, FALSE);
-      if (!pid) {
-	if (DEBUG) fprintf (stderr, "failure to start %s (error %d)\n", table->hosts[i].hostname, errorInfo);
-	exit (1);
-      }
-      table->hosts[i].pid = pid; // save for future reference
-    }
-  }
-
-  if (PARALLEL_MANUAL) {
-    fprintf (stderr, "run the addstar_client commands above.  when these are done, hit return\n");
-    getchar();
-  }
-  if (!PARALLEL_MANUAL && !PARALLEL_SERIAL) {
-    HostTableWaitJobsGetIO (table, __FILE__, __LINE__, VERBOSE);
-  }
-
-  return TRUE;
-}      
-
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/update_coords.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/update_coords.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/src/update_coords.c	(revision 37403)
@@ -19,6 +19,6 @@
       continue;
     }
-    R = measure[m].dR;
-    D = measure[m].dD;
+    R = measure[m].R;
+    D = measure[m].D;
     r += R;
     d += D;
@@ -33,13 +33,8 @@
   r = r / Npt;  /* these are corrections in 1/100 arcsec to RA and DEC */
   d = d / Npt;
-  average[0].R -= r / 3600.0;
-  average[0].D -= d / 3600.0;
+  average[0].R = r;
+  average[0].D = d;
   m = average[0].measureOffset;  /* first measurement of this star */
-  for (i = 0; i < average[0].Nmeasure; i++) {
-    measure[m].dR -= r;
-    measure[m].dD -= d;
-    m = next[m];
-  }
-  
+
   /* measure scatter, if possible */
   if (Npt < 2) return;
@@ -47,5 +42,5 @@
   dR2 = r2 / Npt - r*r;
   dD2 = d2 / Npt - d*d;
-  average[0].ChiSqAve = sqrt (dD2 + dR2 / SQ(cos(d*RAD_DEG)));
+  average[0].ChiSqAve = 3600.0*sqrt (dD2 + dR2 / SQ(cos(d*RAD_DEG)));
   /* ChiSqAve is supposed to be a chisq */
 
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/test/simple.dvo
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/test/simple.dvo	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/addstar/test/simple.dvo	(revision 37403)
@@ -7,30 +7,34 @@
   test.fields PS1_DEV_0 PS1_V1
   test.fields PS1_DEV_1 PS1_V1
-  test.fields PS1_V1 	PS1_V1
-  test.fields PS1_V2 	PS1_V1
-  test.fields PS1_V3 	PS1_V1
-  test.fields PS1_V4 	PS1_V1
+  test.fields PS1_V1    PS1_V1
+  test.fields PS1_V2    PS1_V1
+  test.fields PS1_V3    PS1_V1
+  test.fields PS1_V4    PS1_V1
 
   test.fields PS1_DEV_0 PS1_V2
   test.fields PS1_DEV_1 PS1_V2
-  test.fields PS1_V1 	PS1_V2
-  test.fields PS1_V2 	PS1_V2
-  test.fields PS1_V3 	PS1_V2
-  test.fields PS1_V4 	PS1_V4
+  test.fields PS1_V1    PS1_V2
+  test.fields PS1_V2    PS1_V2
+  test.fields PS1_V3    PS1_V2
+  test.fields PS1_V4    PS1_V4
 
   test.fields PS1_DEV_0 PS1_V3
   test.fields PS1_DEV_1 PS1_V3
-  test.fields PS1_V1 	PS1_V3
-  test.fields PS1_V2 	PS1_V3
-  test.fields PS1_V3 	PS1_V3
-  test.fields PS1_V4 	PS1_V4
+  test.fields PS1_V1    PS1_V3
+  test.fields PS1_V2    PS1_V3
+  test.fields PS1_V3    PS1_V3
+  test.fields PS1_V4    PS1_V4
 
   test.fields PS1_DEV_0 PS1_V4
   test.fields PS1_DEV_1 PS1_V4
-  test.fields PS1_V1 	PS1_V4
-  test.fields PS1_V2 	PS1_V4
-  test.fields PS1_V3 	PS1_V4
-  test.fields PS1_V4 	PS1_V4
+  test.fields PS1_V1    PS1_V4
+  test.fields PS1_V2    PS1_V4
+  test.fields PS1_V3    PS1_V4
+  test.fields PS1_V4    PS1_V4
 end  
+
+if (not($?NO_NOISE)) 
+  $NO_NOISE = ""
+end
 
 # create a populated catdir with a single cmf -- test each field
@@ -50,9 +54,11 @@
 
   mkinput
-  exec mkcmf test.in.txt test.cmf -date 2008/1/1 -time 01:00:00 -radec $RA $DEC -type $1
+  echo mkcmf test.in.txt test.cmf -date 2008/1/1 -time 01:00:00 -radec $RA $DEC -type $1 $NO_NOISE
+  exec mkcmf test.in.txt test.cmf -date 2008/1/1 -time 01:00:00 -radec $RA $DEC -type $1 $NO_NOISE
   if ($TAP_VERBOSE)
     echo exec addstar -D CATDIR catdir.test -D CAMERA simtest test.cmf -D CATFORMAT $2 -quick-airmass
     exec addstar -D CATDIR catdir.test -D CAMERA simtest test.cmf -D CATFORMAT $2 -quick-airmass
   else
+    echo addstar -D CATDIR catdir.test -D CAMERA simtest test.cmf -D CATFORMAT $2 -quick-airmass
     exec addstar -D CATDIR catdir.test -D CAMERA simtest test.cmf -D CATFORMAT $2 -quick-airmass >& tmp.log
   end
@@ -112,9 +118,17 @@
 
     # some fields require arithmetic manipulations
-    if ("$name:0" == "KRON_FLUX") 
-     set v1 = -2.5*log(v1)
-    end
-    if ("$name:0" == "KRON_FLUX_ERR") 
-     set v1 = KRON_FLUX_ERR / KRON_FLUX
+    ## if ("$name:0" == "KRON_FLUX") 
+    ##  set v1 = -2.5*log(v1)
+    ## end
+    ## if ("$name:0" == "KRON_FLUX_ERR") 
+    ##  set v1 = KRON_FLUX_ERR / KRON_FLUX
+    ## end
+    if (("$name:0" == "X_PSF_SIG") || ("$name:0" == "Y_PSF_SIG"))
+     set v1 = int(100*(v1))
+     set v2 = int(100*(v2 + 0.0001))
+    end
+    if ("$name:0" == "POSANGLE")
+     set v1 = int((0xffff/360.0)*(v1))
+     set v2 = int((0xffff/360.0)*(v2 + 0.0028))
     end
 
@@ -206,7 +220,7 @@
 # this list is good for PS1_V1
 list testfields_PS1_V1
-  IPP_IDET          : detid	
-  X_PSF             : xccd	
-  Y_PSF             : yccd	
+  IPP_IDET          : detid     
+  X_PSF             : xccd      
+  Y_PSF             : yccd      
   X_PSF_SIG         : xccd:err #  FAIL
   Y_PSF_SIG         : yccd:err # FAIL
@@ -215,6 +229,6 @@
   POSANGLE          : SKIP # astrometry is not calibrated in the cmf
   PLTSCALE          : SKIP # astrometry is not calibrated in the cmf
-  PSF_INST_MAG      : mag:inst	
-  PSF_INST_MAG_SIG  : mag:err	
+  PSF_INST_MAG      : mag:inst  
+  PSF_INST_MAG_SIG  : mag:err   
   AP_MAG_STANDARD   : mag:ap # FAIL
   AP_MAG_RADIUS     : SKIP # no accessor
@@ -222,13 +236,13 @@
   CAL_PSF_MAG       : SKIP # photometry is not calibrated in the cmf
   CAL_PSF_MAG_SIG   : SKIP # photometry is not calibrated in the cmf
-  SKY               : sky	
-  SKY_SIG           : sky_err	
-  PSF_CHISQ         : psf_chisq	
-  CR_NSIGMA         : cr_nsigma	
+  SKY               : sky       
+  SKY_SIG           : sky_err   
+  PSF_CHISQ         : psf_chisq 
+  CR_NSIGMA         : cr_nsigma 
   EXT_NSIGMA        : ext_nsigma
-  PSF_MAJOR         : FWHM_MAJ	
-  PSF_MINOR         : FWHM_MIN	
+  PSF_MAJOR         : FWHM_MAJ  
+  PSF_MINOR         : FWHM_MIN  
   PSF_THETA         : THETA # FAIL
-  PSF_QF            : PSF_QF	
+  PSF_QF            : PSF_QF    
   PSF_NDOF          : SKIP # no accessor
   PSF_NPIX          : SKIP # no accessor
@@ -237,12 +251,12 @@
   MOMENTS_YY        : SKIP # no accessor
   FLAGS             : phot_flags
-  N_FRAMES          : SKIP # no accessor	
+  N_FRAMES          : SKIP # no accessor        
 end
 
 # this list is good for PS1_V2
 list testfields_PS1_V2
-  IPP_IDET          : detid	
-  X_PSF             : xccd	
-  Y_PSF             : yccd	
+  IPP_IDET          : detid     
+  X_PSF             : xccd      
+  Y_PSF             : yccd      
   X_PSF_SIG         : xccd:err # FAIL
   Y_PSF_SIG         : yccd:err # FAIL
@@ -251,6 +265,6 @@
   POSANGLE          : SKIP # astrometry is not calibrated in the cmf
   PLTSCALE          : SKIP # astrometry is not calibrated in the cmf
-  PSF_INST_MAG      : mag:inst	
-  PSF_INST_MAG_SIG  : mag:err	
+  PSF_INST_MAG      : mag:inst  
+  PSF_INST_MAG_SIG  : mag:err   
   AP_MAG_STANDARD   : mag:ap # FAIL
   AP_MAG_RADIUS     : SKIP # no accessor
@@ -258,13 +272,13 @@
   CAL_PSF_MAG       : SKIP # photometry is not calibrated in the cmf
   CAL_PSF_MAG_SIG   : SKIP # photometry is not calibrated in the cmf
-  SKY               : sky	
-  SKY_SIG           : sky_err	
-  PSF_CHISQ         : psf_chisq	
-  CR_NSIGMA         : cr_nsigma	
+  SKY               : sky       
+  SKY_SIG           : sky_err   
+  PSF_CHISQ         : psf_chisq 
+  CR_NSIGMA         : cr_nsigma 
   EXT_NSIGMA        : ext_nsigma
-  PSF_MAJOR         : FWHM_MAJ	
-  PSF_MINOR         : FWHM_MIN	
+  PSF_MAJOR         : FWHM_MAJ  
+  PSF_MINOR         : FWHM_MIN  
   PSF_THETA         : THETA # FAIL
-  PSF_QF            : PSF_QF	
+  PSF_QF            : PSF_QF    
   PSF_NDOF          : SKIP # no accessor
   PSF_NPIX          : SKIP # no accessor
@@ -273,18 +287,18 @@
   MOMENTS_YY        : SKIP # no accessor
   FLAGS             : phot_flags
-  N_FRAMES          : SKIP # no accessor	
+  N_FRAMES          : SKIP # no accessor        
 end
 
 # this list is good for PS1_V3
 list testfields_PS1_V3
-  IPP_IDET          : detid	
-  X_PSF             : xccd	
-  Y_PSF             : yccd	
+  IPP_IDET          : detid     
+  X_PSF             : xccd      
+  Y_PSF             : yccd      
   X_PSF_SIG         : xccd:err # FAIL
   Y_PSF_SIG         : yccd:err # FAIL
   POSANGLE          : SKIP # astrometry is not calibrated in the cmf
   PLTSCALE          : SKIP # astrometry is not calibrated in the cmf
-  PSF_INST_MAG      : mag:inst	
-  PSF_INST_MAG_SIG  : mag:err	
+  PSF_INST_MAG      : mag:inst  
+  PSF_INST_MAG_SIG  : mag:err   
   PSF_INST_FLUX     : SKIP # not ingested into DVO
   PSF_INST_FLUX_SIG : SKIP # not ingested into DVO
@@ -297,13 +311,13 @@
   DEC_PSF           : SKIP # astrometry is not calibrated in the cmf
   PEAK_FLUX_AS_MAG  : SKIP # not ingested into DVO
-  SKY               : sky	
-  SKY_SIG           : sky_err	
-  PSF_CHISQ         : psf_chisq	
-  CR_NSIGMA         : cr_nsigma	
+  SKY               : sky       
+  SKY_SIG           : sky_err   
+  PSF_CHISQ         : psf_chisq 
+  CR_NSIGMA         : cr_nsigma 
   EXT_NSIGMA        : ext_nsigma
-  PSF_MAJOR         : FWHM_MAJ	
-  PSF_MINOR         : FWHM_MIN	
+  PSF_MAJOR         : FWHM_MAJ  
+  PSF_MINOR         : FWHM_MIN  
   PSF_THETA         : THETA # FAIL
-  PSF_QF            : PSF_QF	
+  PSF_QF            : PSF_QF    
   PSF_QF_PERFECT    : SKIP # not ingested into DVO
   PSF_NDOF          : PSF_NDOF
@@ -326,51 +340,118 @@
 end
 
-# this list is good for PS1_V4
-list testfields_PS1_V4
-  IPP_IDET          : detid	
-  X_PSF             : xccd	
-  Y_PSF             : yccd	
-  X_PSF_SIG         : xccd:err # FAIL
-  Y_PSF_SIG         : yccd:err # FAIL
-  POSANGLE          : SKIP # astrometry is not calibrated in the cmf
-  PLTSCALE          : SKIP # astrometry is not calibrated in the cmf
-  PSF_INST_MAG      : mag:inst	
-  PSF_INST_MAG_SIG  : mag:err	
-  PSF_INST_FLUX     : SKIP # not ingested into DVO
-  PSF_INST_FLUX_SIG : SKIP # not ingested into DVO
-  AP_MAG            : mag:aperinst # FAIL
+# this list is good for PS1_V5
+list testfields_PS1_V5
+  IPP_IDET          : detid     
+  X_PSF             : xccd      
+  Y_PSF             : yccd      
+  X_PSF_SIG         : xccd:err
+  Y_PSF_SIG         : yccd:err
+  POSANGLE          : posangle
+  PLTSCALE          : platescale
+  PSF_INST_MAG      : mag:inst  
+  PSF_INST_MAG_SIG  : mag:err   
+  PSF_INST_FLUX     : flux:inst
+  PSF_INST_FLUX_SIG : flux:inst:err
+  AP_MAG            : mag:aper:inst
   AP_MAG_RAW        : SKIP # not ingested into DVO
   AP_MAG_RADIUS     : SKIP # not ingested into DVO
-  CAL_PSF_MAG       : SKIP # photometry is not calibrated in the cmf
-  CAL_PSF_MAG_SIG   : SKIP # photometry is not calibrated in the cmf
-  RA_PSF            : SKIP # astrometry is not calibrated in the cmf
-  DEC_PSF           : SKIP # astrometry is not calibrated in the cmf
-  PEAK_FLUX_AS_MAG  : SKIP # not ingested into DVO
-  SKY               : sky	
-  SKY_SIGMA         : sky_err	
-  PSF_CHISQ         : psf_chisq	
-  CR_NSIGMA         : cr_nsigma	
-  EXT_NSIGMA        : ext_nsigma
-  PSF_MAJOR         : FWHM_MAJ	
-  PSF_MINOR         : FWHM_MIN	
-  PSF_THETA         : THETA # FAIL
-  PSF_QF            : PSF_QF	
-  PSF_QF_PERFECT    : SKIP # not ingested into DVO
-  PSF_NDOF          : PSF_NDOF
-  PSF_NPIX          : PSF_NPIX
-  MOMENTS_XX        : MXX
-  MOMENTS_XY        : MXY
-  MOMENTS_YY        : MYY
-  MOMENTS_M3C       : SKIP # not ingested into DVO
-  MOMENTS_M3S       : SKIP # not ingested into DVO
-  MOMENTS_M4C       : SKIP # not ingested into DVO
-  MOMENTS_M4S       : SKIP # not ingested into DVO
-  MOMENTS_R1        : SKIP # not ingested into DVO
-  MOMENTS_RH        : SKIP # not ingested into DVO
-  KRON_FLUX         : mag:kroninst
-  KRON_FLUX_ERR     : mag:kronerr
-  KRON_FLUX_INNER   : SKIP # not ingested into DVO
-  KRON_FLUX_OUTER   : SKIP # not ingested into DVO
-  FLAGS             : phot_flags
-  N_FRAMES          : SKIP # not ingested into DVO
-end
+  AP_FLUX           : flux:aper:inst  
+  AP_FLUX_SIG       : flux:aper:inst:err
+  CAL_PSF_MAG       : mag:cal
+  CAL_PSF_MAG_SIG   : mag:cal:err
+  RA_PSF            : ra
+  DEC_PSF           : dec
+  AP_NPIX           : SKIP # not ingested into DVO		      
+  PEAK_FLUX_AS_MAG  : SKIP # not ingested into DVO		      
+  SKY               : sky       				      
+  SKY_SIGMA         : sky_err   				      
+  PSF_CHISQ         : psf_chisq 				      
+  CR_NSIGMA         : cr_nsigma 				      
+  EXT_NSIGMA        : ext_nsigma				      
+  PSF_MAJOR         : fwhm_maj # XXX technically, this is not FWHM but Sigma
+  PSF_MINOR         : fwhm_min # XXX technically, this is not FWHM but Sigma
+  PSF_THETA         : theta # FAIL				      
+  PSF_CORE          : SKIP # not ingested into DVO 
+  PSF_FWHM_MAJ      : SKIP # not ingested into DVO 
+  PSF_FWHM_MIN      : SKIP # not ingested into DVO 
+  PSF_QF            : psf_qf    				      
+  PSF_QF_PERFECT    : SKIP # not ingested into DVO		      
+  PSF_NDOF          : psf_ndof				      
+  PSF_NPIX          : psf_npix				      
+  MOMENTS_XX        : Mxx					      
+  MOMENTS_XY        : Mxy					      
+  MOMENTS_YY        : Myy					      
+  MOMENTS_M3C       : SKIP # not ingested into DVO		      
+  MOMENTS_M3S       : SKIP # not ingested into DVO		      
+  MOMENTS_M4C       : SKIP # not ingested into DVO		      
+  MOMENTS_M4S       : SKIP # not ingested into DVO		      
+  MOMENTS_R1        : SKIP # not ingested into DVO		      
+  MOMENTS_RH        : SKIP # not ingested into DVO		      
+  KRON_FLUX         : flux:kron:inst				      
+  KRON_FLUX_ERR     : flux:kron:inst:err				      
+  KRON_FLUX_INNER   : SKIP # not ingested into DVO		          
+  KRON_FLUX_OUTER   : SKIP # not ingested into DVO		      
+  SKY_LIMIT_RAD     : SKIP # not ingested into DVO		          
+  SKY_LIMIT_FLUX    : SKIP # not ingested into DVO		          
+  SKY_LIMIT_SLOPE   : SKIP # not ingested into DVO		          
+  FLAGS             : phot_flags				      
+  FLAGS2            : SKIP # not ingested into DVO		          
+  N_FRAMES          : SKIP # not ingested into DVO		      
+end								      
+
+# this list is good for PS1_SV3
+list testfields_PS1_SV3
+  IPP_IDET          : detid     
+  X_PSF             : xccd      
+  Y_PSF             : yccd      
+  X_PSF_SIG         : xccd:err
+  Y_PSF_SIG         : yccd:err
+  POSANGLE          : posangle
+  PLTSCALE          : platescale
+  PSF_INST_MAG      : mag:inst  
+  PSF_INST_MAG_SIG  : mag:err   
+  PSF_INST_FLUX     : flux:inst
+  PSF_INST_FLUX_SIG : flux:inst:err
+  AP_MAG            : mag:aper:inst
+  AP_MAG_RAW        : SKIP # not ingested into DVO
+  AP_MAG_RADIUS     : SKIP # not ingested into DVO
+  AP_FLUX           : flux:aper:inst  
+  AP_FLUX_SIG       : flux:aper:inst:err
+  CAL_PSF_MAG       : mag:cal
+  CAL_PSF_MAG_SIG   : mag:cal:err
+  RA_PSF            : ra
+  DEC_PSF           : dec
+  AP_NPIX           : SKIP # not ingested into DVO		      
+  PEAK_FLUX_AS_MAG  : SKIP # not ingested into DVO		      
+  SKY               : sky       				      
+  SKY_SIGMA         : sky_err   				      
+  PSF_CHISQ         : psf_chisq 				      
+  CR_NSIGMA         : cr_nsigma 				      
+  EXT_NSIGMA        : ext_nsigma				      
+  PSF_MAJOR         : fwhm_maj # XXX technically, this is not FWHM but Sigma
+  PSF_MINOR         : fwhm_min # XXX technically, this is not FWHM but Sigma
+  PSF_THETA         : theta # FAIL				      
+  PSF_CORE          : SKIP # not ingested into DVO 
+  PSF_FWHM_MAJ      : SKIP # not ingested into DVO 
+  PSF_FWHM_MIN      : SKIP # not ingested into DVO 
+  PSF_QF            : psf_qf    				      
+  PSF_QF_PERFECT    : SKIP # not ingested into DVO		      
+  PSF_NDOF          : psf_ndof				      
+  PSF_NPIX          : psf_npix				      
+  MOMENTS_XX        : Mxx					      
+  MOMENTS_XY        : Mxy					      
+  MOMENTS_YY        : Myy					      
+  MOMENTS_M3C       : SKIP # not ingested into DVO		      
+  MOMENTS_M3S       : SKIP # not ingested into DVO		      
+  MOMENTS_M4C       : SKIP # not ingested into DVO		      
+  MOMENTS_M4S       : SKIP # not ingested into DVO		      
+  MOMENTS_R1        : SKIP # not ingested into DVO		      
+  MOMENTS_RH        : SKIP # not ingested into DVO		      
+  KRON_FLUX         : flux:kron:inst				      
+  KRON_FLUX_ERR     : flux:kron:inst:err				      
+  KRON_FLUX_INNER   : SKIP # not ingested into DVO		          
+  KRON_FLUX_OUTER   : SKIP # not ingested into DVO		      
+  FLAGS             : phot_flags				      
+  FLAGS2            : SKIP # not ingested into DVO		          
+  N_FRAMES          : SKIP # not ingested into DVO		      
+end								      
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/Makefile
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/Makefile	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/Makefile	(revision 37403)
@@ -0,0 +1,57 @@
+default: checkastro checkastro_client
+help:
+	@echo "make options: checkastro (default)"
+
+include ../../Makefile.System
+HOME    =       $(ROOT)/src/checkastro
+BIN	=	$(HOME)/bin
+LIB	=	$(HOME)/lib
+SRC	=	$(HOME)/src
+MAN	=	$(HOME)/doc
+INC	= 	$(HOME)/include
+include ../../Makefile.Common
+
+# programs may add their own internal requirements here
+FULL_CFLAGS   = $(BASE_CFLAGS)
+FULL_CPPFLAGS = $(BASE_CPPFLAGS)
+FULL_LDFLAGS  = -lkapa -ldvo -lFITS -lohana $(BASE_LDFLAGS)
+
+checkastro: $(BIN)/checkastro.$(ARCH)
+checkastro_client: $(BIN)/checkastro_client.$(ARCH)
+
+install: $(DESTBIN)/checkastro $(DESTBIN)/checkastro_client $(DESTBIN)/testparallax
+
+CHECKASTRO = \
+$(SRC)/ConfigInit.$(ARCH).o	     \
+$(SRC)/ImageOps.$(ARCH).o	     \
+$(SRC)/SetSignals.$(ARCH).o 	     \
+$(SRC)/Shutdown.$(ARCH).o 	     \
+$(SRC)/args.$(ARCH).o		     \
+$(SRC)/bcatalog.$(ARCH).o	     \
+$(SRC)/initialize.$(ARCH).o	     \
+$(SRC)/load_catalogs.$(ARCH).o	     \
+$(SRC)/load_images.$(ARCH).o	     \
+$(SRC)/select_images.$(ARCH).o	     \
+$(SRC)/checkastro.$(ARCH).o	     \
+$(SRC)/checkastro_images.$(ARCH).o   \
+$(SRC)/MeasFilterTest.$(ARCH).o      \
+$(SRC)/BrightCatalog.$(ARCH).o
+
+$(CHECKASTRO): $(INC)/checkastro.h
+$(BIN)/checkastro.$(ARCH): $(CHECKASTRO)
+
+CHECKASTRO_CLIENT = \
+$(SRC)/ConfigInit.$(ARCH).o	     \
+$(SRC)/SetSignals.$(ARCH).o 	     \
+$(SRC)/Shutdown.$(ARCH).o 	     \
+$(SRC)/args.$(ARCH).o		     \
+$(SRC)/bcatalog.$(ARCH).o	     \
+$(SRC)/initialize.$(ARCH).o	     \
+$(SRC)/load_catalogs.$(ARCH).o	     \
+$(SRC)/checkastro_client.$(ARCH).o   \
+$(SRC)/MeasFilterTest.$(ARCH).o      \
+$(SRC)/BrightCatalog.$(ARCH).o 
+
+$(CHECKASTRO_CLIENT): $(INC)/checkastro.h
+$(BIN)/checkastro_client.$(ARCH): $(CHECKASTRO_CLIENT)
+
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/include/checkastro.h
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/include/checkastro.h	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/include/checkastro.h	(revision 37403)
@@ -0,0 +1,145 @@
+# include <ohana.h>
+# include <dvo.h>
+# include <kapa.h>
+# include <signal.h>
+# include <assert.h>
+# include <pthread.h>
+
+// choose off_t or int depending on full-scale relphot analysis resources
+// # define IDX_T off_t
+# define IDX_T int 
+
+typedef struct {
+  Average     *average;	      // array of (minimal) average data
+  MeasureTiny *measure;	      // array of (minimal) measure data 
+  SecFilt     *secfilt;	      // array of secfilt data (matched to average by Nsecfilt)
+  off_t       Naverage;
+  off_t       Nmeasure;
+} BrightCatalog;
+
+typedef struct {
+  Catalog *catalog;	      // array of catalogs generated
+  int NCATALOG;		      // number of catalogs allocated
+  int Ncatalog;		      // number of catalogs generated
+  int Nsecfilt;		      // number of catalogs generated
+  off_t *NAVERAGE; 	      // allocated Averages per catalog
+  off_t *NMEASURE;	      // allocated Measures per catalog
+  int   *index;		      // lookup table catID -> catalog[i]
+  int   *catIDs;	      // lookup table catID <- catalog[i]
+  int    maxID;		      // max catID value to date
+} CatalogSplitter;
+
+/* global variables set in parameter file */
+# define DVO_MAX_PATH 1024
+char   ImageCat[DVO_MAX_PATH];
+char   GSCFILE[DVO_MAX_PATH];
+char   CATDIR[DVO_MAX_PATH];
+
+char   CATMODE[16];    /* raw, mef, split, mysql */
+char   CATFORMAT[16];  /* internal, elixir, loneos, panstarrs */
+char   SKY_TABLE[DVO_MAX_PATH];
+int    SKY_DEPTH;  /** XXX EAM : depth of catalog tables, fix usage */
+
+int          HOST_ID;
+char        *HOSTDIR;
+char        *BCATALOG;
+
+unsigned int OBJ_ID_SRC;
+unsigned int CAT_ID_SRC;
+unsigned int OBJ_ID_DST;
+unsigned int CAT_ID_DST;
+
+double SIGMA_LIM;
+int SRC_MEAS_TOOFEW; //catalog objects wich fewer detections then this are ignored
+double MIN_ERROR;
+
+int    PARALLEL;
+int    PARALLEL_MANUAL;
+int    PARALLEL_SERIAL;
+
+int    VERBOSE;
+int    VERBOSE2;
+
+int MaxDensityUse;
+double MaxDensityValue;
+
+char          *PHOTCODE_KEEP_LIST, *PHOTCODE_SKIP_LIST, *PHOTCODE_RESET_LIST;
+int           NphotcodesKeep,      NphotcodesSkip,      NphotcodesReset;
+PhotCode     **photcodesKeep,     **photcodesSkip,     **photcodesReset;
+
+int ImagSelect;
+double ImagMin, ImagMax;
+
+int PhotFlagSelect, PhotFlagPoor, PhotFlagBad;
+
+float MinBadQF;
+
+int TimeSelect;
+time_t TSTART, TSTOP;
+
+SkyRegion UserPatch;
+
+/*** relphot prototypes ***/
+void          ConfigInit          PROTO((int *argc, char **argv));
+void          GetConfig           PROTO((char *config, char *field, char *format, int N, void *ptr));
+
+int           args                PROTO((int argc, char **argv));
+int           args_client         PROTO((int argc, char **argv));
+int           bcatalog            PROTO((Catalog *subcatalog, Catalog *catalog));
+
+void          findImages          PROTO((Catalog *catalog, int Ncatalog));
+int           findMosaics         PROTO((Catalog *catalog, int Ncatalog));
+
+void          set_db              PROTO((FITS_DB *in));
+int           Shutdown            PROTO((char *format, ...)) OHANA_FORMAT(printf, 1, 2);
+void          TrapSignal          PROTO((int sig));
+void          SetProtect          PROTO((int mode));
+int           SetSignals          PROTO((void));
+
+void          freeImageBins       PROTO((int Ncatalog));
+void          free_catalogs       PROTO((Catalog *catalog, int Ncatalog));
+
+void          initImageBins       PROTO((Catalog *catalog, int Ncatalog));
+void          initImages          PROTO((Image *input, off_t *line_number, off_t N));
+
+void          initialize          PROTO((int argc, char **argv));
+void          initialize_client   PROTO((int argc, char **argv));
+
+Catalog      *load_catalogs       PROTO((SkyList *skylist, int *Ncatalog, int subselect, int hostID, char *hostpath));
+int           load_images         PROTO((FITS_DB *db, SkyList *skylist));
+Image        *select_images       PROTO((SkyList *skylist, Image *timage, off_t Ntimage, off_t **LineNumber, off_t *Nimage));
+
+void check_permissions (char *basefile);
+void lock_image_db (FITS_DB *db, char *filename);
+void unlock_image_db (FITS_DB *db);
+void create_image_db (FITS_DB *db);
+void save_catalogs (Catalog *catalog, int Ncatalog);
+
+int reload_images (FITS_DB *db);
+
+int           main                PROTO((int argc, char **argv));
+
+void          matchImage          PROTO((Catalog *catalog, off_t meas, int cat));
+
+void          set_ZP              PROTO((double ZERO));
+
+off_t getImageByID (off_t ID);
+
+int checkastro_objects (SkyList *skylist, int hostID, char *hostpath);
+int checkastro_images (SkyList *skylist);
+
+int LimitDensityCatalog_ByNmeasure (Catalog *subcatalog, Catalog *catalog);
+int LimitDensityCatalog_RandomSample (Catalog *subcatalog, Catalog *catalog);
+
+BrightCatalog *BrightCatalogLoad(char *filename);
+int BrightCatalogSave(char *filename, BrightCatalog *catalog);
+BrightCatalog *BrightCatalogMerge (Catalog *catalog, int Ncatalog);
+CatalogSplitter *BrightCatalogSplitInit (int Nsecfilt);
+int BrightCatalogSplit (CatalogSplitter *catalogs, BrightCatalog *bcatalog);
+int BrightCatalogSplitFree (CatalogSplitter *catalogs);
+
+Catalog *load_catalogs_parallel (SkyList *sky, int *Ncatalog);
+void bcatalog_show_skips ();
+
+int MeasFilterTestTiny(MeasureTiny *measure, int applySigmaLim);
+int MeasFilterTest(Measure *measure, int applySigmaLim);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/BrightCatalog.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/BrightCatalog.c	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/BrightCatalog.c	(revision 37403)
@@ -0,0 +1,906 @@
+# include "checkastro.h"
+
+// NOTE: this file is nearly identical to relphot/src/BrightCatalog.c, but here we use Average, not AverageTiny
+
+// checkastro_client -load reads from the local catalogs and generates a set of bright, subset catalogs
+// we are going to save these as a single big FITS file, with only 3 extensions:
+
+// measure, average, secfilt.  these only need to contain the fields relevant to the
+// MeasureTiny, Average, and Secfilt tables, but with cat_id appended to each row so we can
+// reassign correctly on read
+
+# define GET_COLUMN(OUT,NAME,TYPE)					\
+  TYPE *OUT = gfits_get_bintable_column_data (&theader, &ftable, NAME, type, &Nrow, &Ncol); \
+  myAssert (!strcmp(type, #TYPE), "wrong column type");
+
+// XXX double check the header extname values for each table
+// XXX make sure we free things as we can
+// XXX make sure we close files as we can
+// XXX handle free and close on error return as well
+BrightCatalog *BrightCatalogLoad(char *filename) {
+
+  int i, Ncol;
+  off_t Nrow;
+  char type[16];
+  Header header;
+  Header theader;
+  Matrix matrix;
+  FTable ftable;
+
+  header.buffer = NULL;
+  matrix.buffer = NULL;
+  ftable.buffer = NULL;
+  theader.buffer = NULL;
+  BrightCatalog *catalog = NULL;
+
+  FILE *f = fopen (filename, "r");
+  if (!f) {
+    fprintf (stderr, "ERROR: cannot open image subset file %s\n", filename);
+    goto escape;
+  }
+
+  /* load in PHU segment (ignore) */
+  if (!gfits_fread_header (f, &header)) {
+    if (VERBOSE) fprintf (stderr, "can't read image subset header\n");
+    fclose (f);
+    goto escape;
+  }
+  if (!gfits_fread_matrix (f, &matrix, &header)) {
+    if (VERBOSE) fprintf (stderr, "can't read image subset matrix\n");
+    gfits_free_header (&header);
+    fclose (f);
+    goto escape;
+  }
+
+  ALLOCATE (catalog, BrightCatalog, 1);
+  catalog->Naverage = 0;
+  catalog->Nmeasure = 0;
+
+  ftable.header = &theader;
+
+  // *** Measure Data *** 
+  { 
+    // load data for this header 
+    if (!gfits_load_header (f, &theader)) goto escape;
+
+    // read the fits table bytes
+    if (!gfits_fread_ftable_data (f, &ftable, FALSE)) goto escape;
+ 
+    // need to create and assign to flat-field correction
+    GET_COLUMN(dR,        "RA_OFF",   	float);
+    GET_COLUMN(dD,        "DEC_OFF",  	float);
+    GET_COLUMN(M,         "MAG_SYS",  	float);
+    GET_COLUMN(Mcal,      "MAG_CAL",  	float);
+    GET_COLUMN(dM,        "MAG_ERR",  	float);
+    GET_COLUMN(airmass,   "AIRMASS",  	float);
+    GET_COLUMN(Xccd,      "X_CCD",    	float);
+    GET_COLUMN(Yccd,      "Y_CCD",    	float);
+    GET_COLUMN(Xfix,      "X_FIX",    	float);
+    GET_COLUMN(Yfix,      "Y_FIX",    	float);
+    GET_COLUMN(dt,        "EXPTIME",  	float);
+    GET_COLUMN(t,         "TIME",     	int);
+    GET_COLUMN(averef,    "AVE_REF",  	int); // XXX signed vs unsigned?
+    GET_COLUMN(imageID,   "IMAGE_ID", 	int);
+    GET_COLUMN(dbFlags,   "DB_FLAGS", 	int);
+    GET_COLUMN(photFlags, "PHOT_FLAGS", int);
+    GET_COLUMN(catID,     "CAT_ID",     int);
+    GET_COLUMN(photcode,  "PHOTCODE",   short);
+    gfits_free_header (&theader);
+    gfits_free_table  (&ftable);
+
+    MeasureTiny *measure = NULL;
+    ALLOCATE (measure, MeasureTiny, Nrow);
+    for (i = 0; i < Nrow; i++) {
+      measure[i].dR        = dR[i];
+      measure[i].dD        = dD[i];
+      measure[i].M         = M[i];
+      measure[i].Mcal      = Mcal[i];
+      measure[i].dM        = dM[i];
+      measure[i].airmass   = airmass[i];
+      measure[i].Xccd      = Xccd[i];
+      measure[i].Yccd      = Yccd[i];
+      measure[i].Xfix      = Xfix[i];
+      measure[i].Yfix      = Yfix[i];
+      measure[i].dt        = dt[i];
+      measure[i].t         = t[i];
+      measure[i].averef    = averef[i];
+      measure[i].imageID   = imageID[i];
+      measure[i].dbFlags   = dbFlags[i];
+      measure[i].photFlags = photFlags[i];
+      measure[i].catID     = catID[i];
+      measure[i].photcode  = photcode[i];
+    }
+    // fprintf (stderr, "loaded data for %lld measures\n", (long long) Nrow);
+
+    free (dR      );
+    free (dD      );
+    free (M       );
+    free (Mcal    );
+    free (dM      );
+    free (airmass );
+    free (Xccd    );
+    free (Yccd    );
+    free (Xfix    );
+    free (Yfix    );
+    free (dt      );
+    free (t       );
+    free (averef  );
+    free (imageID );
+    free (dbFlags );
+    free (photFlags );
+    free (catID   );
+    free (photcode);
+
+    catalog->measure = measure;
+    catalog->Nmeasure = Nrow;
+  }
+
+  /*** load Average values ***/
+  { 
+
+    // load data for this header 
+    if (!gfits_load_header (f, &theader)) goto escape;
+
+    // read the fits table bytes
+    if (!gfits_fread_ftable_data (f, &ftable, FALSE)) goto escape;
+
+    GET_COLUMN(R,              "RA",          double);
+    GET_COLUMN(D,              "DEC",         double);
+    GET_COLUMN(dR,             "RA_ERR",      float);
+    GET_COLUMN(dD,             "DEC_ERR",     float);
+    GET_COLUMN(uR,             "U_RA",        float);
+    GET_COLUMN(uD,             "U_DEC",       float);
+    GET_COLUMN(duR,            "V_RA_ERR",    float);
+    GET_COLUMN(duD,            "V_DEC_ERR",   float);
+    GET_COLUMN(P,              "PAR",         float);
+    GET_COLUMN(dP,             "PAR_ERR",     float);
+    GET_COLUMN(ChiSqAve,       "CHISQ_POS",   float);
+    GET_COLUMN(ChiSqPM,        "CHISQ_PM",    float);
+    GET_COLUMN(ChiSqPar,       "CHISQ_PAP",   float);
+    GET_COLUMN(Tmean,          "MEAN_EPOCH",  int);
+    GET_COLUMN(Trange,         "TIME_RANGE",  int);
+    GET_COLUMN(stargal,        "STARGAL_SEP", float);
+    GET_COLUMN(Npos,           "NUMBER_POS",  short);
+    GET_COLUMN(Nmeasure,       "NMEASURE",    short);
+    GET_COLUMN(Nmissing,       "NMISSING",    short);
+    GET_COLUMN(Nextend,        "NEXTEND",     short);
+    GET_COLUMN(measureOffset,  "OFF_MEASURE", int);
+    GET_COLUMN(missingOffset,  "OFF_MISSING", int);
+    GET_COLUMN(refColor,   "REF_COLOR",  float);
+    GET_COLUMN(flags,          "FLAGS",       int);
+    GET_COLUMN(photFlagsUpper, "PHOTFLAGS_U", int);
+    GET_COLUMN(photFlagsLower, "PHOTFLAGS_L", int);
+    GET_COLUMN(objID,          "OBJ_ID",      int);
+    GET_COLUMN(catID,          "CAT_ID",      int);
+    GET_COLUMN(extID,          "EXT_ID",      int64_t);
+    gfits_free_header (&theader);
+    gfits_free_table  (&ftable);
+
+    Average *average = NULL;
+    ALLOCATE (average, Average, Nrow);
+    for (i = 0; i < Nrow; i++) {
+      average[i].R               = R[i]               ;
+      average[i].D               = D[i]               ;
+      average[i].dR              = dR[i]              ;
+      average[i].dD              = dD[i]              ;
+      average[i].uR              = uR[i]              ;
+      average[i].uD              = uD[i]              ;
+      average[i].duR             = duR[i]             ;
+      average[i].duD             = duD[i]             ;
+      average[i].P               = P[i]               ;
+      average[i].dP              = dP[i]              ;
+      average[i].ChiSqAve        = ChiSqAve[i]        ;
+      average[i].ChiSqPM         = ChiSqPM[i]         ;
+      average[i].ChiSqPar        = ChiSqPar[i]        ;
+      average[i].Tmean           = Tmean[i]           ;
+      average[i].Trange          = Trange[i]          ;
+      average[i].stargal         = stargal[i]         ;
+      average[i].Npos            = Npos[i]            ;
+      average[i].Nmeasure        = Nmeasure[i]        ;
+      average[i].Nmissing        = Nmissing[i]        ;
+      average[i].Nextend         = Nextend[i]         ;
+      average[i].measureOffset   = measureOffset[i]   ; 
+      average[i].missingOffset   = missingOffset[i]   ; 
+      average[i].refColor    = refColor[i]    ;  
+      average[i].flags           = flags[i]           ;
+      average[i].photFlagsUpper  = photFlagsUpper[i]  ;
+      average[i].photFlagsLower  = photFlagsLower[i]  ;
+      average[i].objID           = objID[i]           ;
+      average[i].catID           = catID[i]           ;
+      average[i].extID           = extID[i]           ;
+    }
+    fprintf (stderr, "loaded data for %lld averages\n", (long long) Nrow);
+
+    free (R);
+    free (D);
+    free (dR);
+    free (dD);
+    free (uR);
+    free (uD);
+    free (duR);
+    free (duD);
+    free (P);
+    free (dP);
+    free (ChiSqAve);
+    free (ChiSqPM);
+    free (ChiSqPar);
+    free (Tmean);
+    free (Trange);
+    free (stargal);
+    free (Npos);
+    free (Nmeasure);
+    free (Nmissing);
+    free (Nextend);
+    free (measureOffset);
+    free (missingOffset);
+    free (refColor);
+    free (flags);
+    free (photFlagsUpper);
+    free (photFlagsLower);
+    free (objID);
+    free (catID);
+    free (extID);
+
+    catalog->average = average;
+    catalog->Naverage = Nrow;
+  }
+
+  /*** load Secfilt values ***/
+  {
+
+    // load data for this header 
+    if (!gfits_load_header (f, &theader)) goto escape;
+
+    // read the fits table bytes
+    if (!gfits_fread_ftable_data (f, &ftable, FALSE)) goto escape;
+ 
+    // need to create and assign to flat-field correction
+    GET_COLUMN(M,     "MAG",      float);
+    GET_COLUMN(dM,    "MAG_ERR",  float);
+    GET_COLUMN(Mchisq,"MAG_CHI",  float);
+    GET_COLUMN(flags, "FLAGS",    int);
+    GET_COLUMN(Ncode, "NCODE",    short);
+    GET_COLUMN(Nused, "NUSED",    short);
+    GET_COLUMN(M_20,  "MAG_20",   short);
+    GET_COLUMN(M_80,  "MAG_80",   short);
+    gfits_free_header (&theader);
+    gfits_free_table  (&ftable);
+
+    SecFilt *secfilt = NULL;
+    ALLOCATE (secfilt, SecFilt, Nrow);
+    for (i = 0; i < Nrow; i++) {
+      secfilt[i].M     = M[i];         
+      secfilt[i].dM    = dM[i];
+      secfilt[i].Mchisq= Mchisq[i];
+      secfilt[i].flags = flags[i];
+      secfilt[i].Ncode = Ncode[i];
+      secfilt[i].Nused = Nused[i];
+      secfilt[i].M_20  = M_20[i];
+      secfilt[i].M_80  = M_80[i];
+    }
+    fprintf (stderr, "loaded data for %lld averages\n", (long long) Nrow);
+
+    free (M     );
+    free (dM    );
+    free (Mchisq);
+    free (flags );
+    free (Ncode );
+    free (Nused );
+    free (M_20  );
+    free (M_80  );
+    catalog->secfilt = secfilt;
+    // assert Nsecfilt * Naverage = Nrow?
+  }
+
+
+  gfits_free_header (&header);
+  gfits_free_matrix (&matrix);
+  fclose (f);
+
+  return catalog;
+
+escape:
+  gfits_free_header (&header);
+  gfits_free_matrix (&matrix);
+  gfits_free_header (&theader);
+  gfits_free_table  (&ftable);
+  if (catalog) free (catalog);
+
+  fclose (f);
+  return NULL;
+}
+
+// we are passed a BrightCatalog structure, write it to a FITS table (3 ext)
+int BrightCatalogSave(char *filename, BrightCatalog *catalog) {
+
+  int i;
+  Header header;
+  Header theader;
+  Matrix matrix;
+  FTable ftable;
+
+  gfits_init_header (&header);
+  header.extend = TRUE;
+  gfits_create_header (&header);
+  gfits_create_matrix (&header, &matrix);
+
+  FILE *f = fopen (filename, "w");
+  if (!f) {
+    fprintf (stderr, "ERROR: cannot open image subset file for output %s\n", filename);
+    return FALSE;
+  }
+ 
+  gfits_fwrite_header  (f, &header);
+  gfits_fwrite_matrix  (f, &matrix);
+  gfits_free_header (&header);
+  gfits_free_matrix (&matrix);
+
+  /*** MeasureTiny ***/
+  {
+    gfits_create_table_header (&theader, "BINTABLE", "MEASURE_TINY");
+
+    gfits_define_bintable_column (&theader, "E", "RA_OFF",   "ra offset",                  "arcsec", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "DEC_OFF",  "dec offset",                 "arcsec", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "MAG_SYS",  "magnitude (sys)",             NULL,    1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "MAG_CAL",  "magnitude (cal)",             NULL,    1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "MAG_ERR",  "magnitude (err)",             NULL,    1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "AIRMASS",  "airmass",                	    NULL,    1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "X_CCD",    "ccd x raw coord",            "pix",    1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "Y_CCD",    "ccd y raw coord",            "pix",    1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "X_FIX",    "ccd x fixed coord",          "pix",    1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "Y_FIX",    "ccd y fiex coord",       	   "pix",    1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "EXPTIME",  "-2.5 * log (exposure time)", "sec",    1.0, 0.0);
+    gfits_define_bintable_column (&theader, "J", "TIME",     "time of exp",                "sec",    1.0, 0.0);
+    gfits_define_bintable_column (&theader, "J", "AVE_REF",  "pointer to average table",    NULL,    1.0, 0.0);
+    gfits_define_bintable_column (&theader, "J", "IMAGE_ID", "image",                       NULL,    1.0, 0.0);
+    gfits_define_bintable_column (&theader, "J", "DB_FLAGS", "flags",                       NULL,    1.0, 0.0);
+    gfits_define_bintable_column (&theader, "J", "PHOT_FLAGS", "photflags",                 NULL,    1.0, 0.0);
+    gfits_define_bintable_column (&theader, "J", "CAT_ID",   "catalog",                     NULL,    1.0, 0.0);
+    gfits_define_bintable_column (&theader, "I", "PHOTCODE", "photcode",                    NULL,    1.0, 0.0);
+
+    // generate the output array that carries the data
+    gfits_create_table (&theader, &ftable);
+
+    // create intermediate storage arrays
+    float *dR        ; ALLOCATE (dR       ,  float, catalog->Nmeasure);
+    float *dD        ; ALLOCATE (dD       ,  float, catalog->Nmeasure);
+    float *M         ; ALLOCATE (M        ,  float, catalog->Nmeasure);
+    float *Mcal      ; ALLOCATE (Mcal     ,  float, catalog->Nmeasure);
+    float *dM        ; ALLOCATE (dM       ,  float, catalog->Nmeasure);
+    float *airmass   ; ALLOCATE (airmass  ,  float, catalog->Nmeasure);
+    float *Xccd      ; ALLOCATE (Xccd     ,  float, catalog->Nmeasure);
+    float *Yccd      ; ALLOCATE (Yccd     ,  float, catalog->Nmeasure);
+    float *Xfix      ; ALLOCATE (Xfix     ,  float, catalog->Nmeasure);
+    float *Yfix      ; ALLOCATE (Yfix     ,  float, catalog->Nmeasure);
+    float *dt        ; ALLOCATE (dt       ,  float, catalog->Nmeasure);
+    int   *t         ; ALLOCATE (t        ,  int  , catalog->Nmeasure);
+    int   *averef    ; ALLOCATE (averef   ,  int  , catalog->Nmeasure);
+    int   *imageID   ; ALLOCATE (imageID  ,  int  , catalog->Nmeasure);
+    int   *dbFlags   ; ALLOCATE (dbFlags  ,  int  , catalog->Nmeasure);
+    int   *photFlags ; ALLOCATE (photFlags,  int  , catalog->Nmeasure);
+    int   *catID     ; ALLOCATE (catID    ,  int  , catalog->Nmeasure);
+    short *photcode  ; ALLOCATE (photcode ,  short, catalog->Nmeasure);
+
+    // assign the storage arrays
+    MeasureTiny *measure = catalog->measure;
+    for (i = 0; i < catalog->Nmeasure; i++) {
+      dR[i]       = measure[i].dR       ;
+      dD[i]       = measure[i].dD       ;
+      M[i]  	  = measure[i].M        ;
+      Mcal[i]     = measure[i].Mcal     ;
+      dM[i]       = measure[i].dM       ;
+      airmass[i]  = measure[i].airmass  ;
+      Xccd[i]     = measure[i].Xccd     ;
+      Yccd[i]     = measure[i].Yccd     ;
+      Xfix[i]     = measure[i].Xfix     ;
+      Yfix[i]     = measure[i].Yfix     ;
+      dt[i]       = measure[i].dt       ;
+      t[i] 	  = measure[i].t        ;
+      averef[i]   = measure[i].averef   ;
+      catID[i]    = measure[i].catID    ;
+      imageID[i]  = measure[i].imageID  ;
+      dbFlags[i]  = measure[i].dbFlags  ;
+      photFlags[i]= measure[i].photFlags;
+      photcode[i] = measure[i].photcode ;
+    }
+
+    // add the columns to the output array
+    gfits_set_bintable_column (&theader, &ftable, "RA_OFF",   	dR,        catalog->Nmeasure);
+    gfits_set_bintable_column (&theader, &ftable, "DEC_OFF",  	dD,        catalog->Nmeasure);
+    gfits_set_bintable_column (&theader, &ftable, "MAG_SYS",  	M,         catalog->Nmeasure);
+    gfits_set_bintable_column (&theader, &ftable, "MAG_CAL",  	Mcal,      catalog->Nmeasure);
+    gfits_set_bintable_column (&theader, &ftable, "MAG_ERR",  	dM,        catalog->Nmeasure);
+    gfits_set_bintable_column (&theader, &ftable, "AIRMASS",  	airmass,   catalog->Nmeasure);
+    gfits_set_bintable_column (&theader, &ftable, "X_CCD",    	Xccd,      catalog->Nmeasure);
+    gfits_set_bintable_column (&theader, &ftable, "Y_CCD",    	Yccd,      catalog->Nmeasure);
+    gfits_set_bintable_column (&theader, &ftable, "X_FIX",    	Xfix,      catalog->Nmeasure);
+    gfits_set_bintable_column (&theader, &ftable, "Y_FIX",    	Yfix,      catalog->Nmeasure);
+    gfits_set_bintable_column (&theader, &ftable, "EXPTIME",  	dt,        catalog->Nmeasure);
+    gfits_set_bintable_column (&theader, &ftable, "TIME",     	t,         catalog->Nmeasure);
+    gfits_set_bintable_column (&theader, &ftable, "AVE_REF",  	averef,    catalog->Nmeasure);
+    gfits_set_bintable_column (&theader, &ftable, "IMAGE_ID", 	imageID,   catalog->Nmeasure);
+    gfits_set_bintable_column (&theader, &ftable, "DB_FLAGS", 	dbFlags,   catalog->Nmeasure);
+    gfits_set_bintable_column (&theader, &ftable, "PHOT_FLAGS", photFlags, catalog->Nmeasure);
+    gfits_set_bintable_column (&theader, &ftable, "CAT_ID",     catID,     catalog->Nmeasure);
+    gfits_set_bintable_column (&theader, &ftable, "PHOTCODE",   photcode,  catalog->Nmeasure);
+
+    free (dR      );
+    free (dD      );
+    free (M       );
+    free (Mcal    );
+    free (dM      );
+    free (airmass );
+    free (Xccd    );
+    free (Yccd    );
+    free (Xfix    );
+    free (Yfix    );
+    free (dt      );
+    free (t       );
+    free (averef  );
+    free (imageID );
+    free (dbFlags );
+    free (photFlags );
+    free (catID   );
+    free (photcode);
+
+    gfits_fwrite_Theader (f, &theader);
+    gfits_fwrite_table  (f, &ftable);
+    gfits_free_header (&theader);
+    gfits_free_table (&ftable);
+  }
+
+  /*** Average ***/
+  {
+    gfits_create_table_header (&theader, "BINTABLE", "AVERAGE");
+
+    gfits_define_bintable_column (&theader, "D", "RA",          "RA", 	         	  	         		  "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "D", "DEC",         "DEC", 	         	 	         		  "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "RA_ERR",      "RA error", 	         	         		  "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "DEC_ERR",     "DEC error", 	         	         		  "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "U_RA",        "RA*cos(D) proper-motion", 	         		  "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "U_DEC",       "DEC proper-motion", 	         	 		  "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "V_RA_ERR",    "RA*cos(D) p-m error", 	         	 		  "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "V_DEC_ERR",   "DEC p-m error", 	         	 		  "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "PAR",         "parallax", 	                         		  "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "PAR_ERR",     "parallax error", 	                 		  "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "CHISQ_POS",   "astrometry analysis chisq", 	         		  "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "CHISQ_PM",    "astrometry analysis chisq", 	         		  "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "CHISQ_PAP",   "astrometry analysis chisq", 	         		  "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "J", "MEAN_EPOCH",  "mean epoch (PM-PAR ref)", 	         		  "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "J", "TIME_RANGE",  "mean epoch (PM-PAR ref)", 	         		  "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "STARGAL_SEP", "star/galaxy separator",                		  "", 1.0, 0.0);   
+    gfits_define_bintable_column (&theader, "I", "NUMBER_POS",  "number of detections used for astrometry", 	          "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "I", "NMEASURE",    "number of psf measurements", 	                          "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "I", "NMISSING",    "number of missings", 	          	                  "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "I", "NEXTEND",     "number of extended measurements", 	                  "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "J", "OFF_MEASURE", "offset to first psf measurement", 	 	          "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "J", "OFF_MISSING", "offset to first missing obs", 	         	          "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "J", "OFF_EXTEND",  "offset to first extended measurement", 	          "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "J", "FLAGS",       "average object flags (star; ghost; etc)", 	          "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "J", "PHOTFLAGS_U", "upper bit of 2 bit summary of per-measure photflags", 	  "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "J", "PHOTFLAGS_L", "lower bit of 2 bit summary of per-measure photflags", 	  "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "J", "OBJ_ID",      "unique ID for object in table", 	                  "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "J", "CAT_ID",      "unique ID for table in which object was first realized", "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "K", "EXT_ID",      "external ID for object (eg PSPS objID)", 	          "", 1.0, 0.0);
+
+    // generate the output array that carries the data
+    gfits_create_table (&theader, &ftable);
+
+    // create intermediate storage arrays
+    double   *R             ; ALLOCATE (R             , double  , catalog->Naverage);
+    double   *D             ; ALLOCATE (D             , double  , catalog->Naverage);
+    float    *dR            ; ALLOCATE (dR            , float   , catalog->Naverage);
+    float    *dD            ; ALLOCATE (dD            , float   , catalog->Naverage);
+    float    *uR            ; ALLOCATE (uR            , float   , catalog->Naverage);
+    float    *uD            ; ALLOCATE (uD            , float   , catalog->Naverage);
+    float    *duR           ; ALLOCATE (duR           , float   , catalog->Naverage);
+    float    *duD           ; ALLOCATE (duD           , float   , catalog->Naverage);
+    float    *P             ; ALLOCATE (P             , float   , catalog->Naverage);
+    float    *dP            ; ALLOCATE (dP            , float   , catalog->Naverage);
+    float    *ChiSqAve      ; ALLOCATE (ChiSqAve      , float   , catalog->Naverage);
+    float    *ChiSqPM       ; ALLOCATE (ChiSqPM       , float   , catalog->Naverage);
+    float    *ChiSqPar      ; ALLOCATE (ChiSqPar      , float   , catalog->Naverage);
+    int      *Tmean         ; ALLOCATE (Tmean         , int     , catalog->Naverage);
+    int      *Trange        ; ALLOCATE (Trange        , int     , catalog->Naverage);
+    float    *stargal       ; ALLOCATE (stargal       , float   , catalog->Naverage);
+    short    *Npos          ; ALLOCATE (Npos          , short   , catalog->Naverage);
+    short    *Nmeasure      ; ALLOCATE (Nmeasure      , short   , catalog->Naverage);
+    short    *Nmissing      ; ALLOCATE (Nmissing      , short   , catalog->Naverage);
+    short    *Nextend       ; ALLOCATE (Nextend       , short   , catalog->Naverage);
+    int      *measureOffset ; ALLOCATE (measureOffset , int     , catalog->Naverage);
+    int      *missingOffset ; ALLOCATE (missingOffset , int     , catalog->Naverage);
+    int      *refColor  ; ALLOCATE (refColor  , float     , catalog->Naverage);
+    int      *flags         ; ALLOCATE (flags         , int     , catalog->Naverage);
+    int      *photFlagsUpper; ALLOCATE (photFlagsUpper, int     , catalog->Naverage);
+    int      *photFlagsLower; ALLOCATE (photFlagsLower, int     , catalog->Naverage);
+    int      *objID         ; ALLOCATE (objID         , int     , catalog->Naverage);
+    int      *catID         ; ALLOCATE (catID         , int     , catalog->Naverage);
+    uint64_t *extID         ; ALLOCATE (extID         , uint64_t, catalog->Naverage);
+
+    // assign the storage arrays
+    Average *average = catalog->average;
+    for (i = 0; i < catalog->Naverage; i++) {
+      R[i]               = average[i].R               ;
+      D[i]               = average[i].D               ;
+      dR[i]              = average[i].dR              ;
+      dD[i]              = average[i].dD              ;
+      uR[i]              = average[i].uR              ;
+      uD[i]              = average[i].uD              ;
+      duR[i]             = average[i].duR             ;
+      duD[i]             = average[i].duD             ;
+      P[i]               = average[i].P               ;
+      dP[i]              = average[i].dP              ;
+      ChiSqAve[i]        = average[i].ChiSqAve        ;
+      ChiSqPM[i]         = average[i].ChiSqPM         ;
+      ChiSqPar[i]        = average[i].ChiSqPar        ;
+      Tmean[i]           = average[i].Tmean           ;
+      Trange[i]          = average[i].Trange          ;
+      stargal[i]         = average[i].stargal         ;
+      Npos[i]            = average[i].Npos            ;
+      Nmeasure[i]        = average[i].Nmeasure        ;
+      Nmissing[i]        = average[i].Nmissing        ;
+      Nextend[i]         = average[i].Nextend         ;
+      measureOffset[i]   = average[i].measureOffset   ; 
+      missingOffset[i]   = average[i].missingOffset   ; 
+      refColor[i]    = average[i].refColor    ;  
+      flags[i]           = average[i].flags           ;
+      photFlagsUpper[i]  = average[i].photFlagsUpper  ;
+      photFlagsLower[i]  = average[i].photFlagsLower  ;
+      objID[i]           = average[i].objID           ;
+      catID[i]           = average[i].catID           ;
+      extID[i]           = average[i].extID           ;
+    }
+
+    // add the columns to the output array
+    gfits_set_bintable_column (&theader, &ftable, "RA",          R,               catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "DEC",         D,               catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "RA_ERR",      dR,              catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "DEC_ERR",     dD,              catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "U_RA",        uR,              catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "U_DEC",       uD,              catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "V_RA_ERR",    duR,             catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "V_DEC_ERR",   duD,             catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "PAR",         P,               catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "PAR_ERR",     dP,              catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "CHISQ_POS",   ChiSqAve,        catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "CHISQ_PM",    ChiSqPM,         catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "CHISQ_PAP",   ChiSqPar,        catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "MEAN_EPOCH",  Tmean,           catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "TIME_RANGE",  Trange,          catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "STARGAL_SEP", stargal,         catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "NUMBER_POS",  Npos,            catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "NMEASURE",    Nmeasure,        catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "NMISSING",    Nmissing,        catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "NEXTEND",     Nextend,         catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "OFF_MEASURE", measureOffset,   catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "OFF_MISSING", missingOffset,   catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "REF_COLOR",  refColor,    catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "FLAGS",       flags,           catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "PHOTFLAGS_U", photFlagsUpper,  catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "PHOTFLAGS_L", photFlagsLower,  catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "OBJ_ID",      objID,           catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "CAT_ID",      catID,           catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "EXT_ID",      extID,           catalog->Naverage);
+
+    free (R);
+    free (D);
+    free (dR);
+    free (dD);
+    free (uR);
+    free (uD);
+    free (duR);
+    free (duD);
+    free (P);
+    free (dP);
+    free (ChiSqAve);
+    free (ChiSqPM);
+    free (ChiSqPar);
+    free (Tmean);
+    free (Trange);
+    free (stargal);
+    free (Npos);
+    free (Nmeasure);
+    free (Nmissing);
+    free (Nextend);
+    free (measureOffset);
+    free (missingOffset);
+    free (refColor);
+    free (flags);
+    free (photFlagsUpper);
+    free (photFlagsLower);
+    free (objID);
+    free (catID);
+    free (extID);
+
+    gfits_fwrite_Theader (f, &theader);
+    gfits_fwrite_table  (f, &ftable);
+    gfits_free_header (&theader);
+    gfits_free_table (&ftable);
+  }
+
+  /*** SecFilt ***/
+  {
+    gfits_create_table_header (&theader, "BINTABLE", "SECFILT");
+
+    gfits_define_bintable_column (&theader, "E", "MAG",      "ra offset",                "arcsec", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "MAG_ERR",  "dec offset",               "arcsec", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "MAG_CHI",  "magnitude (sys)",           NULL,    1.0, 0.0);
+    gfits_define_bintable_column (&theader, "J", "FLAGS",    "magnitude (cal)",           NULL,    1.0, 0.0);
+    gfits_define_bintable_column (&theader, "I", "NCODE",    "magnitude (err)",           NULL,    1.0, 0.0);
+    gfits_define_bintable_column (&theader, "I", "NUSED",    "airmass",                   NULL,    1.0, 0.0);
+    gfits_define_bintable_column (&theader, "I", "MAG_20",   "ccd x coord",              "pix",    1.0, 0.0);
+    gfits_define_bintable_column (&theader, "I", "MAG_80",   "ccd y coord",              "pix",    1.0, 0.0);
+
+    // generate the output array that carries the data
+    gfits_create_table (&theader, &ftable);
+
+    // Nsecfilt is number of average filters, Nsec is total number of values
+    int Nsecfilt = GetPhotcodeNsecfilt();
+    int Nsec = Nsecfilt * catalog->Naverage;
+
+    // create intermediate storage arrays
+    float *M        ; ALLOCATE (M      ,  float, Nsec);
+    float *dM       ; ALLOCATE (dM     ,  float, Nsec);
+    float *Mchisq   ; ALLOCATE (Mchisq ,  float, Nsec);
+    int   *flags    ; ALLOCATE (flags  ,  int,   Nsec);
+    short *Ncode    ; ALLOCATE (Ncode  ,  short, Nsec);
+    short *Nused    ; ALLOCATE (Nused  ,  short, Nsec);
+    short *M_20     ; ALLOCATE (M_20   ,  short, Nsec);
+    short *M_80     ; ALLOCATE (M_80   ,  short, Nsec);
+
+    // assign the storage arrays
+    SecFilt *secfilt = catalog->secfilt;
+    for (i = 0; i < Nsec; i++) {
+      M     [i]       = secfilt[i].M      ;
+      dM    [i]       = secfilt[i].dM     ;
+      Mchisq[i]       = secfilt[i].Mchisq ;
+      flags [i]       = secfilt[i].flags  ;
+      Ncode [i]       = secfilt[i].Ncode  ;
+      Nused [i]       = secfilt[i].Nused  ;
+      M_20  [i]       = secfilt[i].M_20   ;
+      M_80  [i]       = secfilt[i].M_80   ;
+    }
+
+    // add the columns to the output array
+    gfits_set_bintable_column (&theader, &ftable, "MAG",      M     , Nsec);
+    gfits_set_bintable_column (&theader, &ftable, "MAG_ERR",  dM    , Nsec);
+    gfits_set_bintable_column (&theader, &ftable, "MAG_CHI",  Mchisq, Nsec);
+    gfits_set_bintable_column (&theader, &ftable, "FLAGS",    flags , Nsec);
+    gfits_set_bintable_column (&theader, &ftable, "NCODE",    Ncode , Nsec);
+    gfits_set_bintable_column (&theader, &ftable, "NUSED",    Nused , Nsec);
+    gfits_set_bintable_column (&theader, &ftable, "MAG_20",   M_20  , Nsec);
+    gfits_set_bintable_column (&theader, &ftable, "MAG_80",   M_80  , Nsec);
+
+    free (M      );
+    free (dM     );
+    free (Mchisq );
+    free (flags  );
+    free (Ncode  );
+    free (Nused  );
+    free (M_20   );
+    free (M_80   );
+
+    gfits_fwrite_Theader (f, &theader);
+    gfits_fwrite_table  (f, &ftable);
+    gfits_free_header (&theader);
+    gfits_free_table (&ftable);
+  }
+  return TRUE;
+}
+
+// merge a list of catalogs into a single BrightCatalog array set
+BrightCatalog *BrightCatalogMerge (Catalog *catalog, int Ncatalog) {
+
+  off_t i, j, k;
+
+  BrightCatalog *bcatalog = NULL;
+  ALLOCATE (bcatalog, BrightCatalog, 1);
+  
+  int Nmeas = 0;
+  int Naves = 0;
+  for (i = 0; i < Ncatalog; i++) {
+    Nmeas += catalog[i].Nmeasure;
+    Naves += catalog[i].Naverage;
+  }
+    
+  // XXX this prevents different catalogs from having different Nsecfilt values
+  int Nsecfilt = GetPhotcodeNsecfilt();
+
+  ALLOCATE (bcatalog[0].measure, MeasureTiny, Nmeas);
+  ALLOCATE (bcatalog[0].average, Average,     Naves);
+  ALLOCATE (bcatalog[0].secfilt, SecFilt,     Naves*Nsecfilt);
+  
+  int Nm = 0;
+  int Na = 0;
+  for (i = 0; i < Ncatalog; i++) {
+    if (!catalog[i].Naverage) continue;
+    for (j = 0; j < catalog[i].Naverage; j++) {
+      bcatalog[0].average[Na] = catalog[i].average[j];
+      for (k = 0; k < Nsecfilt; k++) {
+	bcatalog[0].secfilt[Nsecfilt*Na + k] = catalog[i].secfilt[Nsecfilt*j + k];
+      }
+      Na++;
+      assert (Na <= Naves);
+    }
+    for (j = 0; j < catalog[i].Nmeasure; j++) {
+      bcatalog[0].measure[Nm] = catalog[i].measureT[j];
+      Nm++;
+      assert (Nm <= Nmeas);
+    }
+  }
+  bcatalog->Naverage = Na;
+  bcatalog->Nmeasure = Nm;
+  return bcatalog;
+}
+
+// distribute a bright catalog across separate catalogs
+CatalogSplitter *BrightCatalogSplitInit (int Nsecfilt) {
+
+  int i;
+
+  CatalogSplitter *catalogs = NULL;
+
+  ALLOCATE (catalogs, CatalogSplitter, 1);
+
+  // as we see new BrightCatalogs, we will update maxID and extend this array
+  catalogs->maxID = 0;
+  ALLOCATE (catalogs->index, int, catalogs->maxID + 1);
+  for (i = 0; i <= catalogs->maxID; i++) catalogs->index[i] = -1;
+
+  catalogs->Nsecfilt = Nsecfilt;
+
+  catalogs->Ncatalog =  0;
+  catalogs->NCATALOG = 16;
+  catalogs->catalog = NULL;
+  ALLOCATE (catalogs->catalog, Catalog, catalogs->NCATALOG);
+
+  ALLOCATE (catalogs->catIDs,   int,   catalogs->NCATALOG);
+  ALLOCATE (catalogs->NAVERAGE, off_t, catalogs->NCATALOG);
+  ALLOCATE (catalogs->NMEASURE, off_t, catalogs->NCATALOG);
+
+  for (i = 0; i < catalogs->NCATALOG; i++) {
+    dvo_catalog_init (&catalogs->catalog[i], TRUE);
+    catalogs->catIDs[i] = 0;
+    catalogs->NAVERAGE[i] = 100;
+    catalogs->NMEASURE[i] = 100;
+    catalogs->catalog[i].Naverage = 0;
+    catalogs->catalog[i].Nmeasure = 0;
+    ALLOCATE (catalogs->catalog[i].average,  Average,     catalogs->NAVERAGE[i]);
+    ALLOCATE (catalogs->catalog[i].measureT, MeasureTiny, catalogs->NMEASURE[i]);
+    ALLOCATE (catalogs->catalog[i].secfilt,  SecFilt,     catalogs->NAVERAGE[i]*Nsecfilt);
+  }
+  return catalogs;
+}
+
+// distribute a bright catalog across separate catalogs
+int BrightCatalogSplitFree (CatalogSplitter *catalogs) {
+
+  free (catalogs->catIDs);
+  free (catalogs->NAVERAGE);
+  free (catalogs->NMEASURE);
+  free (catalogs->index);
+  free (catalogs);
+  return TRUE;
+}
+
+// distribute a bright catalog across separate catalogs
+int BrightCatalogSplit (CatalogSplitter *catalogs, BrightCatalog *bcatalog) {
+
+  int i;
+
+  int Nsecfilt = catalogs->Nsecfilt;
+
+  // find the max value of catID in this BrightCatalog
+  int catIDmax = 0;
+  for (i = 0; i < bcatalog->Naverage; i++) {
+    catIDmax = MAX(catIDmax, bcatalog->average[i].catID);
+  }
+  // XXX validate the measure ID range here
+    
+  int maxIDold = catalogs->maxID;
+  catalogs->maxID = MAX (maxIDold, catIDmax);
+    
+  // extend the index array and init
+  REALLOCATE (catalogs->index, int, catalogs->maxID + 1);
+  for (i = maxIDold + 1; i <= catalogs->maxID; i++) catalogs->index[i] = -1;
+
+  // identify the new catID values
+  for (i = 0; i < bcatalog->Naverage; i++) {
+    int catID = bcatalog->average[i].catID;
+    assert (catID > 0);
+    assert (catID < catalogs->maxID + 1);
+    int idx = catalogs->index[catID];
+    if (idx != -1) continue; // already have seen this one
+
+    // a new catID value
+    int Ncat = catalogs->Ncatalog; // the next available slot
+    catalogs->catIDs[Ncat] = catID;
+    assert (Ncat >= 0);
+    assert (Ncat < catalogs->NCATALOG);
+
+    catalogs->catalog[Ncat].Nsecfilt = Nsecfilt;
+    catalogs->catalog[Ncat].catID = catID;
+
+    catalogs->index[catID] = Ncat;
+    assert (catID > 0);
+    assert (catID < catalogs->maxID + 1);
+
+    catalogs->Ncatalog ++;
+
+    if (catalogs->Ncatalog >= catalogs->NCATALOG) {
+      catalogs->NCATALOG += 16;
+      // fprintf (stderr, "realloc catalogs->catalog: old: %llx  ", (long long) catalogs->catalog);
+      REALLOCATE (catalogs->catalog, Catalog, catalogs->NCATALOG);
+      // fprintf (stderr, "new: %llx  -  %llx\n", (long long) catalogs->catalog, (long long) (catalogs->catalog + sizeof(Catalog)*catalogs->NCATALOG));
+
+      // fprintf (stderr, "realloc catalogs->NAVERAGE: old: %llx  ", (long long) catalogs->NAVERAGE);
+      REALLOCATE (catalogs->NAVERAGE, off_t,  catalogs->NCATALOG);
+      // fprintf (stderr, "new: %llx  -  %llx\n", (long long) catalogs->NAVERAGE, (long long) (catalogs->NAVERAGE + sizeof(off_t)*catalogs->NCATALOG));
+
+      // fprintf (stderr, "realloc catalogs->NMEASURE: old: %llx  ", (long long) catalogs->NMEASURE);
+      REALLOCATE (catalogs->NMEASURE, off_t,  catalogs->NCATALOG);
+      // fprintf (stderr, "new: %llx  -  %llx\n", (long long) catalogs->NMEASURE, (long long) (catalogs->NMEASURE + sizeof(off_t)*catalogs->NCATALOG));
+
+      REALLOCATE (catalogs->catIDs,   int,   catalogs->NCATALOG);
+
+      int j;
+      for (j = catalogs->NCATALOG - 16; j < catalogs->NCATALOG; j++) {
+	dvo_catalog_init (&catalogs->catalog[j], TRUE);
+	catalogs->catIDs[j] = 0;
+	catalogs->NAVERAGE[j] = 100;
+	catalogs->NMEASURE[j] = 100;
+	catalogs->catalog[j].Naverage = 0;
+	catalogs->catalog[j].Nmeasure = 0;
+	ALLOCATE (catalogs->catalog[j].average,  Average,     catalogs->NAVERAGE[j]);
+	ALLOCATE (catalogs->catalog[j].measureT, MeasureTiny, catalogs->NMEASURE[j]);
+	ALLOCATE (catalogs->catalog[j].secfilt,  SecFilt,     catalogs->NAVERAGE[j]*Nsecfilt);
+      }
+    }
+  }
+
+  // each bcatalog (from each host) has a different set of catID ranges
+  // they also (probably) have contiguous ranges.  But, it is a bit tricky to be sure I
+  // can use that info, so perhaps ignore it
+
+  // assign the averages to the corresponding catalog
+  for (i = 0; i < bcatalog->Naverage; i++) {
+    int ID = bcatalog->average[i].catID;
+    int Nc = catalogs->index[ID];
+    assert (Nc > -1);
+    assert (Nc < catalogs->NCATALOG);
+
+    int Na = catalogs->catalog[Nc].Naverage;
+    catalogs->catalog[Nc].average[Na] = bcatalog->average[i];
+
+    // secfilt entries are grouped in blocks for each average
+    int k;
+    for (k = 0; k < Nsecfilt; k++) {
+      catalogs->catalog[Nc].secfilt[Na*Nsecfilt + k] = bcatalog->secfilt[i*Nsecfilt + k];
+    }      
+
+    catalogs->catalog[Nc].Naverage ++;
+    if (catalogs->catalog[Nc].Naverage >= catalogs->NAVERAGE[Nc]) {
+      catalogs->NAVERAGE[Nc] += 100;
+      REALLOCATE (catalogs->catalog[Nc].average,  Average, catalogs->NAVERAGE[Nc]);
+      REALLOCATE (catalogs->catalog[Nc].secfilt,  SecFilt, catalogs->NAVERAGE[Nc]*Nsecfilt);
+    }	       
+  }
+
+  // assign the measures to the corresponding catalog
+  // XXX what about averef and related links?  Do I need them?
+  for (i = 0; i < bcatalog->Nmeasure; i++) {
+    int ID = bcatalog->measure[i].catID;
+    int Nc = catalogs->index[ID];
+    assert (Nc > -1);
+    assert (Nc < catalogs->NCATALOG);
+    int Na = catalogs->catalog[Nc].Nmeasure;
+    catalogs->catalog[Nc].measureT[Na] = bcatalog->measure[i];
+    catalogs->catalog[Nc].Nmeasure ++;
+    if (catalogs->catalog[Nc].Nmeasure >= catalogs->NMEASURE[Nc]) {
+      catalogs->NMEASURE[Nc] += 100;
+      REALLOCATE (catalogs->catalog[Nc].measureT, MeasureTiny, catalogs->NMEASURE[Nc]);
+    }	       
+  }
+
+  return TRUE;
+}
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/ConfigInit.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/ConfigInit.c	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/ConfigInit.c	(revision 37403)
@@ -0,0 +1,72 @@
+# include "checkastro.h"
+
+void ConfigInit (int *argc, char **argv) {
+
+  char  *config, *file;
+  char CatdirPhotcodeFile[256];
+  struct stat filestat;
+  int status;
+
+  /*** load configuration info ***/
+  file = SelectConfigFile (argc, argv, "ptolemy");
+  config = LoadConfigFile (file);
+  if (config == (char *) NULL) {
+    fprintf (stderr, "ERROR: can't find configuration file %s\n", file);
+    if (file != (char *) NULL) free (file);
+    exit (0);
+  }
+  if (VERBOSE) fprintf (stderr, "loaded config file: %s\n", file);
+
+  // set defaults for all of these if they are not used by parallel / remote clients
+  if (!ScanConfig (config, "RELASTRO_SIGMA_LIM",         "%lf", 0, &SIGMA_LIM))       SIGMA_LIM = 0.01; 
+  if (!ScanConfig (config, "RELASTRO_SRC_MEAS_TOOFEW",   "%d",  0, &SRC_MEAS_TOOFEW)) SRC_MEAS_TOOFEW = 3;
+
+  // force CATDIR to be absolute (so parallel mode will work)
+  GetConfig (config, "CATDIR",                 "%s",  0, CATDIR);
+  char *tmpcatdir = abspath (CATDIR, DVO_MAX_PATH);
+  strcpy (CATDIR, tmpcatdir);
+  free (tmpcatdir);
+
+  // GetConfig (config, "GSCFILE",                "%s",  0, GSCFILE);
+  ScanConfig(config, "CATMODE",                "%s",  0, CATMODE);
+  ScanConfig(config, "CATFORMAT",              "%s",  0, CATFORMAT);
+
+  sprintf (ImageCat, "%s/Images.dat", CATDIR);
+
+  if (!ScanConfig (config, "SKY_DEPTH",         "%d",  0, &SKY_DEPTH)) SKY_DEPTH = 2;
+  if (!ScanConfig (config, "SKY_TABLE",         "%s",  0, SKY_TABLE)) SKY_TABLE[0] = 0;
+
+  if (*CATMODE == 0) strcpy (CATMODE, "RAW");
+  if (*CATFORMAT == 0) strcpy (CATFORMAT, "ELIXIR");
+
+  // check for existence of CATDIR
+  status = stat (CATDIR, &filestat);
+  if (status == -1) {
+    fprintf (stderr, "directory %s does not exist, giving up\n", CATDIR);
+    exit (1);
+  }
+
+  /* update master photcode table if not defined */
+  sprintf (CatdirPhotcodeFile, "%s/Photcodes.dat", CATDIR);
+  if (!LoadPhotcodes (CatdirPhotcodeFile, NULL, FALSE)) {
+    fprintf (stderr, "error loading photcode table %s\n", CatdirPhotcodeFile);
+    exit (1);
+  }
+  SetZeroPoint (25.0);
+
+  free (config);
+  free (file);
+
+}
+
+void GetConfig (char *config, char *field, char *format, int N, void *ptr) {
+
+  char *status;
+
+  status = ScanConfig (config, field, format, N, ptr);
+  if (status == NULL) {
+    fprintf (stderr, "error in config, cannot find %s\n", field);
+    exit (1);
+  }
+  return;
+}
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/ImageOps.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/ImageOps.c	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/ImageOps.c	(revision 37403)
@@ -0,0 +1,253 @@
+# include "checkastro.h"
+
+// we have an array of images: image[ImageIndex] (ImageIndex : 0 < Nimage)
+static Image        *image;   // list of available images
+static off_t        Nimage;   // number of available images
+
+// if we read only a subset of the rows from the Image FITS, LineNumber tells us to which row
+// each image belongs
+static off_t       *LineNumber; // match of subset to full image table
+
+static off_t        *N_onImage;   // number of measurements on image
+static off_t        *N_ONIMAGE;   // allocated number of measurements on image   
+static off_t        *Nref_onImage;   // number of reference measurements on image
+
+static IDX_T       **MeasureToImage;     // link from catalog,measure to image
+static IDX_T       **ImageToCatalog;   // catalog which supplied measurement on image
+static IDX_T       **ImageToMeasure;   // measure reference for measurement on image
+
+// to search by image ID, we sort (imageIDs, imageIdx) by imageIDs for an index
+static off_t        *imageIDs; // list of all image IDs
+static off_t        *imageIdx; // list of index for image IDs 
+
+// generate the image ID index (for imageID -> image[i] lookups)
+void initImages (Image *input, off_t *line_number, off_t N) {
+
+  off_t i;
+
+  image = input;
+  LineNumber = line_number;
+  Nimage = N;
+
+  ALLOCATE (imageIDs, off_t, Nimage);
+  ALLOCATE (imageIdx, off_t, Nimage);
+
+  for (i = 0; i < Nimage; i++) {
+    imageIdx[i] = i;
+    imageIDs[i] = image[i].imageID;
+  }
+  llsortpair (imageIDs, imageIdx, Nimage);
+}
+
+off_t getImageByID (off_t ID) {
+
+  // we have a pair of vectors (imageIDs, imageIdx) sorted by imageIDs
+  // use bisection to find the specified image ID
+
+  off_t Nlo, Nhi, N;
+
+  Nlo = 0; Nhi = Nimage;
+  while (Nhi - Nlo > 10) {
+    N = 0.5*(Nlo + Nhi);
+    if (imageIDs[N] < ID) {
+      Nlo = MAX(N, 0);
+    } else {
+      Nhi = MIN(N + 1, Nimage);
+    }
+  }
+
+  for (N = Nlo; N < Nhi; N++) {
+    if (imageIDs[N] == ID)
+      return (imageIdx[N]);
+  }
+
+  return (-1);
+}
+
+// these are really image & catalog indexes
+void initImageBins (Catalog *catalog, int Ncatalog) {
+
+  off_t i, j;
+
+  ALLOCATE (MeasureToImage, IDX_T *, Ncatalog);
+  for (i = 0; i < Ncatalog; i++) {
+    ALLOCATE (MeasureToImage[i], IDX_T, MAX (catalog[i].Nmeasure, 1));
+    for (j = 0; j < catalog[i].Nmeasure; j++) MeasureToImage[i][j] = -1;
+  }
+
+  ALLOCATE (N_onImage,      off_t,   Nimage);
+  ALLOCATE (N_ONIMAGE,      off_t,   Nimage);
+  ALLOCATE (Nref_onImage,   off_t,   Nimage);
+  ALLOCATE (ImageToCatalog, IDX_T *, Nimage);
+  ALLOCATE (ImageToMeasure, IDX_T *, Nimage);
+
+  for (i = 0; i < Nimage; i++) {
+    N_onImage[i] =   0;
+    N_ONIMAGE[i] =  30;
+    Nref_onImage[i]   = 0;
+    ImageToCatalog[i] = NULL;  // we allocate these iff they are needed in matchImage
+    ImageToMeasure[i] = NULL;  // we allocate these iff they are needed in matchImage
+  }
+}
+
+void freeImageBins (int Ncatalog) {
+
+  off_t i;
+
+  for (i = 0; i < Ncatalog; i++) {
+    free (MeasureToImage[i]);
+  }
+  free (MeasureToImage);
+  for (i = 0; i < Nimage; i++) {
+    if (ImageToCatalog[i]) { free (ImageToCatalog[i]); }
+    if (ImageToMeasure[i]) { free (ImageToMeasure[i]); }
+  }
+  free (ImageToCatalog);
+  free (ImageToMeasure);
+  free (N_onImage);
+  free (N_ONIMAGE);
+}
+
+/* match measurements to images */
+void findImages (Catalog *catalog, int Ncatalog) {
+
+  off_t i, j;
+  char *name;
+
+  for (i = 0; i < Ncatalog; i++) {
+    for (j = 0; j < catalog[i].Nmeasure; j++) {
+      if (NphotcodesSkip > 0) {
+	int k;
+	int found = FALSE;
+	for (k = 0; (k < NphotcodesSkip) && !found; k++) {
+	  if (photcodesSkip[k][0].code == catalog[i].measureT[j].photcode) found = TRUE;
+	  if (photcodesSkip[k][0].code == GetPhotcodeEquivCodebyCode(catalog[i].measureT[j].photcode)) found = TRUE;
+	}
+	if (found) continue;
+      }  
+      matchImage (catalog, j, i);
+    }
+  }
+
+  BuildChipMatch (image, Nimage);
+
+  char output[128];
+  snprintf (output, 128, "checkastrom.%+3.0f.%+3.0f.%03.0f.%03.0f.dat", UserPatch.Rmin, UserPatch.Rmax, UserPatch.Dmin, UserPatch.Dmax);
+  FILE *f = fopen (output, "w");
+  if (!f) {
+    fprintf (stderr, "problem opening %s for output\n", output);
+  }
+
+  // watch for chips with few stars
+  int Nfew = 0;
+  int Nbad = 0;
+  for (i = 0; i < Nimage; i++) {
+    // ignore the PHU entries
+    if (!strcmp(&image[i].coords.ctype[4], "-DIS")) continue;
+
+    name = GetPhotcodeNamebyCode (image[i].photcode);
+
+    off_t myMosaic = FindMosaicForImage (image, Nimage, i);
+
+    /* only check exposure center */
+    double Rexp = NAN, Dexp = NAN, Rccd = NAN, Dccd = NAN;
+
+    if (myMosaic) {
+      myMosaic --;
+      XY_to_RD (&Rccd, &Dccd, 0.5*image[i].NX, 0.5*image[i].NY, &image[i].coords);
+      XY_to_RD (&Rexp, &Dexp, 0.0, 0.0, &image[myMosaic].coords);
+    }
+
+    char *date = ohana_sec_to_date(image[i].tzero);
+    FILE *outfile = f ? f : stderr;
+    fprintf (outfile, "%d %s : %10.6f %10.6f : %10.6f %10.6f "OFF_T_FMT" "OFF_T_FMT" %d %s %s\n",  
+	     image[i].imageID, image[i].name, Rccd, Dccd, Rexp, Dexp, N_onImage[i], Nref_onImage[i], image[i].nstar,
+	     date, name);
+    free (date);
+
+    if (N_onImage[i] < 20) {
+      Nfew ++;
+    } 
+    if (N_onImage[i] < 15) {
+      Nbad ++;
+    } 
+  }
+  if (f) { fclose (f); }
+  fprintf (stderr, OFF_T_FMT" total images, %d with < 20 measurements, %d with < 15\n", Nimage, Nfew, Nbad);
+}
+
+// this is the imageID-based match
+void matchImage (Catalog *catalog, off_t meas, int cat) {
+
+  off_t idx, ID;
+  MeasureTiny *measure;
+
+  measure = &catalog[cat].measureT[meas];
+  unsigned int averef = measure->averef;
+  Average *average = &catalog[cat].average[averef];
+  assert (meas >= average->measureOffset);
+  assert (meas <  average->measureOffset + average->Nmeasure);
+
+  ID = measure[0].imageID;
+
+  if (catalog[cat].measure) {
+    Measure *measureBig = &catalog[cat].measure[meas];
+    int TESTPT = FALSE;
+    TESTPT |= CAT_ID_SRC && OBJ_ID_SRC && (measureBig->imageID == CAT_ID_SRC) && (measureBig->detID == OBJ_ID_SRC);
+    TESTPT |= CAT_ID_DST && OBJ_ID_DST && (measureBig->imageID == CAT_ID_DST) && (measureBig->detID == OBJ_ID_DST);
+    if (TESTPT) {
+      fprintf (stderr, "got test det\n");
+    }
+  }
+
+  idx = getImageByID (ID);
+  if (idx == -1) {
+    if (VERBOSE2) fprintf (stderr, "can't match detection to image?\n");
+    return;
+  }
+
+  // index for (catalog, measure) -> image
+  MeasureToImage[cat][meas] = idx;
+
+  // if we need to allocate an image index table, do so here
+  if (!ImageToCatalog[idx]) {
+      ALLOCATE (ImageToCatalog[idx], IDX_T, N_ONIMAGE[idx]);
+  }
+  if (!ImageToMeasure[idx]) {
+      ALLOCATE (ImageToMeasure[idx], IDX_T, N_ONIMAGE[idx]);
+  }
+
+  // index for image, Nentry -> catalog
+  ImageToCatalog[idx][N_onImage[idx]] = cat;
+
+  // index for image, Nentry -> measure
+  ImageToMeasure[idx][N_onImage[idx]] = meas;
+
+  // in bcatalog, we set this flag if the object includes a reference photcode
+  if (average->flags & 0x10) {
+    Nref_onImage[idx] ++;
+  }
+
+  // count the number of measurements on this image:
+  N_onImage[idx] ++;
+
+  if (N_onImage[idx] == N_ONIMAGE[idx]) {
+    N_ONIMAGE[idx] += 30;
+    REALLOCATE (ImageToCatalog[idx], IDX_T, N_ONIMAGE[idx]);
+    REALLOCATE (ImageToMeasure[idx], IDX_T, N_ONIMAGE[idx]);
+  }
+
+  return;
+}
+
+void dump_measures (Average *average, Measure *measure) {
+
+  off_t j, off;
+
+  for (j = 0; j < average[0].Nmeasure; j++) {
+    off = average[0].measureOffset + j;
+    fprintf (stderr, "dR, dD, mag, dMag: %f, %f, %f, %f\n", measure[off].dR, measure[off].dD, measure[off].M, measure[off].dM);
+  }
+  return;
+}
+
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/MeasFilterTest.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/MeasFilterTest.c	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/MeasFilterTest.c	(revision 37403)
@@ -0,0 +1,133 @@
+# include "checkastro.h"
+
+/** Determine whether a measurement should be included in the analysis, based on supplied filter criteria */ 
+// we only optionally apply the sigma limit: for object averages, this should not be used (should it?)
+int MeasFilterTestTiny(MeasureTiny *measure, int applySigmaLim) {
+  int found, k;
+  long mask;
+  PhotCode *code;
+  float mag;
+
+  if (!finite(measure[0].dR) || !finite(measure[0].dD)) return FALSE;
+  if (!finite(measure[0].M)) return FALSE; //XXX is this necessary for all checkastro tasks?
+  if (!finite(measure[0].dM)) return FALSE; //XXX is this necessary for all checkastro tasks?
+  
+  /* select measurements by photcode, or equiv photcode, if specified */
+  if (NphotcodesKeep > 0) {
+    found = FALSE;
+    for (k = 0; (k < NphotcodesKeep) && !found; k++) {
+      if (photcodesKeep[k][0].code == measure[0].photcode) found = TRUE;
+      if (photcodesKeep[k][0].code == GetPhotcodeEquivCodebyCode(measure[0].photcode)) found = TRUE;
+    }
+    if (!found) return FALSE;
+  }
+  
+  if (NphotcodesSkip > 0) {
+    found = FALSE;
+    for (k = 0; (k < NphotcodesSkip) && !found; k++) {
+      if (photcodesSkip[k][0].code == measure[0].photcode) found = TRUE;
+      if (photcodesSkip[k][0].code == GetPhotcodeEquivCodebyCode(measure[0].photcode)) found = TRUE;
+    }
+    if (found) return FALSE;
+  }  
+  
+  // if (MinBadQF > 0.0) {
+  //   if (measure[0].psfQF < MinBadQF) return FALSE;
+  // }
+
+  /* select measurements by time */
+  if (TimeSelect) {
+    if (measure[0].t < TSTART) return FALSE;
+    if (measure[0].t > TSTOP) return FALSE;
+  }
+  
+  /* select measurements by quality */
+  if (PhotFlagSelect) {
+    if (PhotFlagBad) {
+      mask = PhotFlagBad;
+    } else {
+      code = GetPhotcodebyCode (measure[0].photcode);
+      mask = code[0].astromBadMask;
+    }
+    if (mask & measure[0].photFlags) return FALSE;
+  }
+
+  /* select measurements by measurement error */
+  if (applySigmaLim && (SIGMA_LIM > 0) && (measure[0].dM > SIGMA_LIM)) {
+    return FALSE;
+  }
+  
+  /* select measurements by mag limit */
+  if (ImagSelect) {
+    mag = PhotInstTiny (measure);
+    if (mag < ImagMin || mag > ImagMax) return FALSE;
+  }
+  
+  return TRUE;
+}
+
+/** Determine whether a measurement should be included in the analysis, based on supplied filter criteria */ 
+// we only optionally apply the sigma limit: for object averages, this should not be used (should it?)
+int MeasFilterTest(Measure *measure, int applySigmaLim) {
+  int found, k;
+  long mask;
+  PhotCode *code;
+  float mag;
+
+  if (!finite(measure[0].dR) || !finite(measure[0].dD)) return FALSE;
+  if (!finite(measure[0].M)) return FALSE; //XXX is this necessary for all checkastro tasks?
+  if (!finite(measure[0].dM)) return FALSE; //XXX is this necessary for all checkastro tasks?
+  
+  /* select measurements by photcode, or equiv photcode, if specified */
+  if (NphotcodesKeep > 0) {
+    found = FALSE;
+    for (k = 0; (k < NphotcodesKeep) && !found; k++) {
+      if (photcodesKeep[k][0].code == measure[0].photcode) found = TRUE;
+      if (photcodesKeep[k][0].code == GetPhotcodeEquivCodebyCode(measure[0].photcode)) found = TRUE;
+    }
+    if (!found) return FALSE;
+  }
+  
+  if (NphotcodesSkip > 0) {
+    found = FALSE;
+    for (k = 0; (k < NphotcodesSkip) && !found; k++) {
+      if (photcodesSkip[k][0].code == measure[0].photcode) found = TRUE;
+      if (photcodesSkip[k][0].code == GetPhotcodeEquivCodebyCode(measure[0].photcode)) found = TRUE;
+    }
+    if (found) return FALSE;
+  }  
+  
+  if (MinBadQF > 0.0) {
+    if (measure[0].psfQF < MinBadQF) return FALSE;
+  }
+
+  /* select measurements by time */
+  if (TimeSelect) {
+    if (measure[0].t < TSTART) return FALSE;
+    if (measure[0].t > TSTOP) return FALSE;
+  }
+  
+  /* select measurements by quality */
+  if (PhotFlagSelect) {
+    if (PhotFlagBad) {
+      mask = PhotFlagBad;
+    } else {
+      code = GetPhotcodebyCode (measure[0].photcode);
+      mask = code[0].astromBadMask;
+    }
+    if (mask & measure[0].photFlags) return FALSE;
+  }
+
+  /* select measurements by measurement error */
+  if (applySigmaLim && (SIGMA_LIM > 0) && (measure[0].dM > SIGMA_LIM)) {
+    return FALSE;
+  }
+  
+  /* select measurements by mag limit */
+  if (ImagSelect) {
+    mag = PhotInst (measure);
+    if (mag < ImagMin || mag > ImagMax) return FALSE;
+  }
+  
+  return TRUE;
+}
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/SetSignals.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/SetSignals.c	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/SetSignals.c	(revision 37403)
@@ -0,0 +1,122 @@
+# include "checkastro.h"
+
+static int Protect = FALSE;
+static int Trapped = FALSE;
+
+void TrapSignal (int sig) {
+    fprintf (stderr, "trapped signal %d\n", sig);
+    if (sig == 11) {
+      fprintf (stderr, "seg fault\n");
+      exit (1);
+    }
+    if (Protect) {
+      Trapped = TRUE;
+      fprintf (stderr, "blocking until protected sections are clear\n");
+      return;
+    }
+    Shutdown ("halted by signal (trapped)");
+}    
+
+void SetProtect (int mode) {
+  Protect = mode;
+  if (Trapped && !Protect) Shutdown ("halted by signal (protect)");
+}
+
+int SetSignals () {
+
+  int i;
+
+  /* disable almost all signal interrupts */
+  for (i = 0; i < 36; i++) {
+    switch (i) {
+      /* can't redirect this signals */
+    case SIGKILL:    /* kill -9: cannot be caught or ignored */
+    case SIGSTOP:    /* SIGSTOP: cannot be caught or ignored */
+      /* ignore these signals */
+    case SIGCHLD:    /* child halted: ignore */
+    case SIGCONT:    /* continue - maintain this action */
+    case SIGTSTP:    /* stop signal sent from tty - why ignore? */
+    case SIGURG:     /* socket signal, ignore this */
+# ifdef SIGPWR
+    case SIGPWR:     /* power failure - why ignore this? (Sys V) */
+# endif
+# ifdef SIGWINCH
+    case SIGWINCH:   /* window resized (4.3BSD) */
+# endif
+      break;
+      
+    default:
+      signal (i, TrapSignal);
+    }
+  }
+  return (TRUE);
+}
+/*
+
+       Signal     Value     Action   Comment
+       -------------------------------------------------------------------------
+       SIGHUP        1        A      Hangup detected on controlling terminal
+                                     or death of controlling process
+       SIGINT        2        A      Interrupt from keyboard
+       SIGQUIT       3        A      Quit from keyboard
+       SIGILL        4        A      Illegal Instruction
+       SIGABRT       6        C      Abort signal from abort(3)
+       SIGFPE        8        C      Floating point exception
+       SIGKILL       9       AEF     Kill signal
+       SIGSEGV      11        C      Invalid memory reference
+       SIGPIPE      13        A      Broken pipe: write to pipe with no readers
+       SIGALRM      14        A      Timer signal from alarm(2)
+       SIGTERM      15        A      Termination signal
+       SIGUSR1   30,10,16     A      User-defined signal 1
+       SIGUSR2   31,12,17     A      User-defined signal 2
+       SIGCHLD   20,17,18     B      Child stopped or terminated
+       SIGCONT   19,18,25            Continue if stopped
+       SIGSTOP   17,19,23    DEF     Stop process
+       SIGTSTP   18,20,24     D      Stop typed at tty
+       SIGTTIN   21,21,26     D      tty input for background process
+       SIGTTOU   22,22,27     D      tty output for background process
+
+       Next various other signals.
+
+       Signal       Value     Action   Comment
+       ---------------------------------------------------------------------
+       SIGTRAP        5         CG     Trace/breakpoint trap
+       SIGIOT         6         CG     IOT trap. A synonym for SIGABRT
+       SIGEMT       7,-,7       G
+       SIGBUS      10,7,10      AG     Bus error
+       SIGSYS      12,-,12      G      Bad argument to routine (SVID)
+       SIGSTKFLT    -,16,-      AG     Stack fault on coprocessor
+       SIGURG      16,23,21     BG     Urgent condition on socket (4.2 BSD)
+       SIGIO       23,29,22     AG     I/O now possible (4.2 BSD)
+       SIGPOLL                  AG     A synonym for SIGIO (System V)
+       SIGCLD       -,-,18      G      A synonym for SIGCHLD
+       SIGXCPU     24,24,30     AG     CPU time limit exceeded (4.2 BSD)
+       SIGXFSZ     25,25,31     AG     File size limit exceeded (4.2 BSD)
+       SIGVTALRM   26,26,28     AG     Virtual alarm clock (4.2 BSD)
+       SIGPROF     27,27,29     AG     Profile alarm clock
+       SIGPWR      29,30,19     AG     Power failure (System V)
+       SIGINFO      29,-,-      G      A synonym for SIGPWR
+       SIGLOST      -,-,-       AG     File lock lost
+       SIGWINCH    28,28,20     BG     Window resize signal (4.3 BSD, Sun)
+       SIGUNUSED    -,31,-      AG     Unused signal
+       (Here - denotes that a signal is absent; there where three values are given, the first one is usually  valid  for  alpha  and
+       sparc,  the  middle  one  for i386 and ppc, the last one for mips. Signal 29 is SIGINFO / SIGPWR on an alpha but SIGLOST on a
+       sparc.)
+
+       The letters in the "Action" column have the following meanings:
+
+       A      Default action is to terminate the process.
+
+       B      Default action is to ignore the signal.
+
+       C      Default action is to dump core.
+
+       D      Default action is to stop the process.
+
+       E      Signal cannot be caught.
+
+       F      Signal cannot be ignored.
+
+       G      Not a POSIX.1 conformant signal.
+
+*/
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/Shutdown.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/Shutdown.c	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/Shutdown.c	(revision 37403)
@@ -0,0 +1,30 @@
+# include "checkastro.h"
+
+static FITS_DB *db;
+
+void set_db (FITS_DB *in) {
+  db = in;
+}
+
+/* clean up open / locked ImageCat before shutting down */
+int Shutdown (char *format, ...) {  
+  va_list argp;
+  char *formatplus;
+  
+  ALLOCATE (formatplus, char, strlen(format));
+  strcpy (formatplus, format);
+  strcat (formatplus, "\n");
+
+  va_start (argp, format);
+  vfprintf (stderr, formatplus, argp);
+  free (formatplus);
+  va_end (argp);
+
+  SetProtect (TRUE);
+  gfits_db_close (db);
+  fprintf (stderr, "ERROR: addstar halted\n");
+  exit (1);
+}
+
+
+/* XXX this is probably not needed anymore : just protect the write statements */
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/args.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/args.c	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/args.c	(revision 37403)
@@ -0,0 +1,433 @@
+# include "checkastro.h"
+void usage (void);
+void usage_client (void);
+void usage_merge_source (void);
+void usage_merge_source_id (char *name);
+
+int args (int argc, char **argv) {
+
+  int N;
+  double trange;
+
+  /* specify portion of the sky : allow default of all sky? */
+  UserPatch.Rmin = 0;
+  UserPatch.Rmax = 360;
+  UserPatch.Dmin = -90;
+  UserPatch.Dmax = +90;
+  if ((N = get_argument (argc, argv, "-region"))) {
+    remove_argument (N, &argc, argv);
+    UserPatch.Rmin = atof (argv[N]);
+    remove_argument (N, &argc, argv);
+    UserPatch.Rmax = atof (argv[N]);
+    remove_argument (N, &argc, argv);
+    UserPatch.Dmin = atof (argv[N]);
+    remove_argument (N, &argc, argv);
+    UserPatch.Dmax = atof (argv[N]);
+    remove_argument (N, &argc, argv);
+  } 
+  if ((N = get_argument (argc, argv, "-catalog"))) {
+    remove_argument (N, &argc, argv);
+    UserPatch.Rmin = atof (argv[N]);
+    UserPatch.Rmax = UserPatch.Rmin + 0.001;
+    remove_argument (N, &argc, argv);
+    UserPatch.Dmin = atof (argv[N]);
+    UserPatch.Dmax = UserPatch.Dmin + 0.001;
+    remove_argument (N, &argc, argv);
+  }
+
+  // XXX for the moment, make this selection manual.  it needs to be automatic 
+  // based on the state of the SkyTable
+  PARALLEL = FALSE;
+  if ((N = get_argument (argc, argv, "-parallel"))) {
+    PARALLEL = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+  // this is a test mode : rather than launching the remote jobs and waiting for completion,
+  // checkastro will simply list the remote command and wait for the user to signal completion
+  PARALLEL_MANUAL = FALSE;
+  if ((N = get_argument (argc, argv, "-parallel-manual"))) {
+    PARALLEL = TRUE; // -parallel-manual implies -parallel
+    PARALLEL_MANUAL = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+  // this is a test mode : rather than launching the checkastro_client jobs remotely, they are 
+  // run in serial via 'system'
+  PARALLEL_SERIAL = FALSE;
+  if ((N = get_argument (argc, argv, "-parallel-serial"))) {
+    if (PARALLEL_MANUAL) {
+      fprintf (stderr, "ERROR: cannot mix -parallel-manual and -parallel-serial\n");
+      exit (1);
+    }
+    PARALLEL = TRUE; // -parallel-serial implies -parallel
+    PARALLEL_SERIAL = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+
+  MaxDensityUse = FALSE;
+  if ((N = get_argument (argc, argv, "-max-density"))) {
+    remove_argument (N, &argc, argv);
+    MaxDensityValue = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+    MaxDensityUse = TRUE;
+  }
+
+  /* define time */
+  TimeSelect = FALSE;
+  if ((N = get_argument (argc, argv, "-time"))) {
+    remove_argument (N, &argc, argv);
+    if (!ohana_str_to_time (argv[N], &TSTART)) { 
+      fprintf (stderr, "ERROR: syntax error\n");
+      return (FALSE);
+    }
+    remove_argument (N, &argc, argv);
+    if (!ohana_str_to_dtime (argv[N], &trange)) { 
+      if (!ohana_str_to_time (argv[N], &TSTOP)) { 
+	fprintf (stderr, "ERROR: syntax error\n");
+	return (FALSE);
+      }
+    } else {
+      if (trange < 0) {
+	trange = fabs (trange);
+	TSTOP = TSTART;
+	TSTART -= trange;
+      } else {
+	TSTOP = TSTART + trange;
+      }
+    }
+    remove_argument (N, &argc, argv);
+    TimeSelect = TRUE;
+  }
+
+  PHOTCODE_RESET_LIST = NULL;
+  if ((N = get_argument (argc, argv, "-reset-to-photcode"))) {
+    remove_argument (N, &argc, argv);
+    PHOTCODE_RESET_LIST = strcreate(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  PHOTCODE_KEEP_LIST = NULL;
+  if ((N = get_argument (argc, argv, "+photcode"))) {
+    remove_argument (N, &argc, argv);
+    PHOTCODE_KEEP_LIST = strcreate(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  PHOTCODE_SKIP_LIST = strcreate("SCOS.103a.E,SCOS.4414.OG590,SCOS.4415.OG590,SCOS.IIIaF.OG590,SCOS.IIIaF.RG610,SCOS.IIIaF.RG630,SCOS.IIIaJ.GG385,SCOS.IIIaJ.GG395,SCOS.IVN.RG715,SCOS.IVN.RG9");
+  if ((N = get_argument (argc, argv, "-photcode"))) {
+    remove_argument (N, &argc, argv);
+    char *tmp1 = strcreate(argv[N]);
+
+    int Ntotal = strlen(tmp1) + strlen(PHOTCODE_SKIP_LIST) + 5;
+
+    char *tmp2 = NULL;
+    ALLOCATE (tmp2, char, Ntotal);
+    snprintf (tmp2, Ntotal, "%s,%s", PHOTCODE_SKIP_LIST, tmp1);
+
+    free (tmp1);
+    free (PHOTCODE_SKIP_LIST);
+
+    PHOTCODE_SKIP_LIST = tmp2;
+    remove_argument (N, &argc, argv);
+  }
+
+  VERBOSE = VERBOSE2 = FALSE;
+  if ((N = get_argument (argc, argv, "-v"))) {
+    VERBOSE = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+  if ((N = get_argument (argc, argv, "-vv"))) {
+    VERBOSE = VERBOSE2 = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+
+  /* XXX update this */
+  MIN_ERROR = 0.001;
+  if ((N = get_argument (argc, argv, "-minerror"))) {
+    remove_argument (N, &argc, argv);
+    MIN_ERROR = atof (argv[N]);
+    remove_argument (N, &argc, argv);
+    /* require MIN_ERROR > 0 */
+  }  
+
+  ImagSelect = FALSE;
+  if ((N = get_argument (argc, argv, "-instmag"))) {
+    remove_argument (N, &argc, argv);
+    ImagMin = atof (argv[N]);
+    remove_argument (N, &argc, argv);
+    ImagMax = atof (argv[N]);
+    remove_argument (N, &argc, argv);
+    ImagSelect = TRUE;
+  }
+  
+  // for now, make the default to ignore the photflags
+  // XXX make it true by default instead?
+  PhotFlagSelect = FALSE;
+  if ((N = get_argument (argc, argv, "+photflags"))) {
+    remove_argument (N, &argc, argv);
+    PhotFlagSelect = TRUE;
+  }
+
+  PhotFlagBad = 0;
+  if ((N = get_argument (argc, argv, "-photflagbad"))) {
+    remove_argument (N, &argc, argv);
+    PhotFlagBad = atoi (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  PhotFlagPoor = 0;
+  if ((N = get_argument (argc, argv, "-photflagpoor"))) {
+    remove_argument (N, &argc, argv);
+    PhotFlagPoor = atoi (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  MinBadQF = 0.0;
+  if ((N = get_argument (argc, argv, "-min-bad-psfqf"))) {
+    remove_argument (N, &argc, argv);
+    MinBadQF = atof (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  if (argc != 1) usage ();
+  return TRUE;
+}
+
+int args_client (int argc, char **argv) {
+
+  int N;
+  double trange;
+
+  /* possible operations */
+  // by definition, the client is not parallel 
+  PARALLEL = FALSE;
+  PARALLEL_MANUAL = FALSE;
+  PARALLEL_SERIAL = FALSE;
+
+  BCATALOG = NULL;
+
+  HOST_ID = 0;
+  if ((N = get_argument (argc, argv, "-hostID"))) {
+    remove_argument (N, &argc, argv);
+    HOST_ID = atoi (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+  if (!HOST_ID) usage_client();
+
+  HOSTDIR = NULL;
+  if ((N = get_argument (argc, argv, "-hostdir"))) {
+    remove_argument (N, &argc, argv);
+    HOSTDIR = strcreate (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+  if (!HOSTDIR) usage_client();
+
+  if ((N = get_argument (argc, argv, "-load-objects"))) {
+    remove_argument (N, &argc, argv);
+    BCATALOG = strcreate(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  /* specify portion of the sky : allow default of all sky? */
+  UserPatch.Rmin = 0;
+  UserPatch.Rmax = 360;
+  UserPatch.Dmin = -90;
+  UserPatch.Dmax = +90;
+  if ((N = get_argument (argc, argv, "-region"))) {
+    remove_argument (N, &argc, argv);
+    UserPatch.Rmin = atof (argv[N]);
+    remove_argument (N, &argc, argv);
+    UserPatch.Rmax = atof (argv[N]);
+    remove_argument (N, &argc, argv);
+    UserPatch.Dmin = atof (argv[N]);
+    remove_argument (N, &argc, argv);
+    UserPatch.Dmax = atof (argv[N]);
+    remove_argument (N, &argc, argv);
+  } 
+  if ((N = get_argument (argc, argv, "-catalog"))) {
+    remove_argument (N, &argc, argv);
+    UserPatch.Rmin = atof (argv[N]);
+    UserPatch.Rmax = UserPatch.Rmin + 0.001;
+    remove_argument (N, &argc, argv);
+    UserPatch.Dmin = atof (argv[N]);
+    UserPatch.Dmax = UserPatch.Dmin + 0.001;
+    remove_argument (N, &argc, argv);
+  }
+
+  MaxDensityUse = FALSE;
+  if ((N = get_argument (argc, argv, "-max-density"))) {
+    remove_argument (N, &argc, argv);
+    MaxDensityValue = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+    MaxDensityUse = TRUE;
+  }
+
+  /* define time */
+  TimeSelect = FALSE;
+  if ((N = get_argument (argc, argv, "-time"))) {
+    remove_argument (N, &argc, argv);
+    if (!ohana_str_to_time (argv[N], &TSTART)) { 
+      fprintf (stderr, "ERROR: syntax error\n");
+      return (FALSE);
+    }
+    remove_argument (N, &argc, argv);
+    if (!ohana_str_to_dtime (argv[N], &trange)) { 
+      if (!ohana_str_to_time (argv[N], &TSTOP)) { 
+	fprintf (stderr, "ERROR: syntax error\n");
+	return (FALSE);
+      }
+    } else {
+      if (trange < 0) {
+	trange = fabs (trange);
+	TSTOP = TSTART;
+	TSTART -= trange;
+      } else {
+	TSTOP = TSTART + trange;
+      }
+    }
+    remove_argument (N, &argc, argv);
+    TimeSelect = TRUE;
+  }
+
+  PHOTCODE_RESET_LIST = NULL;
+  if ((N = get_argument (argc, argv, "-reset-to-photcode"))) {
+    remove_argument (N, &argc, argv);
+    PHOTCODE_RESET_LIST = strcreate(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  PHOTCODE_KEEP_LIST = NULL;
+  if ((N = get_argument (argc, argv, "+photcode"))) {
+    remove_argument (N, &argc, argv);
+    PHOTCODE_KEEP_LIST = strcreate(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  PHOTCODE_SKIP_LIST = NULL;
+  if ((N = get_argument (argc, argv, "-photcode"))) {
+    remove_argument (N, &argc, argv);
+    PHOTCODE_SKIP_LIST = strcreate(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  VERBOSE = VERBOSE2 = FALSE;
+  if ((N = get_argument (argc, argv, "-v"))) {
+    VERBOSE = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+  if ((N = get_argument (argc, argv, "-vv"))) {
+    VERBOSE = VERBOSE2 = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+
+  ImagSelect = FALSE;
+  if ((N = get_argument (argc, argv, "-instmag"))) {
+    remove_argument (N, &argc, argv);
+    ImagMin = atof (argv[N]);
+    remove_argument (N, &argc, argv);
+    ImagMax = atof (argv[N]);
+    remove_argument (N, &argc, argv);
+    ImagSelect = TRUE;
+  }
+  
+  // for now, make the default to ignore the photflags
+  // XXX make it true by default instead?
+  PhotFlagSelect = FALSE;
+  if ((N = get_argument (argc, argv, "+photflags"))) {
+    remove_argument (N, &argc, argv);
+    PhotFlagSelect = TRUE;
+  }
+
+  PhotFlagBad = 0;
+  if ((N = get_argument (argc, argv, "-photflagbad"))) {
+    remove_argument (N, &argc, argv);
+    PhotFlagBad = atoi (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  PhotFlagPoor = 0;
+  if ((N = get_argument (argc, argv, "-photflagpoor"))) {
+    remove_argument (N, &argc, argv);
+    PhotFlagPoor = atoi (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  MinBadQF = 0.0;
+  if ((N = get_argument (argc, argv, "-min-bad-psfqf"))) {
+    remove_argument (N, &argc, argv);
+    MinBadQF = atof (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  if (argc != 1) usage_client ();
+  return TRUE;
+}
+
+void usage () {
+  fprintf (stderr, "ERROR: USAGE: checkastro [options]\n");
+  fprintf (stderr, " options: \n");
+  fprintf (stderr, "  -region RA RA DEC DEC\n");
+  fprintf (stderr, "  -catalog (ra) (dec)\n\n");
+  fprintf (stderr, "  -time (start)(stop)\n");
+  fprintf (stderr, "  +photcode (code)[,code,code...]\n");
+  fprintf (stderr, "  -photcode (code)[,code,code...]\n");
+  fprintf (stderr, "  -reset-to-photcode (code)[,code,code...]\n");
+  fprintf (stderr, "  -max-density (rho)\n");
+  fprintf (stderr, "  -minerror\n");
+  fprintf (stderr, "  -minerror\n");
+  fprintf (stderr, "  -instmag min max\n\n");
+  fprintf (stderr, "  +photflags\n");
+  fprintf (stderr, "  -photflagbad\n");
+  fprintf (stderr, "  -photflagpoor\n");
+  fprintf (stderr, "  -v\n");
+  fprintf (stderr, "  -vv\n");
+  fprintf (stderr, "  -parallel\n");
+  fprintf (stderr, "  -parallel-manual\n");
+  fprintf (stderr, "  -parallel-serial\n");
+  fprintf (stderr, "  \n");
+  exit (2);
+} 
+
+void usage_client () {
+  fprintf (stderr, "ERROR: USAGE: checkastro_client -load\n");
+  fprintf (stderr, "       OR:    checkastro_client -update-offsets\n");
+  fprintf (stderr, "       OR:    checkastro_client -update-objects\n");
+  fprintf (stderr, "       OR:    checkastro_client -high-speed\n\n");
+
+  fprintf (stderr, "  specify one of the following modes: \n");
+  fprintf (stderr, "  -load : load the bright source detections for analysis\n");
+  fprintf (stderr, "  -update-offsets : apply the updated image parameters\n");
+  fprintf (stderr, "  -update-objects : calculate average astrometric properties of objects\n");
+  fprintf (stderr, "  -high-speed (code[,code,code]) (code[,code,code]) (radius) (output catdir)\n");
+  fprintf (stderr, "    support for the special high-speed mode\n");
+
+  fprintf (stderr, " additional options: \n");
+  fprintf (stderr, "  -pm : calculate proper motions\n");
+  fprintf (stderr, "  -par : calculate parallaxes\n");
+  fprintf (stderr, "  -pmpar : calculate motions and parallaxes\n");
+  fprintf (stderr, "  -region Rmin Rmax Dmin Dmax");
+  fprintf (stderr, "  -catalog RA DEC");
+  fprintf (stderr, "  -time (start)(stop)\n");
+  fprintf (stderr, "  +photcode (code)[,code,code...]\n");
+  fprintf (stderr, "  -photcode (code)[,code,code...]\n");
+  fprintf (stderr, "  -statmode (mode)\n");
+  fprintf (stderr, "  -reset\n");
+  fprintf (stderr, "  -minerror\n");
+  fprintf (stderr, "  -instmag min max\n\n");
+  fprintf (stderr, "  +photflags\n");
+  fprintf (stderr, "  -photflagbad\n");
+  fprintf (stderr, "  -photflagpoor\n");
+  fprintf (stderr, "  -v\n");
+  fprintf (stderr, "  \n");
+  exit (2);
+} 
+
+void usage_merge_source_id (char *name) {
+
+  fprintf (stderr, "ERROR: invalid ID %s (remember to prefix 0x to hex IDs)\n", name);
+  exit (2);
+}
+
+void usage_merge_source () {
+  fprintf (stderr, "ERROR: USAGE: checkastro -merge-source (objID) (catID) into (objID) (catID)\n");
+  exit (2);
+}
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/bcatalog.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/bcatalog.c	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/bcatalog.c	(revision 37403)
@@ -0,0 +1,620 @@
+# include "checkastro.h"
+
+static int Nkeep1 = 0;
+static int Nkeep2 = 0;
+static int Nskip1 = 0;
+static int Nskip2 = 0;
+
+// test image: 2013/06/15,13:25:51, GPC1.r.XY50
+static int CHECK_TEST_IMAGE = TRUE;
+// static unsigned int Tref = 1378812312; 
+// static short Cref = 10001;
+
+static unsigned int Tref = 1379570672;
+static short Cref = 10341;
+
+int LimitDensityCatalog_ByNmeasureGrid (Catalog *subcatalog, Catalog *oldcatalog);
+
+int bcatalog (Catalog *subcatalog, Catalog *catalog) {
+
+  off_t i, j, offset;
+  off_t NAVERAGE, NMEASURE, Naverage, Nmeasure, Nm;
+  int Nsecfilt;
+
+  // XXX in the future, use catalog[0].Nsecfilt only?  allow catalogs to have variable Nsecfilt?
+  Nsecfilt = GetPhotcodeNsecfilt ();
+  assert (catalog[0].Nsecfilt == Nsecfilt);
+
+  /* we are moving only the subset of measurements from catalog[0] to subcatalog[0] */
+  memset(subcatalog, 0, sizeof(Catalog));
+  NAVERAGE = 50;
+  NMEASURE = 1000;
+  ALLOCATE (subcatalog[0].average,  Average,     NAVERAGE);
+  ALLOCATE (subcatalog[0].secfilt,  SecFilt,     NAVERAGE*Nsecfilt);
+  ALLOCATE (subcatalog[0].measureT, MeasureTiny, NMEASURE);
+  Nmeasure = Naverage = 0;
+
+  /* exclude stars not in range or with too few measurements */
+  for (i = 0; i < catalog[0].Naverage; i++) {
+    if (catalog[0].average[i].Nmeasure <= SRC_MEAS_TOOFEW) continue;
+    
+    /* start with all stars good */
+    subcatalog[0].average[Naverage] = catalog[0].average[i];
+    subcatalog[0].average[Naverage].measureOffset = Nmeasure;
+    for (j = 0; j < Nsecfilt; j++) {
+      subcatalog[0].secfilt[Nsecfilt*Naverage+j] = catalog[0].secfilt[Nsecfilt*i+j];
+    }
+
+    int foundRef = FALSE;
+
+    Nm = 0;
+    for (j = 0; j < catalog[0].average[i].Nmeasure; j++) {
+
+      offset = catalog[0].average[i].measureOffset + j;
+      
+      // filter objects based on user supplied criteria, including SIGMA_LIM
+      if (!MeasFilterTest(&catalog[0].measure[offset], TRUE)) {
+	catalog[0].measure[offset].dbFlags &= ~ID_MEAS_USED_CHIP;
+	if (CHECK_TEST_IMAGE && (abs(catalog[0].measure[offset].t - Tref) < 10) && (catalog[0].measure[offset].photcode == Cref)) {
+	  Nskip1 ++;
+	}
+	continue;
+      }
+      if (CHECK_TEST_IMAGE && (abs(catalog[0].measure[offset].t - Tref) < 10) && (catalog[0].measure[offset].photcode == Cref)) {
+	Nkeep1 ++;
+      }
+
+      // does this measurement match any of the reference photcodes?
+      if (!foundRef && NphotcodesReset) {
+	int m, found = FALSE;
+	for (m = 0; (m < NphotcodesReset) && !found; m++) {
+	  if (catalog[0].measure[offset].photcode == photcodesReset[m][0].code) {
+	    found = TRUE;
+	  }
+	}
+	if (found) {
+	  foundRef = TRUE;
+	}
+      }
+
+      // subcatalog[0].measure[Nmeasure] = catalog[0].measure[offset];
+      CopyMeasureToTiny (&subcatalog[0].measureT[Nmeasure], &catalog[0].measure[offset]);
+      subcatalog[0].measureT[Nmeasure].dbFlags &= ~ID_MEAS_SKIP_ASTROM;
+      subcatalog[0].measureT[Nmeasure].dbFlags &= ~ID_MEAS_NOCAL;
+      subcatalog[0].measureT[Nmeasure].averef   = Naverage;
+
+      Nmeasure ++;
+      Nm ++;
+      if (Nmeasure == NMEASURE) {
+        NMEASURE += 1000;
+        REALLOCATE (subcatalog[0].measureT, MeasureTiny, NMEASURE);
+      }
+    }
+    if (foundRef) {
+      subcatalog[0].average[Naverage].flags |= 0x10; 
+    }
+    subcatalog[0].average[Naverage].Nmeasure = Nm;
+    Naverage ++;
+    if (Naverage == NAVERAGE) {
+      NAVERAGE += 50;
+      REALLOCATE (subcatalog[0].average, Average, NAVERAGE);
+      REALLOCATE (subcatalog[0].secfilt, SecFilt, NAVERAGE*Nsecfilt);
+    }
+  }
+  REALLOCATE (subcatalog[0].average,  Average,     MAX (Naverage, 1));
+  REALLOCATE (subcatalog[0].measureT, MeasureTiny, MAX (Nmeasure, 1));
+  REALLOCATE (subcatalog[0].secfilt,  SecFilt,     MAX (Naverage, 1)*Nsecfilt);
+  subcatalog[0].Naverage = Naverage;
+  subcatalog[0].Nmeasure = Nmeasure;
+  subcatalog[0].Nsecfilt = catalog[0].Nsecfilt;
+  subcatalog[0].Nsecfilt = catalog[0].Nsecfilt;
+  subcatalog[0].catID    = catalog[0].catID;
+  assert (Nsecfilt == catalog[0].Nsecfilt);
+
+  // limit the total number of stars in the catalog
+  if (MaxDensityUse) {
+    LimitDensityCatalog_ByNmeasureGrid (subcatalog, catalog);
+  } else {
+    if (VERBOSE2) {
+      char *basename = filebasename (catalog[0].filename);
+      fprintf (stderr, "subset of "OFF_T_FMT" ("OFF_T_FMT" total) stars, "OFF_T_FMT" ("OFF_T_FMT" total) measures for catalog %s\n", 
+	       subcatalog[0].Naverage, catalog[0].Naverage, subcatalog[0].Nmeasure, catalog[0].Nmeasure, basename);
+      free (basename);
+    }
+  }
+  if (CHECK_TEST_IMAGE && (Nkeep1 + Nkeep2 + Nskip1 + Nskip2 > 0)) {
+    fprintf (stderr, "kept %d %d, skipped %d %d\n", Nkeep1, Nkeep2, Nskip1, Nskip2);
+  }
+
+  return (TRUE);
+}
+
+void bcatalog_show_skips () {
+  fprintf (stderr, "Nskip: %d, %d\n", Nskip1, Nskip2);
+  fprintf (stderr, "Nkeep: %d, %d\n", Nkeep1, Nkeep2);
+}
+
+// sort by decreasing Nmeasure (X)
+void sort_by_Nmeasure (int *X, off_t *Y, off_t N) {
+
+# define SWAPFUNC(A,B){ int tmpI; off_t tmpT;	\
+  tmpI = X[A]; X[A] = X[B]; X[B] = tmpI; \
+  tmpT = Y[A]; Y[A] = Y[B]; Y[B] = tmpT; \
+}
+# define COMPARE(A,B)(X[A] > X[B])
+
+  OHANA_SORT (N, COMPARE, SWAPFUNC);
+
+# undef SWAPFUNC
+# undef COMPARE
+
+}
+
+/* generate a grid in a locally-projected coordinate system, try to select average entries 
+   from each grid cell in decending Nmeasure order.
+ */ 
+int LimitDensityCatalog_ByNmeasureGrid (Catalog *subcatalog, Catalog *oldcatalog) {
+
+  off_t i, j;
+  int ix, iy;
+
+  Catalog tmpcatalog;
+
+  double Rmin, Rmax, Dmin, Dmax;
+
+  int Nsecfilt = GetPhotcodeNsecfilt ();
+
+  gfits_scan (&oldcatalog[0].header, "RA0",  "%lf", 1, &Rmin);
+  gfits_scan (&oldcatalog[0].header, "DEC0", "%lf", 1, &Dmin);
+  gfits_scan (&oldcatalog[0].header, "RA1",  "%lf", 1, &Rmax);
+  gfits_scan (&oldcatalog[0].header, "DEC1", "%lf", 1, &Dmax);
+
+  if (VERBOSE2) fprintf (stderr, "extracting from catalog covering region %f,%f to %f,%f\n", Rmin, Dmin, Rmax, Dmax);
+
+  float AREA = fabs(Dmax - Dmin) * fabs(Rmax - Rmin) * cos (0.5*RAD_DEG*(Dmax + Dmin));
+  assert (AREA > 0);
+
+  off_t Nmax = MaxDensityValue * AREA;
+  if (subcatalog[0].Naverage <= Nmax) {
+    if (VERBOSE) {
+      fprintf (stderr, "subcatalog has less than the max density\n");
+    }
+    return (TRUE);
+  }
+
+  off_t Naverage = subcatalog[0].Naverage;
+
+  // generate a grid in locally projected space
+  double Rc = 0.5*(Rmin + Rmax);
+  double Dc = 0.5*(Dmin + Dmax);
+
+  /* project coordinates to a plane centered on the object with units of arcsec */
+  Coords coords;
+  coords.crval1 = Rc;
+  coords.crval2 = Dc;
+  coords.crpix1 = 0;
+  coords.crpix2 = 0;
+  coords.cdelt1 = coords.cdelt2 = 1.0 / 3600.0;
+  coords.pc1_1  = coords.pc2_2 = 1.0;
+  coords.pc1_2  = coords.pc2_1 = 0.0;
+  coords.Npolyterms = 1;
+  strcpy (coords.ctype, "DEC--SIN");
+
+  // convert all average R,D values to X,Y:
+  double *X, *Y;
+  ALLOCATE (X, double, Naverage);
+  ALLOCATE (Y, double, Naverage);
+  float Xmin = +10000.0, Ymin = +10000.0;
+  float Xmax = -10000.0, Ymax = -10000.0;
+  for (i = 0; i < Naverage; i++) {
+    X[i] = NAN;
+    Y[i] = NAN;
+    // skip any stars which are outside of nominal catalog range
+    if (subcatalog[0].average[i].R < Rmin) continue;
+    if (subcatalog[0].average[i].R > Rmax) continue;
+    if (subcatalog[0].average[i].D < Dmin) continue;
+    if (subcatalog[0].average[i].D > Dmax) continue;
+    RD_to_XY (&X[i], &Y[i], subcatalog[0].average[i].R, subcatalog[0].average[i].D, &coords);
+    Xmin = MIN (Xmin, X[i]);
+    Xmax = MAX (Xmax, X[i]);
+    Ymin = MIN (Ymin, Y[i]);
+    Ymax = MAX (Ymax, Y[i]);
+  }
+
+  // how many grid cells? what is the grid spacing? 
+  float dX = Xmax - Xmin;
+  float dY = Ymax - Ymin;
+
+  // *** XXX for the moment, I'm using a hard-wired cell size (200 arcsec ~ 3.3 arcmin)
+  int NX = (int)(dX / 200) + 1;
+  int NY = (int)(dY / 200) + 1;
+  // fprintf (stderr, "Density Grid: %d x %d\n", NX, NY);
+  // XXX check that NX,NY are sensible (5 degrees / 200 arcsec seems like the absolute max)
+  if (NX > 1000) { 
+    fprintf (stderr, "serious problem with %s: NX = %d\n", subcatalog[0].filename, NX); 
+    exit (3); 
+  }
+  if (NY > 1000) { 
+    fprintf (stderr, "serious problem with %s: NY = %d\n", subcatalog[0].filename, NY); 
+    exit (3); 
+  }
+  
+  // kind of ugly : generate a grid of index, Nmeasure arrays
+  // to be filled below (I also need NN and Nn to track the number of 
+  // entries in each).
+  int    **NN_grid;
+  int    **Nn_grid;
+  int   ***Nm_grid;
+  off_t ***idxgrid;
+  ALLOCATE (NN_grid, int *, NX);
+  ALLOCATE (Nn_grid, int *, NX);
+  ALLOCATE (Nm_grid, int **, NX);
+  ALLOCATE (idxgrid, off_t **, NX);
+
+  for (ix = 0; ix < NX; ix++) {
+    ALLOCATE (NN_grid[ix], int, NY);
+    ALLOCATE (Nn_grid[ix], int, NY);
+    ALLOCATE (Nm_grid[ix], int *, NY);
+    ALLOCATE (idxgrid[ix], off_t *, NY);
+    for (iy = 0; iy < NY; iy++) {
+      Nn_grid[ix][iy] = 0;
+      NN_grid[ix][iy] = 100;
+      ALLOCATE (Nm_grid[ix][iy], int,   NN_grid[ix][iy]);
+      ALLOCATE (idxgrid[ix][iy], off_t, NN_grid[ix][iy]);
+    }
+  }
+
+  // assign all of the average entries to a grid cell
+  for (i = 0; i < Naverage; i++) {
+    if (isnan(X[i])) continue;
+    if (isnan(Y[i])) continue;
+    ix = (X[i] - Xmin) / 200.0;
+    iy = (Y[i] - Ymin) / 200.0;
+    int Nn = Nn_grid[ix][iy];
+    Nm_grid[ix][iy][Nn] = subcatalog[0].average[i].Nmeasure;
+    
+    // if we are resetting to a given photcode, we need to have that photcode...
+    // XXX this is not relevant for the check...
+    if (FALSE && NphotcodesReset) {
+      int k;
+      int foundReset = FALSE;
+      int m = subcatalog[0].average[i].measureOffset;
+      MeasureTiny *measure = &subcatalog[0].measureT[m];
+      for (j = 0; (j < subcatalog[0].average[i].Nmeasure) && !foundReset; j++) {
+	if (CHECK_TEST_IMAGE && (abs(measure[j].t - Tref) < 10) && (measure[j].photcode == Cref)) {
+	  fprintf (stderr, ".");
+	}
+	for (k = 0; (k < NphotcodesReset) && !foundReset; k++) {
+	  if (photcodesReset[k][0].code == measure[j].photcode) foundReset = TRUE;
+	}
+      }
+      if (!foundReset) {
+	Nm_grid[ix][iy][Nn] = 0;
+      }
+    }
+
+    idxgrid[ix][iy][Nn] = i;
+    Nn_grid[ix][iy] ++;
+    if (Nn_grid[ix][iy] >= NN_grid[ix][iy]) {
+      NN_grid[ix][iy] += 100;
+      REALLOCATE (Nm_grid[ix][iy], int,   NN_grid[ix][iy]);
+      REALLOCATE (idxgrid[ix][iy], off_t, NN_grid[ix][iy]);
+    }
+  }
+    
+  // sort all of the grid cells
+  for (ix = 0; ix < NX; ix++) {
+    for (iy = 0; iy < NY; iy++) {
+      sort_by_Nmeasure (Nm_grid[ix][iy], idxgrid[ix][iy], Nn_grid[ix][iy]);
+      NN_grid[ix][iy] = 0; // I'm going to use this array to track which element I've already selected
+    }
+  }
+
+  // cycle over the grid until we ready Nmax
+  off_t *keepidx = NULL;
+  ALLOCATE (keepidx, off_t, Naverage);
+  memset (keepidx, 0, Naverage*sizeof(off_t));
+  int Nkeep = 0;
+
+  for (i = 0; (i < 20) && (Nkeep < Nmax); i++) {
+    for (ix = 0; (ix < NX) && (Nkeep < Nmax); ix++) {
+      for (iy = 0; (iy < NY) && (Nkeep < Nmax); iy++) {
+	if (NN_grid[ix][iy] >= Nn_grid[ix][iy]) continue; // all used up!
+	int Nn = NN_grid[ix][iy];
+	keepidx[Nkeep] = idxgrid[ix][iy][Nn];
+	Nkeep ++;
+	NN_grid[ix][iy] ++;
+      }
+    }
+  }
+
+  // count the number of measurements this selection will yield
+  off_t ave, NMEASURE = 0;
+  for (i = 0; i < Nkeep; i++) {
+    ave = keepidx[i];
+    NMEASURE += subcatalog[0].average[ave].Nmeasure;
+  }
+
+  // test catID : 37262 37261 37257 37258
+  int dumpit = FALSE;
+  dumpit |= (oldcatalog[0].catID == 37007);
+  // dumpit |= (oldcatalog[0].catID == 37261);
+  // dumpit |= (oldcatalog[0].catID == 37257);
+  // dumpit |= (oldcatalog[0].catID == 37258);
+  if (dumpit) {
+    char name[64];
+    snprintf (name, 64, "cat.%05d.dump.dat", oldcatalog[0].catID);
+    FILE *fdump = fopen (name, "w");
+    for (i = 0; i < Nkeep; i++) {
+      ave = keepidx[i];
+      fprintf (fdump, "%10.6f %10.6f %d\n", subcatalog[0].average[ave].R, subcatalog[0].average[ave].D, subcatalog[0].average[ave].Nmeasure);
+    }
+    fclose (fdump);
+  }
+
+  // allocate the output data 
+  ALLOCATE (tmpcatalog.average,  Average,     Nkeep);
+  ALLOCATE (tmpcatalog.measureT, MeasureTiny, NMEASURE);
+  ALLOCATE (tmpcatalog.secfilt,  SecFilt,     Nkeep * Nsecfilt);
+
+  off_t Nmeasure = 0;
+
+  // copy the Nkeep selected entries from subcatalog to tmpcatalog (adjusting links)
+  for (i = 0; i < Nkeep; i++) {
+    ave = keepidx[i];
+    tmpcatalog.average[i] = subcatalog[0].average[ave];
+    tmpcatalog.average[i].measureOffset = Nmeasure;
+    for (j = 0; j < tmpcatalog.average[i].Nmeasure; j++) {
+      off_t offset = subcatalog[0].average[ave].measureOffset + j;
+      tmpcatalog.measureT[Nmeasure] = subcatalog[0].measureT[offset];
+      tmpcatalog.measureT[Nmeasure].averef = i;
+      Nmeasure ++;
+    }
+    for (j = 0; j < Nsecfilt; j++) {
+      tmpcatalog.secfilt[i*Nsecfilt + j] = subcatalog[0].secfilt[ave*Nsecfilt + j];
+    }
+  }
+
+  if (VERBOSE2) {
+    char *basename = filebasename (oldcatalog[0].filename);
+    fprintf (stderr, "limited to %d ("OFF_T_FMT" subset, "OFF_T_FMT" total) stars, "OFF_T_FMT" ("OFF_T_FMT" subset, "OFF_T_FMT" total) measures for catalog %s\n", 
+	     Nkeep, subcatalog[0].Naverage, oldcatalog[0].Naverage, Nmeasure, subcatalog[0].Nmeasure,  oldcatalog[0].Nmeasure, basename);
+    free (basename);
+  }
+
+  free (X);
+  free (Y);
+
+  for (ix = 0; ix < NX; ix++) {
+    for (iy = 0; iy < NY; iy++) {
+      free (Nm_grid[ix][iy]);
+      free (idxgrid[ix][iy]);
+    }
+    free (NN_grid[ix]);
+    free (Nn_grid[ix]);
+    free (Nm_grid[ix]);
+    free (idxgrid[ix]);
+  }
+  free (NN_grid);
+  free (Nn_grid);
+  free (Nm_grid);
+  free (idxgrid);
+
+  free (keepidx);
+
+  free (subcatalog[0].average);
+  free (subcatalog[0].measureT);
+  free (subcatalog[0].secfilt);
+
+  subcatalog[0].average = tmpcatalog.average;
+  subcatalog[0].measureT = tmpcatalog.measureT;
+  subcatalog[0].secfilt = tmpcatalog.secfilt;
+  subcatalog[0].Naverage = Nkeep;
+  subcatalog[0].Nmeasure = Nmeasure;
+  subcatalog[0].Nsecfilt = oldcatalog[0].Nsecfilt;
+  subcatalog[0].Nsecf_mem = Naverage * oldcatalog[0].Nsecfilt;
+
+  return (TRUE);
+}
+
+/* this version does NOT use AverageTiny, MeasureTiny */ 
+int LimitDensityCatalog_ByNmeasure (Catalog *subcatalog, Catalog *oldcatalog) {
+
+  Catalog tmpcatalog;
+
+  double Rmin, Rmax, Dmin, Dmax;
+
+  int Nsecfilt = GetPhotcodeNsecfilt ();
+
+  gfits_scan (&oldcatalog[0].header, "RA0",  "%lf", 1, &Rmin);
+  gfits_scan (&oldcatalog[0].header, "DEC0", "%lf", 1, &Dmin);
+  gfits_scan (&oldcatalog[0].header, "RA1",  "%lf", 1, &Rmax);
+  gfits_scan (&oldcatalog[0].header, "DEC1", "%lf", 1, &Dmax);
+
+  if (VERBOSE2) fprintf (stderr, "extracting from catalog covering region %f,%f to %f,%f\n", Rmin, Dmin, Rmax, Dmax);
+
+  float AREA = fabs(Dmax - Dmin) * fabs(Rmax - Rmin) * cos (0.5*RAD_DEG*(Dmax + Dmin));
+  assert (AREA > 0);
+
+  off_t Nmax = MaxDensityValue * AREA;
+  if (subcatalog[0].Naverage <= Nmax) {
+    if (VERBOSE) {
+      fprintf (stderr, "subcatalog has less than the max density\n");
+    }
+    return (TRUE);
+  }
+
+  off_t Naverage = subcatalog[0].Naverage;
+
+  // select a random subset of Nmax stars from subcatalog using Fisher-Yates
+
+  // we are going to select Nmax entries by choosing the brightest objects
+  int *value;
+  off_t *index, i, j, ave;
+  ALLOCATE (index, off_t, Naverage);
+  ALLOCATE (value, int, Naverage);
+  for (i = 0; i < Naverage; i++) {
+    index[i] = i;
+    value[i] = subcatalog[0].average[i].Nmeasure;
+  }
+  sort_by_Nmeasure (value, index, Naverage);
+
+  // count the number of measurements this selection will yield
+  off_t NMEASURE = 0;
+  for (i = 0; i < Nmax; i++) {
+    ave = index[i];
+    NMEASURE += subcatalog[0].average[ave].Nmeasure;
+  }
+
+# if (0)
+  if (oldcatalog[0].catID == 59962) {
+    FILE *fdump = fopen ("cat.dump.dat", "w");
+    for (i = 0; i < Nmax; i++) {
+      ave = index[i];
+      fprintf (fdump, "%10.6f %10.6f %d\n", subcatalog[0].average[ave].R, subcatalog[0].average[ave].D, subcatalog[0].average[ave].Nmeasure);
+    }
+    fclose (fdump);
+  }
+# endif
+
+  // allocate the output data 
+  ALLOCATE (tmpcatalog.average,  Average,     Nmax);
+  ALLOCATE (tmpcatalog.measureT, MeasureTiny, NMEASURE);
+  ALLOCATE (tmpcatalog.secfilt,  SecFilt,     Nmax * Nsecfilt);
+
+  off_t Nmeasure = 0;
+
+  // copy the Nmax selected entries from subcatalog to tmpcatalog (adjusting links)
+  for (i = 0; i < Nmax; i++) {
+    ave = index[i];
+    tmpcatalog.average[i] = subcatalog[0].average[ave];
+    tmpcatalog.average[i].measureOffset = Nmeasure;
+    for (j = 0; j < tmpcatalog.average[i].Nmeasure; j++) {
+      off_t offset = subcatalog[0].average[ave].measureOffset + j;
+      tmpcatalog.measureT[Nmeasure] = subcatalog[0].measureT[offset];
+      tmpcatalog.measureT[Nmeasure].averef = i;
+      Nmeasure ++;
+    }
+    for (j = 0; j < Nsecfilt; j++) {
+      tmpcatalog.secfilt[i*Nsecfilt + j] = subcatalog[0].secfilt[ave*Nsecfilt + j];
+    }
+  }
+
+  if (VERBOSE2) {
+    char *basename = filebasename (oldcatalog[0].filename);
+    fprintf (stderr, "limited to "OFF_T_FMT" ("OFF_T_FMT" subset, "OFF_T_FMT" total) stars, "OFF_T_FMT" ("OFF_T_FMT" subset, "OFF_T_FMT" total) measures for catalog %s\n", 
+	     Nmax, subcatalog[0].Naverage, oldcatalog[0].Naverage, Nmeasure, subcatalog[0].Nmeasure,  oldcatalog[0].Nmeasure, basename);
+    free (basename);
+  }
+
+  free (index);
+  free (value);
+  free (subcatalog[0].average);
+  free (subcatalog[0].measureT);
+  free (subcatalog[0].secfilt);
+
+  subcatalog[0].average = tmpcatalog.average;
+  subcatalog[0].measureT = tmpcatalog.measureT;
+  subcatalog[0].secfilt = tmpcatalog.secfilt;
+  subcatalog[0].Naverage = Nmax;
+  subcatalog[0].Nmeasure = Nmeasure;
+  subcatalog[0].Nsecfilt = oldcatalog[0].Nsecfilt;
+  subcatalog[0].Nsecf_mem = Naverage * oldcatalog[0].Nsecfilt;
+
+  return (TRUE);
+}
+
+/* this version does NOT use AverageTiny, MeasureTiny */ 
+int LimitDensityCatalog_RandomSample (Catalog *subcatalog, Catalog *catalog) {
+
+  Catalog tmpcatalog;
+
+  double Rmin, Rmax, Dmin, Dmax;
+
+  int Nsecfilt = GetPhotcodeNsecfilt ();
+
+  gfits_scan (&catalog[0].header, "RA0",  "%lf", 1, &Rmin);
+  gfits_scan (&catalog[0].header, "DEC0", "%lf", 1, &Dmin);
+  gfits_scan (&catalog[0].header, "RA1",  "%lf", 1, &Rmax);
+  gfits_scan (&catalog[0].header, "DEC1", "%lf", 1, &Dmax);
+
+  if (VERBOSE2) fprintf (stderr, "extracting from catalog covering region %f,%f to %f,%f\n", Rmin, Dmin, Rmax, Dmax);
+
+  float AREA = fabs(Dmax - Dmin) * fabs(Rmax - Rmin) * cos (0.5*RAD_DEG*(Dmax + Dmin));
+  assert (AREA > 0);
+
+  off_t Nmax = MaxDensityValue * AREA;
+  if (subcatalog[0].Naverage <= Nmax) {
+    if (VERBOSE2) {
+      fprintf (stderr, "subcatalog has less than the max density\n");
+    }
+    return (TRUE);
+  }
+
+  off_t Naverage = subcatalog[0].Naverage;
+
+  // select a random subset of Nmax stars from subcatalog using Fisher-Yates
+
+  // we are going to select Nmax entries by generating a random-sorted index list
+  off_t *index, tmp, i, j, ave;
+  ALLOCATE (index, off_t, Naverage);
+  for (i = 0; i < Naverage; i++) {
+    index[i] = i;
+  }
+  for (i = 0; i < Naverage; i++) {
+    j = (Naverage - i) * drand48() + i; // a number between i and Naverage
+    tmp = index[j];
+    index[j] = index[i];
+    index[i] = tmp;
+  }
+
+  // count the number of measurements this selection will yield
+  off_t NMEASURE = 0;
+  for (i = 0; i < Nmax; i++) {
+    ave = index[i];
+    NMEASURE += subcatalog[0].average[ave].Nmeasure;
+  }
+
+  // allocate the output data 
+  ALLOCATE (tmpcatalog.average,  Average,     Nmax);
+  ALLOCATE (tmpcatalog.measureT, MeasureTiny, NMEASURE);
+  ALLOCATE (tmpcatalog.secfilt,  SecFilt,     Nmax * Nsecfilt);
+
+  off_t Nmeasure = 0;
+
+  // copy the Nmax selected entries from subcatalog to tmpcatalog (adjusting links)
+  for (i = 0; i < Nmax; i++) {
+    ave = index[i];
+    tmpcatalog.average[i] = subcatalog[0].average[ave];
+    tmpcatalog.average[i].measureOffset = Nmeasure;
+    for (j = 0; j < tmpcatalog.average[i].Nmeasure; j++) {
+      off_t offset = subcatalog[0].average[ave].measureOffset + j;
+      tmpcatalog.measureT[Nmeasure] = subcatalog[0].measureT[offset];
+      tmpcatalog.measureT[Nmeasure].averef = i;
+      Nmeasure ++;
+    }
+    for (j = 0; j < Nsecfilt; j++) {
+      tmpcatalog.secfilt[i*Nsecfilt + j] = subcatalog[0].secfilt[ave*Nsecfilt + j];
+    }
+  }
+
+  if (VERBOSE2) {
+    fprintf (stderr, "limited to "OFF_T_FMT" of "OFF_T_FMT" stars ("OFF_T_FMT" of "OFF_T_FMT" measures) for catalog %s\n", 
+	     Nmax, subcatalog[0].Naverage, Nmeasure, subcatalog[0].Nmeasure,  catalog[0].filename);
+  }
+
+  free (subcatalog[0].average);
+  free (subcatalog[0].measureT);
+  free (subcatalog[0].secfilt);
+
+  subcatalog[0].average = tmpcatalog.average;
+  subcatalog[0].measureT = tmpcatalog.measureT;
+  subcatalog[0].secfilt = tmpcatalog.secfilt;
+  subcatalog[0].Naverage = Nmax;
+  subcatalog[0].Nmeasure = Nmeasure;
+  subcatalog[0].Nsecfilt = catalog[0].Nsecfilt;
+  subcatalog[0].Nsecf_mem = Naverage * catalog[0].Nsecfilt;
+
+  return (TRUE);
+}
+
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/checkastro.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/checkastro.c	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/checkastro.c	(revision 37403)
@@ -0,0 +1,14 @@
+# include "checkastro.h"
+
+int main (int argc, char **argv) {
+
+  /* get configuration info, args */
+  initialize (argc, argv);
+
+  SkyTable *sky = SkyTableLoadOptimal (CATDIR, SKY_TABLE, GSCFILE, TRUE, SKY_DEPTH, VERBOSE);
+  SkyTableSetFilenames (sky, CATDIR, "cpt");
+  SkyList *skylist = SkyListByPatch (sky, -1, &UserPatch);
+
+  checkastro_images (skylist);
+  exit (0);
+}
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/checkastro_client.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/checkastro_client.c	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/checkastro_client.c	(revision 37403)
@@ -0,0 +1,36 @@
+# include "checkastro.h"
+
+// checkastro_client is run on a remote host and is responsible for updating the catalogs
+// owned by that host.  
+
+// there are four modes:
+
+// checkastro_client -load-objects : extract the bright catalog subset from the client's
+//                                 tables and save to a local FITS table for checkastro to
+//                                 load and used
+
+int main (int argc, char **argv) {
+
+  // get configuration info, args, lockfile (set CATDIR, HOST_ID, HOSTDIR, etc) 
+  initialize_client (argc, argv);
+
+  SkyTable *sky = SkyTableLoadOptimal (CATDIR, SKY_TABLE, GSCFILE, TRUE, SKY_DEPTH, VERBOSE);
+  SkyTableSetFilenames (sky, CATDIR, "cpt");
+  SkyList *skylist = SkyListByPatch (sky, -1, &UserPatch);
+
+  // USAGE: checkastro_client -load-objects
+  int Ncatalog;
+  Catalog *catalog = load_catalogs (skylist, &Ncatalog, TRUE, HOST_ID, HOSTDIR);
+  if (!catalog) {
+    fprintf (stderr, "ERROR loading catalogs from %s\n", CATDIR);
+    exit (2);
+  }
+
+  BrightCatalog *bcatalog = BrightCatalogMerge (catalog, Ncatalog);
+  if (!BrightCatalogSave (BCATALOG, bcatalog)) {
+    fprintf (stderr, "ERROR saving bright catalog from %s\n", CATDIR);
+    exit (2);
+  }
+
+  exit (0);
+}
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/checkastro_images.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/checkastro_images.c	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/checkastro_images.c	(revision 37403)
@@ -0,0 +1,48 @@
+# include "checkastro.h"
+
+int checkastro_images (SkyList *skylist) {
+
+  int status, Ncatalog;
+  Catalog *catalog;
+  FITS_DB db;
+
+  INITTIME;
+
+  /* register database handle with shutdown procedure */
+  set_db (&db);
+
+  /* lock and load the image db table */
+  status = dvo_image_lock (&db, ImageCat, 60.0, LCK_SOFT);
+  if (!status) Shutdown ("ERROR: failure to lock image catalog %s", db.filename);
+  if (db.dbstate == LCK_EMPTY) Shutdown ("ERROR: No images in catalog %s (1)", db.filename);
+  if (!dvo_image_load (&db, VERBOSE, FALSE)) Shutdown ("can't read image catalog %s", db.filename);
+  MARKTIME("load image data: %f sec\n", dtime);
+
+  /* load regions and images based on specified sky patch (default depth) (require full overlap) */
+  load_images (&db, skylist);
+  MARKTIME("load images: %f sec\n", dtime);
+
+  // photcodesKeep is used here to allow measurements from the images being calibrated
+  // note if -reset-to-photcode is selected, photocodesKeep is replaced with below with photcodesReset
+  catalog = load_catalogs (skylist, &Ncatalog, TRUE, 0, NULL);
+  MARKTIME("load catalog data: %f sec\n", dtime);
+
+  if (photcodesReset) {
+    photcodesKeep  = photcodesReset;
+    NphotcodesKeep = NphotcodesReset;
+  }
+
+  if (Ncatalog == 0) {
+    fprintf (stderr, "ERROR: no valid data for checkastro, exiting\n");
+    exit (2);
+  }
+
+  /* match measurements with images */
+  initImageBins (catalog, Ncatalog);
+  MARKTIME("make image bins: %f sec\n", dtime);
+
+  findImages (catalog, Ncatalog);
+  MARKTIME("set up image indexes: %f sec\n", dtime);
+
+  exit (0);
+}
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/initialize.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/initialize.c	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/initialize.c	(revision 37403)
@@ -0,0 +1,29 @@
+# include "checkastro.h"
+
+void initialize (int argc, char **argv) {
+
+  ConfigInit (&argc, argv);
+  args (argc, argv);
+
+  if (PHOTCODE_KEEP_LIST)  fprintf (stderr, "PHOTCODE_KEEP_LIST:  %s\n", PHOTCODE_KEEP_LIST);
+  if (PHOTCODE_SKIP_LIST)  fprintf (stderr, "PHOTCODE_SKIP_LIST:  %s\n", PHOTCODE_SKIP_LIST);
+  if (PHOTCODE_RESET_LIST) fprintf (stderr, "PHOTCODE_RESET_LIST: %s\n", PHOTCODE_RESET_LIST);
+
+  photcodesKeep   = ParsePhotcodeList (PHOTCODE_KEEP_LIST,  &NphotcodesKeep,   FALSE);
+  photcodesSkip   = ParsePhotcodeList (PHOTCODE_SKIP_LIST,  &NphotcodesSkip,   FALSE);
+  photcodesReset  = ParsePhotcodeList (PHOTCODE_RESET_LIST, &NphotcodesReset,  FALSE);
+}
+
+void initialize_client (int argc, char **argv) {
+
+  ConfigInit (&argc, argv);
+  args_client (argc, argv);
+
+  if (PHOTCODE_KEEP_LIST)  fprintf (stderr, "PHOTCODE_KEEP_LIST:  %s\n", PHOTCODE_KEEP_LIST);
+  if (PHOTCODE_SKIP_LIST)  fprintf (stderr, "PHOTCODE_SKIP_LIST:  %s\n", PHOTCODE_SKIP_LIST);
+  if (PHOTCODE_RESET_LIST) fprintf (stderr, "PHOTCODE_RESET_LIST: %s\n", PHOTCODE_RESET_LIST);
+
+  photcodesKeep   = ParsePhotcodeList (PHOTCODE_KEEP_LIST,  &NphotcodesKeep,   FALSE);
+  photcodesSkip   = ParsePhotcodeList (PHOTCODE_SKIP_LIST,  &NphotcodesSkip,   FALSE);
+  photcodesReset  = ParsePhotcodeList (PHOTCODE_RESET_LIST, &NphotcodesReset,  FALSE);
+}
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/load_catalogs.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/load_catalogs.c	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/load_catalogs.c	(revision 37403)
@@ -0,0 +1,215 @@
+# include "checkastro.h"
+
+Catalog *load_catalogs (SkyList *skylist, int *Ncatalog, int subselect, int hostID, char *hostpath) {
+
+  int i, Nstar;
+  Catalog *catalog, *pcatalog, tcatalog;
+
+  // XXX need to decide how to determine PARALLEL mode...
+  if (PARALLEL && !hostID) {
+    catalog = load_catalogs_parallel (skylist, Ncatalog);
+    return catalog;
+  }
+
+  if (VERBOSE) fprintf (stderr, "loading catalog data\n");
+
+  ALLOCATE (catalog, Catalog, skylist[0].Nregions);
+
+  // load data from each region file, only use bright stars
+  int Ncat = 0;
+  for (i = 0; i < skylist[0].Nregions; i++) {
+
+    // does this host ID match the desired location for the table?
+    if (!HostTableTestHost(skylist[0].regions[i], hostID)) continue;
+
+    // we only allow output if we do not use a subset.  in this case,
+    // the output parameters are correctly set for catalog[i] via pcatalog
+    pcatalog = subselect ? &tcatalog : &catalog[i];
+
+    // define the catalog file name
+    char hostfile[1024];
+    snprintf (hostfile, 1024, "%s/%s.cpt", hostpath, skylist[0].regions[i]->name);
+    pcatalog->filename = hostID ? hostfile : skylist[0].filename[i];
+
+    // set up the basic catalog info
+    pcatalog->catformat = dvo_catalog_catformat (CATFORMAT);    // set the default catformat from config data
+    pcatalog->catmode   = dvo_catalog_catmode (CATMODE);        // set the default catmode from config data
+    pcatalog->catflags  = LOAD_AVES | LOAD_MEAS | LOAD_SECF; // don't need to load all data at this point
+    pcatalog->Nsecfilt  = GetPhotcodeNsecfilt ();
+
+    // loads Average, Measure, SecFilt
+    if (!dvo_catalog_open (pcatalog, skylist[0].regions[i], VERBOSE2, "w")) {
+      fprintf (stderr, "ERROR: failure reading catalog %s\n", pcatalog[0].filename);
+      exit (1);
+    }
+    if (!pcatalog[0].Naves_disk) {
+      if (VERBOSE2) fprintf (stderr, "no data in %s, skipping\n", pcatalog[0].filename);
+      dvo_catalog_unlock (pcatalog);
+      dvo_catalog_free (pcatalog);
+      continue;
+    }
+
+    if (!pcatalog->sorted) {
+      fprintf (stderr, "this database is not sorted.  please sort using addstar -resort\n");
+      exit (1);
+    }
+
+    // select only the brighter stars
+    if (subselect) {
+      // results are in Average, Secfilt, and MeasureTiny
+      // Ncat tracks the actually used catalogs
+      bcatalog (&catalog[Ncat], &tcatalog);
+      dvo_catalog_unlock (&tcatalog);
+      dvo_catalog_free (&tcatalog);
+    }
+    Ncat ++;
+  }
+
+  // XXX TEST : bcatalog_show_skips();
+
+  Nstar = 0;
+  for (i = 0; i < Ncat; i++) {
+    Nstar += catalog[i].Naverage;
+    if ((sizeof(IDX_T) == 8) && (catalog[i].Nmeasure > 0xffffffff)) {
+      fprintf (stderr, "ERROR: using small-sized IDX_T on data with more than 2G detections per table will cause errors\n");
+      fprintf (stderr, "  If you need to do this, and you can afford the RAM, rebuild with IDX_T set to off_t (see checkastro.h, ImagesOps.c)\n");
+      exit (3);
+    }
+  }
+  if (Nstar < 2) { 
+    fprintf (stderr, "warning: insufficient stars %d\n", Nstar);
+  }
+
+  // only return the populated catalogs
+  REALLOCATE (catalog, Catalog, Ncat);
+  *Ncatalog = Ncat;
+  return (catalog);
+}
+
+/* this function loads all relevant catalog files for the first pass.  it currently loads the data
+   read only (SOFT lock) since it assumes the image table has been locked. if we go to the new
+   addstar locking paradigm, in which the images and catalogs are updated independently, then we may
+   need to use an XCLD lock here.  
+*/
+
+// CATDIR is supplied globally
+# define DEBUG 1
+Catalog *load_catalogs_parallel (SkyList *sky, int *Ncatalog) {
+
+  char uniquer[12];
+  int TIME = time(NULL);
+  int PID = getpid();
+  snprintf (uniquer, 12, "%05d.%05d", PID, TIME % 100000);
+
+  // load the list of hosts
+  HostTable *table = HostTableLoad (CATDIR, sky->hosts);
+  if (!table) {
+    fprintf (stderr, "ERROR: failure reading Host Table %s for database %s\n", sky->hosts, CATDIR);
+    exit (1);
+  }    
+
+  int i;
+  for (i = 0; i < table->Nhosts; i++) {
+
+    // ensure that the paths are absolute path names
+    char *tmppath = abspath (table->hosts[i].pathname, DVO_MAX_PATH);
+    free (table->hosts[i].pathname);
+    table->hosts[i].pathname = tmppath;
+
+    ALLOCATE (table->hosts[i].results, char, 1024);
+    snprintf (table->hosts[i].results, 1024, "%s/checkastro.catalog.%s.dat", table->hosts[i].pathname, uniquer);
+
+    char command[1024];
+    snprintf (command, 1024, "checkastro_client -load-objects %s -hostID %d -D CATDIR %s -hostdir %s -region %f %f %f %f -D RELASTRO_SIGMA_LIM %f", 
+	      table->hosts[i].results, table->hosts[i].hostID, CATDIR, table->hosts[i].pathname, UserPatch.Rmin, UserPatch.Rmax, UserPatch.Dmin, UserPatch.Dmax, SIGMA_LIM);
+
+    char tmpline[1024];
+
+    if (VERBOSE)       { snprintf (tmpline, 1024, "%s -v",              command);                    strcpy (command, tmpline); }
+    if (VERBOSE2)      { snprintf (tmpline, 1024, "%s -vv",             command); 		     strcpy (command, tmpline); }
+    if (MaxDensityUse) { snprintf (tmpline, 1024, "%s -max-density %f", command, MaxDensityValue);   strcpy (command, tmpline); }
+    if (ImagSelect)    { snprintf (tmpline, 1024, "%s -instmag %f %f",  command, ImagMin, ImagMax);  strcpy (command, tmpline); }
+
+    if (PHOTCODE_KEEP_LIST) { snprintf (tmpline, 1024, "%s +photcode %s", command, PHOTCODE_KEEP_LIST); strcpy (command, tmpline); }
+    if (PHOTCODE_SKIP_LIST) { snprintf (tmpline, 1024, "%s -photcode %s", command, PHOTCODE_SKIP_LIST); strcpy (command, tmpline); }
+    if (PHOTCODE_RESET_LIST) { snprintf (tmpline, 1024, "%s -reset-to-photcode %s", command, PHOTCODE_RESET_LIST); strcpy (command, tmpline); }
+    if (PhotFlagSelect)    { snprintf (tmpline, 1024, "%s +photflags",   command);                     strcpy (command, tmpline); }
+    if (PhotFlagBad)       { snprintf (tmpline, 1024, "%s +photflagbad %d", command, PhotFlagBad);     strcpy (command, tmpline); }
+    if (PhotFlagPoor)      { snprintf (tmpline, 1024, "%s +photflagpoor %d", command, PhotFlagPoor);   strcpy (command, tmpline); }
+    // XXX note that the above pass in the flag as decimal -- also note that args.c cannot handle 0xHEX values
+
+    if (TimeSelect) { 
+      char *tstart = ohana_sec_to_date (TSTART);
+      char *tstop  = ohana_sec_to_date (TSTOP);
+      snprintf (tmpline, 1024, "%s -time %s %s", command, tstart, tstop); 
+      free (tstart);
+      free (tstop);
+      strcpy (command, tmpline); 
+    }
+
+    fprintf (stderr, "command: %s\n", command);
+
+    if (PARALLEL_MANUAL) continue;
+
+    if (PARALLEL_SERIAL) {
+      int status = system (command);
+      if (status) {
+	fprintf (stderr, "ERROR running checkastro_client\n");
+	exit (2);
+      }
+    } else {
+      // launch the job on the remote machine (no handshake)
+      int errorInfo = 0;
+      int pid = rconnect ("ssh", table->hosts[i].hostname, command, table->hosts[i].stdio, &errorInfo, FALSE);
+      if (!pid) {
+	if (DEBUG) fprintf (stderr, "failure to start %s (error %d)\n", table->hosts[i].hostname, errorInfo);
+	exit (1);
+      }
+      table->hosts[i].pid = pid; // save for future reference
+    }
+  }
+
+  if (PARALLEL_MANUAL) {
+    fprintf (stderr, "run the checkastro_client commands above.  when these are done, hit return\n");
+    getchar();
+  }
+  if (!PARALLEL_MANUAL && !PARALLEL_SERIAL) {
+    HostTableWaitJobsGetIO (table, __FILE__, __LINE__, VERBOSE);
+  }
+
+  // each host generates a BrightCatalog structure, with the measure, average, etc value
+  // loaded into a single set of arrays (of MeasureTiny, AverageTiny, Secfilt).  I need to
+  // split out the per-catalog measurements into separate catalog entries.
+
+  // set up an initial array of catalogs
+  int Nsecfilt  = GetPhotcodeNsecfilt (); 
+  CatalogSplitter *catalogs = BrightCatalogSplitInit (Nsecfilt);
+
+  for (i = 0; i < table->Nhosts; i++) {
+
+    BrightCatalog *bcatalog = BrightCatalogLoad (table->hosts[i].results);
+    assert (bcatalog);
+    
+    BrightCatalogSplit (catalogs, bcatalog);
+
+    free (bcatalog->average);
+    free (bcatalog->measure);
+    free (bcatalog->secfilt);
+    free (bcatalog);
+  }
+
+  Catalog *catalog = catalogs->catalog;
+  *Ncatalog = catalogs->Ncatalog;
+  BrightCatalogSplitFree (catalogs);
+
+  int Nmeasure = 0;
+  int Naverage = 0;
+  for (i = 0; i < catalogs->Ncatalog; i++) {
+    Nmeasure += catalogs->catalog[i].Nmeasure;
+    Naverage += catalogs->catalog[i].Naverage;
+  }
+
+  fprintf (stderr, "loaded %d catalogs, using a total of %d stars (%d measures)\n", catalogs->Ncatalog, Naverage, Nmeasure);
+
+  return (catalog);
+}      
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/load_images.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/load_images.c	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/load_images.c	(revision 37403)
@@ -0,0 +1,34 @@
+# include "checkastro.h"
+
+int load_images (FITS_DB *db, SkyList *skylist) {
+
+  Image     *image, *subset;
+  off_t      Nimage, Nsubset;
+  off_t     *LineNumber;
+
+  INITTIME;
+
+  // convert database table to internal structure
+  image = gfits_table_get_Image (&db[0].ftable, &Nimage, &db[0].swapped);
+  if (!image) {
+      fprintf (stderr, "ERROR: failed to read images\n");
+      exit (2);
+  }
+  MARKTIME("  convert image table: %f sec\n", dtime);
+
+  // select the images which overlap the selected sky regions
+  subset = select_images (skylist, image, Nimage, &LineNumber, &Nsubset);
+  MARKTIME("  select images: %f sec\n", dtime);
+
+  fprintf (stderr, "%llx\n", (long long) subset);
+
+  initImages (subset, LineNumber, Nsubset);
+  MARKTIME("  init images: %f sec\n", dtime);
+
+  // unlock, if we can (else, unlocked below)
+  int unlockImages = TRUE;
+  if (unlockImages) dvo_image_unlock (db); 
+
+  return TRUE;
+}
+
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/select_images.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/select_images.c	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/checkastro/src/select_images.c	(revision 37403)
@@ -0,0 +1,132 @@
+# include "checkastro.h"
+
+/* this function returns a list of all images which overlap the given SkyList (set of
+   SkyRegions).  All images in the image catalog are tested once, so there is no check that an
+   image already has been included.  LineNum stores the locations in the Image database of the
+   list of images */
+
+Image *select_images (SkyList *skylist, Image *timage, off_t Ntimage, off_t **LineNumber, off_t *Nimage) {
+  
+  Image *image;
+  off_t i, k, nimage, NIMAGE, D_NIMAGE;
+  off_t *line_number;
+  int found;
+  double Rexp, Dexp;
+  
+  double RmaxSkyRegion, RminSkyRegion, RmidSkyRegion, DminSkyRegion, DmaxSkyRegion;
+
+  if (skylist[0].Nregions < 1) {
+    *Nimage = 0;
+    *LineNumber = NULL;
+    if (VERBOSE) fprintf (stderr, "no matching sky regions\n");
+    return NULL;
+  }
+
+  INITTIME;
+
+  RminSkyRegion = +360.0;
+  RmaxSkyRegion = -360.0;
+  DminSkyRegion = +90.0;
+  DmaxSkyRegion = -90.0;
+
+  D_NIMAGE = 6000;
+
+  /* compare with each region file */
+  for (i = 0; i < skylist[0].Nregions; i++) { 
+    RminSkyRegion = MIN(RminSkyRegion, skylist[0].regions[i][0].Rmin);
+    RmaxSkyRegion = MAX(RmaxSkyRegion, skylist[0].regions[i][0].Rmax);
+    DminSkyRegion = MIN(DminSkyRegion, skylist[0].regions[i][0].Dmin);
+    DmaxSkyRegion = MAX(DmaxSkyRegion, skylist[0].regions[i][0].Dmax);
+  }
+  RmidSkyRegion = 0.5*(RminSkyRegion + RmaxSkyRegion);
+  MARKTIME("define sky region: %f sec\n", dtime);
+
+  if (VERBOSE) fprintf (stderr, "finding images\n");
+  BuildChipMatch (timage, Ntimage);
+  MARKTIME("build chip match: %f sec\n", dtime);
+
+  nimage = 0;
+  NIMAGE = D_NIMAGE;
+  ALLOCATE (image, Image, NIMAGE);
+  ALLOCATE (line_number, off_t, NIMAGE);
+  
+  // we now have a region of interest: RminSkyRegion - RmaxSkyRegion, DminSkyRegion - DmaxSkyRegion, 
+  // we now want to find all gpc1 chips (WRP) for which the exposure center (DIS) is in this region,
+
+  // go through the complete list of images, selecting ones which overlap the region
+  for (i = 0; i < Ntimage; i++) {
+      
+    /* select images by photcode, or equiv photcode, if specified */
+    if (NphotcodesKeep > 0) {
+      found = FALSE;
+      // we have to keep DIS mosaics explicitly (photcode = 0)
+      if (!strcmp(&timage[i].coords.ctype[4], "-DIS")) found = TRUE;
+      for (k = 0; (k < NphotcodesKeep) && !found; k++) {
+	if (photcodesKeep[k][0].code == timage[i].photcode) found = TRUE;
+	if (photcodesKeep[k][0].code == GetPhotcodeEquivCodebyCode(timage[i].photcode)) found = TRUE;
+      }
+      if (!found) continue;
+    }
+    if (NphotcodesSkip > 0) {
+      found = FALSE;
+      for (k = 0; (k < NphotcodesSkip) && !found; k++) {
+	if (photcodesSkip[k][0].code == timage[i].photcode) found = TRUE;
+	if (photcodesSkip[k][0].code == GetPhotcodeEquivCodebyCode(timage[i].photcode)) found = TRUE;
+      }
+      if (found) continue;
+    }
+
+    /* exclude images by time */
+    if (TimeSelect) {
+      if (timage[i].tzero < TSTART) continue;
+      if (timage[i].tzero > TSTOP) continue;
+    }
+    
+    // this adds 1.3 sec for 3M images
+    off_t myMosaic = FindMosaicForImage (timage, Ntimage, i);
+    if (!myMosaic) {
+      fprintf (stderr, "cannot find mosaic for "OFF_T_FMT"\n", i);
+      continue;
+    }
+    myMosaic --;
+
+    /* only check exposure center */
+    if (!strcmp(&timage[i].coords.ctype[4], "-DIS")) {
+      XY_to_RD (&Rexp, &Dexp, 0.0, 0.0, &timage[i].coords);
+    } else {
+      XY_to_RD (&Rexp, &Dexp, 0.0, 0.0, &timage[myMosaic].coords);
+    }
+    Rexp = ohana_normalize_angle_to_midpoint (Rexp, RmidSkyRegion);
+
+    // check that this image is even in range of the searched region
+    if (Dexp + 1.5 > UserPatch.Dmax) continue;
+    if (Dexp - 1.5 < UserPatch.Dmin) continue;
+    
+    // the sky region RA is defined to be 0 - 360.0
+    if ((Dexp < 88) && (Dexp > -88)) {
+      if (Rexp + 1.5/cos(Dexp*RAD_DEG) > UserPatch.Rmax) continue;
+      if (Rexp - 1.5/cos(Dexp*RAD_DEG) < UserPatch.Rmin) continue;
+    }
+
+    image[nimage] = timage[i]; 
+    line_number[nimage] = i;
+    nimage ++;
+    if (nimage == NIMAGE) {
+      NIMAGE += D_NIMAGE;
+      D_NIMAGE = MAX (100000, D_NIMAGE * 1.5);
+      REALLOCATE (image, Image, NIMAGE);
+      REALLOCATE (line_number, off_t, NIMAGE);
+    }
+  }
+  MARKTIME("finish image selection: %f sec\n", dtime);
+
+  if (VERBOSE) fprintf (stderr, "found "OFF_T_FMT" images\n", nimage);
+
+  REALLOCATE (image, Image, MAX (nimage, 1));
+  REALLOCATE (line_number, off_t, MAX (nimage, 1));
+
+  *Nimage  = nimage;
+  *LineNumber = line_number;
+  return (image);
+}
+
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/delstar/include/delstar.h
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/delstar/include/delstar.h	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/delstar/include/delstar.h	(revision 37403)
@@ -67,4 +67,5 @@
 int    UPDATE;
 int    IMAGE_DETAILS;
+int    IMAGE_DUPLICATES_BY_OBSTIME;
 int    IMAGE_ONLY;
 int    ORPHAN;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/delstar/src/ImageOpsFixLAP.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/delstar/src/ImageOpsFixLAP.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/delstar/src/ImageOpsFixLAP.c	(revision 37403)
@@ -1,4 +1,3 @@
 # include "delstar.h"
-# define FT_BZERO_INT32 1.0*0x80000000
 
 off_t   Nimage = 0;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/delstar/src/ImageSubsetFixLAP.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/delstar/src/ImageSubsetFixLAP.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/delstar/src/ImageSubsetFixLAP.c	(revision 37403)
@@ -1,5 +1,3 @@
 # include "delstar.h"
-# define FT_BZERO_INT16 1.0*0x8000	  
-# define FT_BZERO_INT32 1.0*0x80000000
 
 # define GET_COLUMN(OUT,NAME,TYPE) \
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/delstar/src/MeasureEdgeOps.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/delstar/src/MeasureEdgeOps.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/delstar/src/MeasureEdgeOps.c	(revision 37403)
@@ -1,4 +1,3 @@
 # include "delstar.h"
-# define FT_BZERO_INT32 1.0*0x80000000
 
 # define GET_COLUMN(OUT,NAME,TYPE) \
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/delstar/src/args.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/delstar/src/args.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/delstar/src/args.c	(revision 37403)
@@ -18,4 +18,6 @@
   fprintf (stderr, "  -image-details : list info about the deleted images (-dup-images only)\n");
   fprintf (stderr, "  -image-only : only examine the image table (changes are NOT saved; -dup-images only)\n");
+  fprintf (stderr, "  -image-only-force : modify only the image table (-dup-images only)\n");
+  fprintf (stderr, "  -image-by-obstime : use date/time and photcode (not externID) to find duplicates\n");
   fprintf (stderr, "  -region Rmin Rmax Dmin Dmax : apply changes to this part of the sky\n");
   
@@ -68,4 +70,10 @@
   if ((N = get_argument (argc, argv, "-image-details"))) {
     IMAGE_DETAILS = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+
+  IMAGE_DUPLICATES_BY_OBSTIME = FALSE;
+  if ((N = get_argument (argc, argv, "-image-by-obstime"))) {
+    IMAGE_DUPLICATES_BY_OBSTIME = TRUE;
     remove_argument (N, &argc, argv);
   }
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/delstar/src/delete_duplicate_images.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/delstar/src/delete_duplicate_images.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/delstar/src/delete_duplicate_images.c	(revision 37403)
@@ -1,3 +1,8 @@
 # include "delstar.h"
+
+IndexArray *find_duplicates_obstime (Image *image, off_t Nimage, off_t *Nduplicates);
+off_t find_obstime_range (Image *image, off_t Nimage, off_t firstEntry);
+void sort_by_obstime (e_time *T, short *P, off_t *I, off_t N);
+void sort_by_photcode (short *P, off_t *I, off_t N);
 
 // this function identifies the images to be deleted based on duplication of the 
@@ -18,5 +23,11 @@
 
   off_t Nduplicates = 0;
-  IndexArray *imageID = find_duplicates (image, Nimage, &Nduplicates);
+  IndexArray *imageID = NULL;
+
+  if (IMAGE_DUPLICATES_BY_OBSTIME) {
+    imageID = find_duplicates_obstime (image, Nimage, &Nduplicates);
+  } else {
+    imageID = find_duplicates (image, Nimage, &Nduplicates);
+  }
 
   if (Nduplicates == 0) {
@@ -494,4 +505,209 @@
 }
 
+// sort by increasing obstime
+void sort_by_obstime (e_time *T, short *P, off_t *I, off_t N) {
+
+# define SWAPFUNC(A,B){ e_time tmpT; short tmpP; off_t tmpI; \
+  tmpT = T[A]; T[A] = T[B]; T[B] = tmpT; \
+  tmpP = P[A]; P[A] = P[B]; P[B] = tmpP; \
+  tmpI = I[A]; I[A] = I[B]; I[B] = tmpI; \
+}
+# define COMPARE(A,B)(T[A] < T[B])
+
+  OHANA_SORT (N, COMPARE, SWAPFUNC);
+
+# undef SWAPFUNC
+# undef COMPARE
+
+}
+
+// sort by increasing photcode
+void sort_by_photcode (short *P, off_t *I, off_t N) {
+
+# define SWAPFUNC(A,B){ short tmpP; off_t tmpI; \
+  tmpP = P[A]; P[A] = P[B]; P[B] = tmpP; \
+  tmpI = I[A]; I[A] = I[B]; I[B] = tmpI; \
+}
+# define COMPARE(A,B)(P[A] < P[B])
+
+  OHANA_SORT (N, COMPARE, SWAPFUNC);
+
+# undef SWAPFUNC
+# undef COMPARE
+
+}
+
+static e_time *obstime  = NULL;
+static short  *photcode = NULL;
+static off_t  *primary  = NULL;
+static off_t  *idx      = NULL;
+static char   *keep     = NULL;
+
+static short  *photcode_subset = NULL;
+static off_t  *idx_subset      = NULL;
+
+static off_t Nsubset = 0;
+static off_t NSUBSET = 300;
+
+off_t find_obstime_range (Image *image, off_t Nimage, off_t firstEntry) {
+
+  Nsubset = 0;
+
+  // find all entries with the same obstime:
+  e_time firstTime = obstime[firstEntry];
+
+  idx_subset[Nsubset] = idx[firstEntry];
+  photcode_subset[Nsubset] = photcode[firstEntry];
+  Nsubset++;
+
+  off_t i = firstEntry + Nsubset;
+  while ((i < Nimage) && (obstime[i] == firstTime)) {
+    idx_subset[Nsubset] = idx[i];
+    photcode_subset[Nsubset] = photcode[i];
+    Nsubset++;
+    i++;
+    if (Nsubset >= NSUBSET) {
+      NSUBSET += 1000;
+      REALLOCATE (photcode_subset, short, NSUBSET);
+      REALLOCATE (idx_subset, off_t, NSUBSET);
+    }
+  }      
+
+  sort_by_photcode (photcode_subset, idx_subset, Nsubset);
+
+  return i;
+}
+
+// alternative version to find duplicates based on obstime and photcode
+IndexArray *find_duplicates_obstime (Image *image, off_t Nimage, off_t *Nduplicates) {
+
+  if (Nimage < 1) return NULL;
+
+  // how to find duplicates:
+  // generate a set of arrays (idx, obstime, photcode, keep)
+  // sort the arrays by obstime
+  // loop over obstime.  
+  // for a given new obstime, scan through the entries with the same value
+  // create a sub-array of photcodes, idx
+  // sort by photcode
+  // loop over entries
+  // find matching photcodes
+  // mark duplicate enties
+
+  ALLOCATE (obstime, e_time, Nimage);
+  ALLOCATE (photcode, short, Nimage);
+  ALLOCATE (primary, off_t, Nimage);
+  ALLOCATE (idx, off_t, Nimage);
+  ALLOCATE (keep, char, Nimage);
+
+  off_t i;
+
+  INITTIME;
+
+  // skip entries with photcode == 0?
+  for (i = 0; i < Nimage; i++) {
+    idx[i] = i;
+    primary[i] = -1; // only duplicates get a value for primary
+    keep[i] = TRUE;
+    obstime[i] = image[i].tzero;
+    photcode[i] = image[i].photcode;
+  }
+  MARKTIME("  generate index arrays: %f sec\n", dtime);
+
+  // sort the 4 arrays
+  sort_by_obstime (obstime, photcode, idx, Nimage);
+  MARKTIME("  sort index arrays: %f sec\n", dtime);
+
+  // image[idx[i]].tzero = obstime[i]
+  // keep[i] -> keep image[i] ('keep' is NOT resorted)
+
+  // allocate arrays to store the subsets (these are global static)
+  // These get reallocated if necessary in find_obstime_range()
+  ALLOCATE (photcode_subset, short, NSUBSET);
+  ALLOCATE (idx_subset, off_t, NSUBSET);
+
+  // entries of idx_subset correspond to the original image sequence:
+  // image[idx_subset[i]].tzero = obstime[i]
+
+  off_t firstEntry = 0;
+  off_t nextEntry = 0;
+  
+  while (nextEntry < Nimage) {
+    if (firstEntry >= Nimage) {
+      fprintf (stderr, "error, too far?\n");
+    }
+    
+    // generate photcode_subset, idx_subset in order of photcode for this unique obstime[firstEntry]
+    // returned value is the first value of the next entry
+    nextEntry = find_obstime_range (image, Nimage, firstEntry);
+    
+    // step through the photcodes and find duplicates
+    int j;
+    int firstCodeEntry = 0;
+    short firstCode = photcode_subset[firstCodeEntry];
+    for (j = 1; j < Nsubset; j++) {
+      if (photcode_subset[j] == firstCode) {
+	// mark as duplicate
+	off_t dupIndex = idx_subset[j];
+	keep[dupIndex] = FALSE;
+	primary[dupIndex] = idx_subset[firstCodeEntry];
+      } else {
+	// new value of photcode, call if the first one
+	firstCodeEntry = j;
+	firstCode = photcode_subset[firstCodeEntry];
+      }
+    }
+    firstEntry = nextEntry;
+  }
+  MARKTIME("  find duplicates: %f sec\n", dtime);
+
+  IndexArray *imageID = make_index_array (image, Nimage, IMAGE_ID);
+  MARKTIME("  make index array: %f sec\n", dtime);
+
+  // set imageID->value to TRUE for images we want to delete
+  off_t Ndup = 0;
+  for (i = 0; i < Nimage; i++) {
+    if (keep[i]) continue;
+    off_t Ni = image[i].imageID - imageID->minID;
+    myAssert (Ni >= 0, "oops");
+    myAssert (Ni < imageID->range, "oops");
+    imageID->value[Ni] = TRUE;
+    Ndup ++;
+  }
+  MARKTIME("  mark duplicates: %f sec\n", dtime);
+
+  for (i = 0; IMAGE_DETAILS && (i < Nimage); i++) {
+    off_t Ni = image[i].imageID - imageID->minID;
+    if (!imageID->value[Ni]) continue;
+    
+    char *date = NULL;
+    date = ohana_sec_to_date (image[i].tzero);
+    fprintf (stderr, "delete image : (" OFF_T_FMT "), extID = %d : %30s : %20s %5d  ==  ", i, image[i].externID, image[i].name, date, image[i].photcode);
+    free (date);
+
+    off_t myPrimary = primary[i];
+    if (myPrimary < 0) {
+      fprintf (stderr, "ERROR: this should never happen\n");
+      abort();
+    }
+    date = ohana_sec_to_date (image[myPrimary].tzero);
+    fprintf (stderr, "parent image : (" OFF_T_FMT "), extID = %d : %30s : %20s %5d\n", myPrimary, image[myPrimary].externID, image[myPrimary].name, date, image[myPrimary].photcode);
+    free (date);
+  }
+
+  *Nduplicates = Ndup;
+
+  free (photcode_subset);
+  free (idx_subset);
+  
+  free (obstime);
+  free (photcode);
+  free (primary);
+  free (idx);
+  free (keep);
+
+  return imageID;;
+}
+
 // find the min & max values of the given ID (externID or imageID)
 // construct an empty array with length needed to fit IDs
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/delstar/src/delete_fix_LAP_edges.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/delstar/src/delete_fix_LAP_edges.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/delstar/src/delete_fix_LAP_edges.c	(revision 37403)
@@ -206,4 +206,6 @@
   double Dgapmin = Dmin + dD;
   double Dgapmax = Dmax - dD;
+  
+  float cosDec = cos(RAD_DEG * 0.5 * (Dmin + Dmax));
 
   // XXX should deal with pole, but not yet...
@@ -218,7 +220,9 @@
     float maxOff = 0.0;
     m = catalog[0].average[i].measureOffset;
+
     for (j = 0; j < catalog[0].average[i].Nmeasure; j++) {
-      float dRoff = catalog[0].measure[m+j].dR * cos(RAD_DEG * 0.5 * (Dmin + Dmax));
-      float dDoff = catalog[0].measure[m+j].dD;
+
+      float dRoff = dvoOffsetR(&catalog[0].measure[m+j], &catalog[0].average[i])*cosDec;
+      float dDoff = dvoOffsetD(&catalog[0].measure[m+j], &catalog[0].average[i]);
       float dOff = hypot (dRoff, dDoff);
       maxOff = MAX (maxOff, dOff);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvolens/Makefile
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvolens/Makefile	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvolens/Makefile	(revision 37403)
@@ -0,0 +1,52 @@
+default: dvolens dvolens_client
+help:
+	@echo "make options: dvolens (default)"
+
+include ../../Makefile.System
+HOME    =       $(ROOT)/src/dvolens
+BIN	=	$(HOME)/bin
+LIB	=	$(HOME)/lib
+SRC	=	$(HOME)/src
+MAN	=	$(HOME)/doc
+INC	= 	$(HOME)/include
+include ../../Makefile.Common
+
+# programs may add their own internal requirements here
+FULL_CFLAGS   = $(BASE_CFLAGS)
+FULL_CPPFLAGS = $(BASE_CPPFLAGS)
+FULL_LDFLAGS  = -lkapa -ldvo -lFITS -lohana $(BASE_LDFLAGS)
+
+dvolens: $(BIN)/dvolens.$(ARCH)
+dvolens_client: $(BIN)/dvolens_client.$(ARCH)
+
+install: $(DESTBIN)/dvolens $(DESTBIN)/dvolens_client
+
+DVOLENS = \
+$(SRC)/ConfigInit.$(ARCH).o	 \
+$(SRC)/SetSignals.$(ARCH).o 	 \
+$(SRC)/Shutdown.$(ARCH).o 	 \
+$(SRC)/args.$(ARCH).o		 \
+$(SRC)/help.$(ARCH).o		 \
+$(SRC)/initialize.$(ARCH).o	 \
+$(SRC)/update_objects.$(ARCH).o	 \
+$(SRC)/update_objects_catalog.$(ARCH).o	 \
+$(SRC)/client_logger.$(ARCH).o	 \
+$(SRC)/dvolens.$(ARCH).o
+
+$(DVOLENS): $(INC)/dvolens.h
+$(BIN)/dvolens.$(ARCH): $(DVOLENS)
+
+DVOLENS_CLIENT = \
+$(SRC)/ConfigInit.$(ARCH).o	 \
+$(SRC)/SetSignals.$(ARCH).o 	 \
+$(SRC)/Shutdown.$(ARCH).o 	 \
+$(SRC)/args.$(ARCH).o		 \
+$(SRC)/help.$(ARCH).o		 \
+$(SRC)/initialize.$(ARCH).o	 \
+$(SRC)/update_objects.$(ARCH).o	 \
+$(SRC)/update_objects_catalog.$(ARCH).o	 \
+$(SRC)/client_logger.$(ARCH).o	 \
+$(SRC)/dvolens_client.$(ARCH).o
+
+$(DVOLENS_CLIENT): $(INC)/dvolens.h
+$(BIN)/dvolens_client.$(ARCH): $(DVOLENS_CLIENT)
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvolens/include/dvolens.h
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvolens/include/dvolens.h	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvolens/include/dvolens.h	(revision 37403)
@@ -0,0 +1,64 @@
+# include <ohana.h>
+# include <dvo.h>
+# include <kapa.h>
+# include <signal.h>
+# include <pthread.h>
+
+typedef enum {
+  MODE_ERROR = 0,
+  MODE_UPDATE_OBJECTS,
+} DvoLensMode;
+
+/* global variables set in parameter file */
+# define DVO_MAX_PATH 1024
+char  *CATDIR;
+char   CATMODE[16];    /* raw, mef, split, mysql */
+char   CATFORMAT[16];  /* internal, elixir, loneos, panstarrs */
+
+int    HOST_ID;
+char  *HOSTDIR;
+
+int    PARALLEL;
+int    PARALLEL_MANUAL;
+int    PARALLEL_SERIAL;
+
+int    VERBOSE;
+int    VERBOSE2;
+int    UPDATE;
+int    NTHREADS;
+
+DvoLensMode MODE;
+
+SkyRegion UserPatch;
+char     *UserCatalog;
+
+/*** dvolens prototypes ***/
+void          ConfigInit              PROTO((int *argc, char **argv));
+void          GetConfig               PROTO((char *config, char *field, char *format, int N, void *ptr));
+
+DvoLensMode   args                    PROTO((int argc, char **argv));
+int           args_client             PROTO((int argc, char **argv));
+
+DvoLensMode   initialize              PROTO((int argc, char **argv));
+void          initialize_client       PROTO((int argc, char **argv));
+
+void 	      dvolens_usage           PROTO((void));
+void 	      dvolens_help            PROTO((int argc, char **argv));
+
+void 	      dvolens_client_usage    PROTO((void));
+void 	      dvolens_client_help     PROTO((int argc, char **argv));
+
+int           Shutdown                PROTO((char *format, ...) OHANA_FORMAT(printf, 1, 2)) ;
+void          TrapSignal              PROTO((int sig));
+void          SetProtect              PROTO((int mode));
+int           SetSignals              PROTO((void));
+
+int           main                    PROTO((int argc, char **argv));
+
+void          update_objects          PROTO(());
+int           update_objects_parallel PROTO((SkyList *sky));
+int           update_objects_catalog  PROTO((Catalog *catalog));
+
+int  	      client_logger_init      PROTO((char *dirname));
+int  	      client_logger_message   PROTO((char *format,...));
+
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvolens/src/ConfigInit.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvolens/src/ConfigInit.c	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvolens/src/ConfigInit.c	(revision 37403)
@@ -0,0 +1,50 @@
+# include "dvolens.h"
+
+void ConfigInit (int *argc, char **argv) {
+
+  char CatdirPhotcodeFile[256];
+
+  /*** load configuration info ***/
+  char *file = SelectConfigFile (argc, argv, "ptolemy");
+  char *config = LoadConfigFile (file);
+  if (!config) {
+    fprintf (stderr, "ERROR: can't find configuration file %s\n", file);
+    if (file) free (file);
+    exit (0);
+  }
+  if (VERBOSE) fprintf (stderr, "loaded config file: %s\n", file);
+
+  // force CATDIR to be absolute (so parallel mode will work)
+  char *tmpcatdir = NULL;
+  ALLOCATE (tmpcatdir, char, DVO_MAX_PATH);
+  GetConfig (config, "CATDIR",                 "%s",  0, tmpcatdir);
+  CATDIR = abspath (tmpcatdir, DVO_MAX_PATH);
+  free (tmpcatdir);
+
+  ScanConfig (config, "CATMODE",                "%s",  0, CATMODE);
+  ScanConfig (config, "CATFORMAT",              "%s",  0, CATFORMAT);
+
+  if (*CATMODE == 0) strcpy (CATMODE, "RAW");
+  if (*CATFORMAT == 0) strcpy (CATFORMAT, "ELIXIR");
+
+  sprintf (CatdirPhotcodeFile, "%s/Photcodes.dat", CATDIR);
+  if (!LoadPhotcodes (CatdirPhotcodeFile, NULL, FALSE)) {
+    fprintf (stderr, "error loading photcode table %s\n", CatdirPhotcodeFile);
+    exit (1);
+  }
+
+  free (config);
+  free (file);
+}
+
+void GetConfig (char *config, char *field, char *format, int N, void *ptr) {
+
+  char *status;
+
+  status = ScanConfig (config, field, format, N, ptr);
+  if (status == NULL) {
+    fprintf (stderr, "error in config, cannot find %s\n", field);
+    exit (1);
+  }
+  return;
+}
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvolens/src/SetSignals.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvolens/src/SetSignals.c	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvolens/src/SetSignals.c	(revision 37403)
@@ -0,0 +1,122 @@
+# include "dvolens.h"
+
+static int Protect = FALSE;
+static int Trapped = FALSE;
+
+void TrapSignal (int sig) {
+    fprintf (stderr, "trapped signal %d\n", sig);
+    if (sig == 11) {
+      fprintf (stderr, "seg fault\n");
+      exit (1);
+    }
+    if (Protect) {
+      Trapped = TRUE;
+      fprintf (stderr, "blocking until protected sections are clear\n");
+      return;
+    }
+    Shutdown ("halted by signal (trapped)");
+}    
+
+void SetProtect (int mode) {
+  Protect = mode;
+  if (Trapped && !Protect) Shutdown ("halted by signal (protect)");
+}
+
+int SetSignals () {
+
+  int i;
+
+  /* disable almost all signal interrupts */
+  for (i = 0; i < 36; i++) {
+    switch (i) {
+      /* can't redirect these signals */
+    case SIGKILL:    /* kill -9: cannot be caught or ignored (POSIX.1-1990) */
+    case SIGSTOP:    /* SIGSTOP: cannot be caught or ignored (POSIX.1-1990) */
+      /* ignore these signals */
+    case SIGCHLD:    /* child halted: ignore (POSIX.1-1990) */
+    case SIGCONT:    /* continue - maintain this action (POSIX.1-1990) */
+    case SIGTSTP:    /* stop signal sent from tty - why ignore? (POSIX.1-1990) */
+    case SIGURG:     /* socket signal, ignore this (POSIX.1-2001) */
+# ifdef SIGPWR
+    case SIGPWR:     /* power failure - why ignore this? (Sys V) */
+# endif
+# ifdef SIGWINCH
+    case SIGWINCH:   /* window resized (4.3BSD) */
+# endif
+      break;
+      
+    default:
+      signal (i, TrapSignal);
+    }
+  }
+  return (TRUE);
+}
+/*
+
+       Signal     Value     Action   Comment
+       -------------------------------------------------------------------------
+       SIGHUP        1        A      Hangup detected on controlling terminal
+                                     or death of controlling process
+       SIGINT        2        A      Interrupt from keyboard
+       SIGQUIT       3        A      Quit from keyboard
+       SIGILL        4        A      Illegal Instruction
+       SIGABRT       6        C      Abort signal from abort(3)
+       SIGFPE        8        C      Floating point exception
+       SIGKILL       9       AEF     Kill signal
+       SIGSEGV      11        C      Invalid memory reference
+       SIGPIPE      13        A      Broken pipe: write to pipe with no readers
+       SIGALRM      14        A      Timer signal from alarm(2)
+       SIGTERM      15        A      Termination signal
+       SIGUSR1   30,10,16     A      User-defined signal 1
+       SIGUSR2   31,12,17     A      User-defined signal 2
+       SIGCHLD   20,17,18     B      Child stopped or terminated
+       SIGCONT   19,18,25            Continue if stopped
+       SIGSTOP   17,19,23    DEF     Stop process
+       SIGTSTP   18,20,24     D      Stop typed at tty
+       SIGTTIN   21,21,26     D      tty input for background process
+       SIGTTOU   22,22,27     D      tty output for background process
+
+       Next various other signals.
+
+       Signal       Value     Action   Comment
+       ---------------------------------------------------------------------
+       SIGTRAP        5         CG     Trace/breakpoint trap
+       SIGIOT         6         CG     IOT trap. A synonym for SIGABRT
+       SIGEMT       7,-,7       G
+       SIGBUS      10,7,10      AG     Bus error
+       SIGSYS      12,-,12      G      Bad argument to routine (SVID)
+       SIGSTKFLT    -,16,-      AG     Stack fault on coprocessor
+       SIGURG      16,23,21     BG     Urgent condition on socket (4.2 BSD)
+       SIGIO       23,29,22     AG     I/O now possible (4.2 BSD)
+       SIGPOLL                  AG     A synonym for SIGIO (System V)
+       SIGCLD       -,-,18      G      A synonym for SIGCHLD
+       SIGXCPU     24,24,30     AG     CPU time limit exceeded (4.2 BSD)
+       SIGXFSZ     25,25,31     AG     File size limit exceeded (4.2 BSD)
+       SIGVTALRM   26,26,28     AG     Virtual alarm clock (4.2 BSD)
+       SIGPROF     27,27,29     AG     Profile alarm clock
+       SIGPWR      29,30,19     AG     Power failure (System V)
+       SIGINFO      29,-,-      G      A synonym for SIGPWR
+       SIGLOST      -,-,-       AG     File lock lost
+       SIGWINCH    28,28,20     BG     Window resize signal (4.3 BSD, Sun)
+       SIGUNUSED    -,31,-      AG     Unused signal
+       (Here - denotes that a signal is absent; there where three values are given, the first one is usually  valid  for  alpha  and
+       sparc,  the  middle  one  for i386 and ppc, the last one for mips. Signal 29 is SIGINFO / SIGPWR on an alpha but SIGLOST on a
+       sparc.)
+
+       The letters in the "Action" column have the following meanings:
+
+       A      Default action is to terminate the process.
+
+       B      Default action is to ignore the signal.
+
+       C      Default action is to dump core.
+
+       D      Default action is to stop the process.
+
+       E      Signal cannot be caught.
+
+       F      Signal cannot be ignored.
+
+       G      Not a POSIX.1 conformant signal.
+
+*/
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvolens/src/Shutdown.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvolens/src/Shutdown.c	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvolens/src/Shutdown.c	(revision 37403)
@@ -0,0 +1,19 @@
+# include "dvolens.h"
+
+int Shutdown (char *format, ...) {  
+  va_list argp;
+  char *formatplus;
+  
+  ALLOCATE (formatplus, char, strlen(format) + 2);
+  strcpy (formatplus, format);
+  strcat (formatplus, "\n");
+
+  va_start (argp, format);
+  vfprintf (stderr, formatplus, argp);
+  free (formatplus);
+  va_end (argp);
+
+  fprintf (stderr, "ERROR: dvolens halted\n");
+  exit (1);
+}
+
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvolens/src/args.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvolens/src/args.c	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvolens/src/args.c	(revision 37403)
@@ -0,0 +1,175 @@
+# include "dvolens.h"
+
+DvoLensMode args (int argc, char **argv) {
+
+  int N;
+
+  /* specify portion of the sky */
+  UserPatch.Rmin = 0;
+  UserPatch.Rmax = 360;
+  UserPatch.Dmin = -90;
+  UserPatch.Dmax = +90;
+  if ((N = get_argument (argc, argv, "-region"))) {
+    remove_argument (N, &argc, argv);
+    UserPatch.Rmin = atof (argv[N]);
+    remove_argument (N, &argc, argv);
+    UserPatch.Rmax = atof (argv[N]);
+    remove_argument (N, &argc, argv);
+    UserPatch.Dmin = atof (argv[N]);
+    remove_argument (N, &argc, argv);
+    UserPatch.Dmax = atof (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  /* specify region file by name (eg n0000/0000.00) */
+  UserCatalog = NULL;
+  if ((N = get_argument (argc, argv, "-catalog"))) {
+    remove_argument (N, &argc, argv);
+    UserCatalog = strcreate (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  VERBOSE = VERBOSE2 = FALSE;
+  if ((N = get_argument (argc, argv, "-v"))) {
+    VERBOSE = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+  if ((N = get_argument (argc, argv, "-vv"))) {
+    VERBOSE2 = VERBOSE = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+
+  NTHREADS = 0;
+  if ((N = get_argument (argc, argv, "-threads"))) {
+    remove_argument (N, &argc, argv);
+    NTHREADS = atof (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  // XXX for the moment, make this selection manual.  it needs to be automatic 
+  // based on the state of the SkyTable
+  HOST_ID = 0;
+  PARALLEL = FALSE;
+  if ((N = get_argument (argc, argv, "-parallel"))) {
+    PARALLEL = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+  // this is a test mode : rather than launching the remote jobs and waiting for completion,
+  // dvolens will simply list the remote command and wait for the user to signal completion
+  PARALLEL_MANUAL = FALSE;
+  if ((N = get_argument (argc, argv, "-parallel-manual"))) {
+    PARALLEL = TRUE; // -parallel-manual implies -parallel
+    PARALLEL_MANUAL = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+  // this is a test mode : rather than launching the dvolens_client jobs remotely, they are 
+  // run in serial via 'system'
+  PARALLEL_SERIAL = FALSE;
+  if ((N = get_argument (argc, argv, "-parallel-serial"))) {
+    if (PARALLEL_MANUAL) {
+      fprintf (stderr, "ERROR: cannot mix -parallel-manual and -parallel-serial\n");
+      exit (1);
+    }
+    PARALLEL = TRUE; // -parallel-serial implies -parallel
+    PARALLEL_SERIAL = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+
+  UPDATE = FALSE;
+  if ((N = get_argument (argc, argv, "-update"))) {
+    remove_argument (N, &argc, argv);
+    UPDATE = TRUE;
+  }
+
+  DvoLensMode mode = MODE_ERROR;
+  if ((N = get_argument (argc, argv, "-update-objects"))) {
+    remove_argument (N, &argc, argv);
+    mode = MODE_UPDATE_OBJECTS;
+  }
+
+  switch (mode) {
+    case MODE_UPDATE_OBJECTS:
+      if (argc != 1) dvolens_usage();
+      break;
+      
+    default:
+      fprintf (stderr, "no valid mode selected\n");
+      dvolens_usage();
+      break;
+  }
+  if (argc != 1) dvolens_usage ();
+
+  return mode;
+}
+
+int args_client (int argc, char **argv) {
+
+  int N;
+
+  // by definition, the client is not parallel 
+  PARALLEL = FALSE;
+  PARALLEL_MANUAL = FALSE;
+  PARALLEL_SERIAL = FALSE;
+
+  HOST_ID = 0;
+  if ((N = get_argument (argc, argv, "-hostID"))) {
+    remove_argument (N, &argc, argv);
+    HOST_ID = atoi (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+  if (!HOST_ID) dvolens_client_usage();
+
+  HOSTDIR = NULL;
+  if ((N = get_argument (argc, argv, "-hostdir"))) {
+    remove_argument (N, &argc, argv);
+    HOSTDIR = strcreate (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+  if (!HOSTDIR) dvolens_client_usage();
+
+  MODE = MODE_ERROR;
+  if ((N = get_argument (argc, argv, "-update-objects"))) {
+    MODE = MODE_UPDATE_OBJECTS;
+    remove_argument (N, &argc, argv);
+  }
+  if (!MODE) dvolens_client_usage();
+
+  /* specify portion of the sky */
+  UserPatch.Rmin = 0;
+  UserPatch.Rmax = 360;
+  UserPatch.Dmin = -90;
+  UserPatch.Dmax = +90;
+  if ((N = get_argument (argc, argv, "-region"))) {
+    remove_argument (N, &argc, argv);
+    UserPatch.Rmin = atof (argv[N]);
+    remove_argument (N, &argc, argv);
+    UserPatch.Rmax = atof (argv[N]);
+    remove_argument (N, &argc, argv);
+    UserPatch.Dmin = atof (argv[N]);
+    remove_argument (N, &argc, argv);
+    UserPatch.Dmax = atof (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  VERBOSE = VERBOSE2 = FALSE;
+  if ((N = get_argument (argc, argv, "-v"))) {
+    VERBOSE = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+  if ((N = get_argument (argc, argv, "-vv"))) {
+    VERBOSE2 = VERBOSE = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+
+  UPDATE = FALSE;
+  if ((N = get_argument (argc, argv, "-update"))) {
+    remove_argument (N, &argc, argv);
+    UPDATE = TRUE;
+  }
+
+  if ((MODE == MODE_UPDATE_OBJECTS)  && (argc == 1)) return TRUE;
+  if (argc != 2) dvolens_client_usage ();
+
+  return TRUE;
+}
+
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvolens/src/client_logger.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvolens/src/client_logger.c	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvolens/src/client_logger.c	(revision 37403)
@@ -0,0 +1,37 @@
+# include "dvolens.h"
+
+// I'm getting unlogged errors and failures.  I need a log ouput that the clients can
+// write independent of the master
+
+static FILE *logfile = NULL;
+int client_logger_init (char *dirname) {
+
+  char filename[DVO_MAX_PATH];
+
+  snprintf (filename, DVO_MAX_PATH, "%s/log.dvolens.XXXXXX", dirname);
+    
+  int fd = mkstemp (filename);
+  if (fd == -1) {
+    fprintf (stderr, "failed to open client logger %s, exiting\n", filename);
+    exit (50);
+  }
+
+  logfile = fdopen (fd, "w");
+  if (!logfile)  {
+    fprintf (stderr, "failed to fdopen client logger, exiting\n");
+    exit (51);
+  }
+  return TRUE;
+}
+
+int client_logger_message (char *format,...) {
+
+  va_list argp;
+
+  va_start (argp, format);
+  vfprintf (logfile, format, argp);
+  va_end (argp);
+
+  fflush (logfile);
+  return TRUE;
+}
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvolens/src/dvolens.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvolens/src/dvolens.c	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvolens/src/dvolens.c	(revision 37403)
@@ -0,0 +1,20 @@
+# include "dvolens.h"
+
+int main (int argc, char **argv) {
+
+  // get configuration info, args
+  DvoLensMode mode = initialize (argc, argv);
+  if (!mode) exit (2);
+
+  switch (mode) {
+    case MODE_UPDATE_OBJECTS:
+      update_objects ();
+      exit (0);
+
+    default:
+      fprintf (stderr, "ERROR: no valid dvolens mode chosen\n");
+      exit (2);
+  }
+  fprintf (stderr, "IMPOSSIBLE: skipped out of switch?\n");
+  exit (1);
+}
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvolens/src/dvolens_client.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvolens/src/dvolens_client.c	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvolens/src/dvolens_client.c	(revision 37403)
@@ -0,0 +1,28 @@
+# include "dvolens.h"
+
+// dvolens_client is run on a remote host and is responsible for updating the catalogs
+// owned by that host.  
+
+// dvolens_client -update-objects : calculate mean lensing parameters
+
+int main (int argc, char **argv) {
+
+  // get configuration info, args, lockfile (set CATDIR, HOST_ID, HOSTDIR, etc) 
+  initialize_client (argc, argv);
+  client_logger_init (HOSTDIR);
+
+  switch (MODE) {
+    case MODE_UPDATE_OBJECTS:
+      client_logger_message ("start dvolens_client\n");
+      update_objects ();
+      client_logger_message ("updated objects\n");
+      break;
+
+    default:
+      fprintf (stderr, "ERROR: no valid dvolens mode chosen\n");
+      exit (2);
+  }
+  client_logger_message ("done with dvolens_client\n");
+
+  exit (0);
+}
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvolens/src/help.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvolens/src/help.c	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvolens/src/help.c	(revision 37403)
@@ -0,0 +1,57 @@
+# include "dvolens.h"
+
+void dvolens_usage (void) {
+  fprintf (stderr, "ERROR: USAGE: dvolens -update-objects\n");
+  fprintf (stderr, "  regions:    -region RA RA DEC DEC)\n");
+  fprintf (stderr, "       or:    -catalog (name)\n");
+  fprintf (stderr, "  use -h for more usage information\n");
+  exit (2);
+} 
+
+void dvolens_help (int argc, char **argv) {
+  /* check for help request */
+  if (get_argument (argc, argv, "-help")) goto show_help;
+  if (get_argument (argc, argv, "-h"))    goto show_help;
+  if (argc == 1) dvolens_usage();
+  return;
+
+show_help:
+  fprintf (stderr, "ERROR: USAGE: dvolens -update-objects\n");
+  fprintf (stderr, "  regions:    -region RA RA DEC DEC)\n");
+  fprintf (stderr, "       or:    -catalog (name)\n");
+  fprintf (stderr, "  options: \n");
+  fprintf (stderr, "  -time (start) (stop)\n");
+  fprintf (stderr, "  -v : verbose output\n");
+  fprintf (stderr, "  -vv : more verbose output\n");
+  fprintf (stderr, "  -statmode (mode)\n");
+  fprintf (stderr, "  -n (nloop)\n");
+  fprintf (stderr, "  -reset\n");
+  fprintf (stderr, "  -update\n");
+  fprintf (stderr, "  \n");
+  exit (2);
+}
+
+void dvolens_client_usage (void) {
+  fprintf (stderr, "ERROR: USAGE: dvolens -update-objects -hostID (hostID) -hostdir (hostdir) [options]\n");
+  fprintf (stderr, "  use -h for more usage information\n");
+  exit (2);
+} 
+
+void dvolens_client_help (int argc, char **argv) {
+
+  /* check for help request */
+  if (get_argument (argc, argv, "-help")) goto show_help;
+  if (get_argument (argc, argv, "-h"))    goto show_help;
+  if (argc == 1) dvolens_client_usage();
+  return;
+
+show_help:
+  fprintf (stderr, "USAGE: dvolens_client -update-objects  : determine average magnitudes for objects\n\n");
+  fprintf (stderr, "       db info : -hostID (hostID) -hostdir (hostdir) -catdir (catdir)\n");
+  fprintf (stderr, "other options:\n");
+  fprintf (stderr, "  -v  : verbose output\n");
+  fprintf (stderr, "  -vv : extra verbose output\n");
+  fprintf (stderr, "  \n");
+  exit (2);
+}
+
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvolens/src/initialize.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvolens/src/initialize.c	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvolens/src/initialize.c	(revision 37403)
@@ -0,0 +1,23 @@
+# include "dvolens.h"
+
+// dvolens has the following modes:
+// * -update-objects
+
+DvoLensMode initialize (int argc, char **argv) {
+
+  dvolens_help (argc, argv);
+  ConfigInit (&argc, argv);
+  DvoLensMode mode = args (argc, argv);
+  if (!mode) exit (2);
+
+  return mode;
+}
+
+void initialize_client (int argc, char **argv) {
+
+  // XXX need to determine which globals can affect relphot_client in either mode and pass appropriately
+
+  dvolens_client_help (argc, argv);
+  ConfigInit (&argc, argv);
+  args_client (argc, argv);
+}
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvolens/src/update_objects.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvolens/src/update_objects.c	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvolens/src/update_objects.c	(revision 37403)
@@ -0,0 +1,193 @@
+# include "dvolens.h"
+
+# define DEBUG 1
+
+# define TIMESTAMP(TIME){				\
+  gettimeofday (&stopTimer, (void *) NULL);		\
+  double dtime = DTIME (stopTimer, startTimer);		\
+  TIME += dtime;					\
+  gettimeofday (&startTimer, (void *) NULL); }
+
+void update_objects () {
+
+  int i;
+  int status;
+  struct stat filestat;
+  Catalog catalog;
+
+  double time1 = 0.0;
+  double time2 = 0.0;
+  double time3 = 0.0;
+  double time4 = 0.0;
+
+  // load the current sky table (layout of all SkyRegions) 
+  SkyTable *sky = SkyTableLoadOptimal (CATDIR, NULL, NULL, FALSE, 0, VERBOSE);
+  SkyTableSetFilenames (sky, CATDIR, "cpt");
+  
+  // determine the populated SkyRegions overlapping the requested area (default depth)
+  SkyList *skylist = SkyListByPatch (sky, -1, &UserPatch);
+
+  // XXX need to decide how to determine PARALLEL mode...
+  // in parallel mode, master: PARALLEL is true and HOST_ID == 0, client: PARALLEL is false, HOST_ID != 0
+  // in non-parallel mode, master: PARALLEL is false and HOST_ID == 0
+  if (PARALLEL && !HOST_ID) {
+    update_objects_parallel (skylist);
+    return;
+  }
+
+  if (VERBOSE) fprintf (stderr, "re-loading catalog data\n");
+
+  /* load data from each region file */
+  for (i = 0; i < skylist[0].Nregions; i++) {
+
+    // does this host ID match the desired location for the table?
+    if (!HostTableTestHost(skylist[0].regions[i], HOST_ID)) continue;
+
+    INITTIME;
+
+    // set up the basic catalog info
+    char hostfile[1024];
+    snprintf (hostfile, 1024, "%s/%s.cpt", HOSTDIR, skylist[0].regions[i]->name);
+    catalog.filename = HOST_ID ? hostfile : skylist[0].filename[i];
+
+    // only update existing db tables
+    status = stat (catalog.filename, &filestat);
+    if ((status == -1) && (errno == ENOENT)) {
+      if (VERBOSE) fprintf (stderr, "no file %s, skipping\n", catalog.filename);
+      continue;
+    }
+    TIMESTAMP(time1);
+
+    catalog.catformat = dvo_catalog_catformat (CATFORMAT);    // set the default catformat from config data
+    catalog.catmode   = dvo_catalog_catmode (CATMODE);        // set the default catmode from config data
+    catalog.catflags  = LOAD_AVES | LOAD_MEAS | LOAD_MISS | LOAD_SECF | LOAD_LENSING | LOAD_LENSOBJ;
+    catalog.Nsecfilt  = GetPhotcodeNsecfilt ();               // set the desired number in case we need to create the catalog
+
+    if (!dvo_catalog_open (&catalog, skylist[0].regions[i], VERBOSE, "w")) {
+      fprintf (stderr, "ERROR: failure reading catalog %s\n", catalog.filename);
+      exit (1);
+    }
+    if (VERBOSE && (catalog.Naves_disk == 0)) {
+	fprintf (stderr, "no data in %s, skipping\n", catalog.filename);
+	dvo_catalog_unlock (&catalog);
+	dvo_catalog_free (&catalog);
+	continue;
+    }
+    TIMESTAMP(time2);
+
+    update_objects_catalog (&catalog);
+    TIMESTAMP(time3);
+
+    struct timeval now;
+    gettimeofday (&now, (void *) NULL);
+    char *moddate = ohana_sec_to_date (now.tv_sec);
+    gfits_modify (&catalog.header, "DVOLENS", "%s", 1, moddate);      
+    free (moddate);
+
+    if (!UPDATE) {
+      dvo_catalog_unlock (&catalog);
+      dvo_catalog_free (&catalog);
+      continue;
+    }
+
+    SetProtect (TRUE);
+    dvo_catalog_save (&catalog, VERBOSE); 
+    dvo_catalog_unlock (&catalog);
+    SetProtect (FALSE);
+
+    dvo_catalog_free (&catalog);
+    TIMESTAMP(time4);
+
+    if (HOST_ID) {
+      client_logger_message ("updated catalog file %s\n", catalog.filename);
+    }
+  }
+
+  fprintf (stderr, "time step 1  %10.3f sec : find catalog\n", time1);
+  fprintf (stderr, "time step 2  %10.3f sec : load catalog\n", time2);
+  fprintf (stderr, "time step 3  %10.3f sec : update catalog\n", time3);
+  fprintf (stderr, "time step 4  %10.3f sec : save catalog\n", time4);
+}
+
+int update_objects_parallel (SkyList *sky) {
+
+  // now launch the dvolens_client jobs to the parallel hosts
+
+  // load the list of hosts
+  HostTable *table = HostTableLoad (CATDIR, sky->hosts);
+  if (!table) {
+    fprintf (stderr, "ERROR: problem with parallel host table\n");
+    exit (2);
+  }
+
+  int i, j;
+  for (i = 0; i < table->Nhosts; i++) {
+
+    if (sky->Nregions < table->Nhosts) {
+      // do any of the regions want this host?
+      int wantThisHost = FALSE;
+      for (j = 0; j < sky->Nregions; j++) {
+	if (HostTableTestHost (sky->regions[j], table->hosts[i].hostID)) {
+	  wantThisHost = TRUE;
+	  break;
+	}
+      }
+      if (!wantThisHost) {
+	// fprintf (stderr, "skip host %s\n", table->hosts[i].hostname);
+	continue;
+      }
+    }
+
+    // ensure that the paths are absolute path names
+    char *tmppath = abspath (table->hosts[i].pathname, DVO_MAX_PATH);
+    free (table->hosts[i].pathname);
+    table->hosts[i].pathname = tmppath;
+
+    char command[1024];
+    snprintf (command, 1024, "dvolens_client -update-objects -hostID %d -D CATDIR %s -hostdir %s -region %f %f %f %f", 
+	      table->hosts[i].hostID, CATDIR, table->hosts[i].pathname, 
+	      UserPatch.Rmin, UserPatch.Rmax, UserPatch.Dmin, UserPatch.Dmax);
+
+    // options & configs which affect dvolens_client -update-catalogs
+    // VERBOSE, VERBOSE2, UPDATE
+    
+    char tmpline[1024];
+    if (VERBOSE)          { snprintf (tmpline, 1024, "%s -v",           	command);                    			  strcpy (command, tmpline); }
+    if (VERBOSE2)         { snprintf (tmpline, 1024, "%s -vv",          	command); 		     			  strcpy (command, tmpline); }
+    if (UPDATE)           { snprintf (tmpline, 1024, "%s -update",       	command); 		     			  strcpy (command, tmpline); }
+
+    fprintf (stderr, "command: %s\n", command);
+
+    if (PARALLEL_MANUAL) continue;
+
+    if (PARALLEL_SERIAL) {
+      int status = system (command);
+      if (status) {
+	fprintf (stderr, "ERROR running dvolens_client\n");
+	exit (2);
+      }
+    } else {
+      // launch the job on the remote machine (no handshake)
+      int errorInfo = 0;
+      int pid = rconnect ("ssh", table->hosts[i].hostname, command, table->hosts[i].stdio, &errorInfo, FALSE);
+      if (!pid) {
+	if (DEBUG) fprintf (stderr, "failure to start %s (error %d)\n", table->hosts[i].hostname, errorInfo);
+	exit (1);
+      }
+      table->hosts[i].pid = pid; // save for future reference
+    }
+  }
+
+  if (PARALLEL_MANUAL) {
+    fprintf (stderr, "run the dvolens_client commands above.  when these are done, hit return\n");
+    getchar();
+  } 
+  if (!PARALLEL_MANUAL && !PARALLEL_SERIAL) {
+    int status = HostTableWaitJobsGetIO (table, __FILE__, __LINE__, VERBOSE);
+    if (!status) {
+      fprintf (stderr, "at least one remote client job failed to load data, exiting\n");
+      exit (3);
+    }
+  }
+  return (TRUE);
+}      
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvolens/src/update_objects_catalog.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvolens/src/update_objects_catalog.c	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvolens/src/update_objects_catalog.c	(revision 37403)
@@ -0,0 +1,167 @@
+# include "dvolens.h"
+
+int update_objects_catalog (Catalog *catalog) {
+
+  off_t i, j, Lj, Mj;
+
+  if (VERBOSE2) fprintf (stderr, "lensobj catalog %d : "OFF_T_FMT" ave, "OFF_T_FMT" meas, "OFF_T_FMT" lensing\n", 
+			 catalog->catID, catalog->Naverage, catalog->Nmeasure, catalog->Nlensing);
+
+  // I am making this measurement per filter
+  int Nsecfilt = GetPhotcodeNsecfilt ();
+  
+  // I think we have already allocated lensobj
+  REALLOCATE (catalog->lensobj, Lensobj, catalog->Naverage * Nsecfilt);
+
+  // Nlensobj tracks how many lensobj entries have I actually generated so far for this
+  // catalog This is not necessarily 1-to-1 with secfilt entries, but any average entry
+  // will either have 0 or Nsecfilt lensobj entries
+  int Nlensobj = 0;
+
+  for (i = 0; i < catalog->Naverage; i++) {
+    Average *average = &catalog->average[i];
+    if (average->Nlensing == 0) continue;
+
+    // NOTE Nlensobj increments by Nsecfilt each time
+    Lensobj *lensobj = &catalog->lensobj[Nlensobj];
+    for (j = 0; j < Nsecfilt; j++) {
+      dvo_lensobj_init (&lensobj[j], TRUE); // init accumulated values to 0
+    }
+
+    // reset the average values
+
+    off_t Loff = average->lensingOffset;
+    off_t Moff = average->measureOffset;
+
+    // loop over the lensing measurements.  for each one, I need to find the corresponding measurement (make an index in lensing?)
+    for (Lj = 0; Lj < average->Nlensing; Lj++) {
+      
+      // find the corresponding measure
+      Lensing *lensing = &catalog->lensing[Loff + Lj];
+      if (!isfinite(lensing->X11_sm_obj)) continue;
+
+      Measure *measure = NULL;
+      int found = FALSE;
+      for (Mj = 0; !found && (Mj < average->Nmeasure); Mj++) {
+	measure = &catalog->measure[Moff + Mj];
+	if (measure->imageID != lensing->imageID) continue;
+	found = TRUE;
+      }
+      if (!found) {
+	fprintf (stderr, "error: cannot match measurement with lensing parameter\n");
+	fprintf (stderr, "objID: %d, catID: %d, detID: %d, imageID: %d, averef: %d\n",
+		 lensing->objID, lensing->catID, lensing->detID, lensing->imageID, lensing->averef); 
+	abort();
+      }
+      
+      // skip measurements that do not match the current photcode
+      PhotCode *code = GetPhotcodebyCode (measure->photcode);
+      myAssert (code, "missing photcode?");
+      myAssert (code->equiv > -1, "photcode not equivalent to secfilt?");
+      
+      int Nsec = GetPhotcodeNsec (code->equiv);
+      myAssert (Nsec > -1, "cannot find Nsec?");
+	
+      // if (measure->dbFlags & MEAS_BAD) SKIP_THIS_MEAS(Nbad); 
+      if (measure->psfQF < 0.85) continue; 
+      if (measure->psfQFperf < 0.85) continue; 
+      
+
+      lensobj[Nsec].X11_sm_obj += lensing->X11_sm_obj;
+      lensobj[Nsec].X12_sm_obj += lensing->X12_sm_obj;
+      lensobj[Nsec].X22_sm_obj += lensing->X22_sm_obj;
+      lensobj[Nsec]. E1_sm_obj += lensing-> E1_sm_obj;
+      lensobj[Nsec]. E2_sm_obj += lensing-> E2_sm_obj;
+
+      lensobj[Nsec].X11_sh_obj += lensing->X11_sh_obj;
+      lensobj[Nsec].X12_sh_obj += lensing->X12_sh_obj;
+      lensobj[Nsec].X22_sh_obj += lensing->X22_sh_obj;
+      lensobj[Nsec]. E1_sh_obj += lensing-> E1_sh_obj;
+      lensobj[Nsec]. E2_sh_obj += lensing-> E2_sh_obj;
+
+      lensobj[Nsec].X11_sm_psf += lensing->X11_sm_psf;
+      lensobj[Nsec].X12_sm_psf += lensing->X12_sm_psf;
+      lensobj[Nsec].X22_sm_psf += lensing->X22_sm_psf;
+      lensobj[Nsec]. E1_sm_psf += lensing-> E1_sm_psf;
+      lensobj[Nsec]. E2_sm_psf += lensing-> E2_sm_psf;
+
+      lensobj[Nsec].X11_sh_psf += lensing->X11_sh_psf;
+      lensobj[Nsec].X12_sh_psf += lensing->X12_sh_psf;
+      lensobj[Nsec].X22_sh_psf += lensing->X22_sh_psf;
+      lensobj[Nsec]. E1_sh_psf += lensing-> E1_sh_psf;
+      lensobj[Nsec]. E2_sh_psf += lensing-> E2_sh_psf;
+
+      lensobj[Nsec]. F_ApR5 += lensing-> F_ApR5;
+      lensobj[Nsec].dF_ApR5 += SQ(lensing->dF_ApR5);
+      lensobj[Nsec].sF_ApR5 += SQ(lensing->sF_ApR5);
+      lensobj[Nsec].fF_ApR5 += lensing->fF_ApR5;
+
+      lensobj[Nsec]. F_ApR6 += lensing-> F_ApR6;
+      lensobj[Nsec].dF_ApR6 += SQ(lensing->dF_ApR6);
+      lensobj[Nsec].sF_ApR6 += SQ(lensing->sF_ApR6);
+      lensobj[Nsec].fF_ApR6 += lensing->fF_ApR6;
+
+      lensobj[Nsec].Nmeas   ++;
+      lensobj[Nsec].photcode = code->equiv;
+      lensobj[Nsec].objID = lensing->objID;
+      lensobj[Nsec].catID = lensing->catID;
+    }
+    
+    for (j = 0; j < Nsecfilt; j++) {
+      if (!lensobj[j].Nmeas) {
+	dvo_lensobj_init (&lensobj[j], FALSE);
+	continue;
+      }
+      float Nmeas = lensobj[j].Nmeas;
+      lensobj[j].X11_sm_obj /= Nmeas;
+      lensobj[j].X12_sm_obj /= Nmeas;
+      lensobj[j].X22_sm_obj /= Nmeas;
+      lensobj[j]. E1_sm_obj /= Nmeas;
+      lensobj[j]. E2_sm_obj /= Nmeas;
+      lensobj[j].X11_sh_obj /= Nmeas;
+      lensobj[j].X12_sh_obj /= Nmeas;
+      lensobj[j].X22_sh_obj /= Nmeas;
+      lensobj[j]. E1_sh_obj /= Nmeas;
+      lensobj[j]. E2_sh_obj /= Nmeas;
+      lensobj[j].X11_sm_psf /= Nmeas;
+      lensobj[j].X12_sm_psf /= Nmeas;
+      lensobj[j].X22_sm_psf /= Nmeas;
+      lensobj[j]. E1_sm_psf /= Nmeas;
+      lensobj[j]. E2_sm_psf /= Nmeas;
+      lensobj[j].X11_sh_psf /= Nmeas;
+      lensobj[j].X12_sh_psf /= Nmeas;
+      lensobj[j].X22_sh_psf /= Nmeas;
+      lensobj[j]. E1_sh_psf /= Nmeas;
+      lensobj[j]. E2_sh_psf /= Nmeas;
+
+      lensobj[j]. F_ApR5 /= Nmeas;
+      lensobj[j].dF_ApR5 /= Nmeas;
+      lensobj[j].sF_ApR5 /= Nmeas;
+      lensobj[j].fF_ApR5 /= Nmeas;
+      lensobj[j]. F_ApR6 /= Nmeas;
+      lensobj[j].dF_ApR6 /= Nmeas;
+      lensobj[j].sF_ApR6 /= Nmeas;
+      lensobj[j].fF_ApR6 /= Nmeas;
+
+      lensobj[j].dF_ApR5 = sqrt(lensobj[j].dF_ApR5);
+      lensobj[j].sF_ApR5 = sqrt(lensobj[j].sF_ApR5);
+      lensobj[j].dF_ApR6 = sqrt(lensobj[j].dF_ApR6);
+      lensobj[j].sF_ApR6 = sqrt(lensobj[j].sF_ApR6);
+
+      // somewhere in here I should calculate the values of E1, E2, and gamma
+    }
+
+    average->Nlensobj = Nsecfilt;
+    average->lensobjOffset = Nlensobj;
+    Nlensobj += Nsecfilt;
+    // XVERB |= (catalog->average[j].objID == OBJ_ID_SRC) && (catalog->average[j].catID == CAT_ID_SRC);
+    // XVERB |= (catalog->average[j].objID == OBJ_ID_DST) && (catalog->average[j].catID == CAT_ID_DST);
+  }
+
+  catalog->Nlensobj = Nlensobj;
+  catalog->Nlensobj_disk = 0;
+  catalog->Nlensobj_off  = 0;
+  REALLOCATE (catalog->lensobj, Lensobj, Nlensobj);
+
+  return (TRUE);
+}
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/include/dvomerge.h
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/include/dvomerge.h	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/include/dvomerge.h	(revision 37403)
@@ -129,10 +129,16 @@
 int        merge_catalogs_old     PROTO((SkyRegion *region, Catalog *output, Catalog *input, double RADIUS, int *secflitMap));
 
+off_t 	  *build_measure_links    PROTO((Average *average, off_t Naverage, Measure *measure, off_t Nmeasure));
 off_t 	  *init_measure_links     PROTO((Average *average, off_t Naverage, Measure *measure, off_t Nmeasure));
+int   	   add_meas_link     	  PROTO((Average *average, off_t *next, off_t Nmeasure, off_t NMEASURE));
+Measure   *sort_measure     	  PROTO((Average *average, off_t Naverage, Measure *measure, off_t Nmeasure, off_t *next));
+
+off_t 	  *build_lensing_links    PROTO((Average *average, off_t Naverage, Lensing *lensing, off_t Nlensing));
+off_t 	  *init_lensing_links     PROTO((Average *average, off_t Naverage, Lensing *lensing, off_t Nlensing));
+int   	   add_lens_link     	  PROTO((Average *average, off_t *next, off_t Nlensing, off_t NLENSING));
+Lensing   *sort_lensing     	  PROTO((Average *average, off_t Naverage, Lensing *lensing, off_t Nlensing, off_t *next));
+
 off_t 	  *init_missing_links     PROTO((Average *average, off_t Naverage, Missing *missing, off_t Nmissing));
-off_t 	  *build_measure_links    PROTO((Average *average, off_t Naverage, Measure *measure, off_t Nmeasure));
-int   	   add_meas_link     	  PROTO((Average *average, off_t *next, off_t Nmeasure, off_t NMEASURE));
 int   	   add_miss_link     	  PROTO((Average *average, off_t *next, off_t Nmissing));
-Measure   *sort_measure     	  PROTO((Average *average, off_t Naverage, Measure *measure, off_t Nmeasure, off_t *next));
 Missing   *sort_missing     	  PROTO((Average *average, off_t Naverage, Missing *missing, off_t Nmissing, off_t *next_miss));
 
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/include/dvoverify.h
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/include/dvoverify.h	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/include/dvoverify.h	(revision 37403)
@@ -56,2 +56,5 @@
 int LoadImageIDs (char *catdir);
 int CheckImageID (Catalog *catalog);
+
+int SaveImageIDsSmall(char *filename);
+int LoadImageIDsSmall (char *filename);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/IDmapIO.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/IDmapIO.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/IDmapIO.c	(revision 37403)
@@ -27,6 +27,6 @@
   gfits_create_table_header (&theader, "BINTABLE", "IMAGE_ID_MAP");
 
-  gfits_define_bintable_column (&theader, "J", "OLD_IDS", "old image IDs", NULL, 1.0, 1.0*0x8000);
-  gfits_define_bintable_column (&theader, "J", "NEW_IDS", "new image IDs", NULL, 1.0, 1.0*0x8000);
+  gfits_define_bintable_column (&theader, "J", "OLD_IDS", "old image IDs", NULL, 1.0, FT_BZERO_INT32);
+  gfits_define_bintable_column (&theader, "J", "NEW_IDS", "new image IDs", NULL, 1.0, FT_BZERO_INT32);
 
   // generate the output array that carries the data
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/LoadCatalog.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/LoadCatalog.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/LoadCatalog.c	(revision 37403)
@@ -8,5 +8,5 @@
 
     // always load all of the data (if any exists)
-    catalog[0].catflags = LOAD_AVES | LOAD_MEAS | LOAD_MISS | LOAD_SECF;
+    catalog[0].catflags = LOAD_AVES | LOAD_MEAS | LOAD_MISS | LOAD_SECF | LOAD_LENSING | LOAD_LENSOBJ;
 
     catalog[0].catformat = dvo_catalog_catformat (CATFORMAT);  // set the default catformat from config data
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/build_links.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/build_links.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/build_links.c	(revision 37403)
@@ -1,3 +1,26 @@
 # include "dvomerge.h"
+
+/* 
+
+There are two modes for the measure table: sorted and unsorted. 
+
+In sorted mode, all measures associated with a given average are in a single block.  The block
+is pointed to by average->measureOffset and the range is average->Nmeasure
+
+In unsorted mode, it is not possible to go directly from average to measure without scanning.
+In this case, it is necessary to use the value measure->averef to find the corresponding
+average entry.  
+
+Note that average->measureOffset and measure->averef are only valid for a given load of the
+data: they refer to the sequence number in the data blocks.
+
+next_meas is a list of the equivalent sequence of the measure block as if it were sorted.
+
+to find the sequence of measurements for a given average:
+n_0 = average->measureOffset
+n_1 = next_meas[n_0]
+n_i = next_meas[n_i-1]
+
+*/
 
 /* build the initial links assuming the table is sorted, 
@@ -6,17 +29,17 @@
 
   off_t i, j, N;
-  off_t *next;
+  off_t *next_meas;
 
   N = 0;
 
-  ALLOCATE (next, off_t, Nmeasure);
+  ALLOCATE (next_meas, off_t, Nmeasure);
   for (i = 0; i < Naverage; i++, N++) {
     for (j = 0; j < average[i].Nmeasure - 1; j++, N++) {
-      next[N] = N + 1;
+      next_meas[N] = N + 1;
       if (N >= Nmeasure) {
 	fprintf (stderr, "WARNING: N out of bounds (1)\n");
       }
     }
-    next[N] = -1;
+    next_meas[N] = -1;
     if (N >= Nmeasure) {
       fprintf (stderr, "WARNING: N out of bounds (2)\n");
@@ -28,59 +51,5 @@
     }
   }
-  return (next);
-}
-
-/* average[].measureOffset, average[].Nmeasure are valid within an addstar run */
-int add_meas_link (Average *average, off_t *next, off_t Nmeasure, off_t NMEASURE) {
-
-  off_t k, m;
-
-  /* if we have trouble, check validity of next[m] : m < Nmeasure */
-  m = average[0].measureOffset;  
-
-  for (k = 0; k < average[0].Nmeasure - 1; k++)  {
-    m = next[m];
-    if (m >= NMEASURE) {
-      fprintf (stderr, "WARNING: m out of bounds (3)\n");
-    }
-  }
-
-  /* set up references */
-  next[Nmeasure] = -1;
-  if (Nmeasure >= NMEASURE) {
-    fprintf (stderr, "WARNING: Nmeasure out of bounds (1)\n");
-  }
-
-  if (m == -1) {
-    average[0].measureOffset = Nmeasure;
-  } else {
-    next[m] = Nmeasure;
-    if (m >= NMEASURE) {
-      fprintf (stderr, "WARNING: m out of bounds (4)\n");
-    }
-  }
-
-  return (TRUE);
-}
-
-Measure *sort_measure (Average *average, off_t Naverage, Measure *measure, off_t Nmeasure, off_t *next) {
-
-  off_t i, k, n, N;
-  Measure *tmpmeasure;
-
-  /* fix order of Measure (memory intensive, but fast) */
-  N = 0; 
-  ALLOCATE (tmpmeasure, Measure, Nmeasure);
-  for (i = 0; i < Naverage; i++) {
-    n = average[i].measureOffset;
-    average[i].measureOffset = N;
-    for (k = 0; k < average[i].Nmeasure; k++, N++) {
-      tmpmeasure[N] = measure[n]; 
-      tmpmeasure[N].averef = i;
-      n = next[n];
-    }
-  }
-  free (measure);
-  return (tmpmeasure);
+  return (next_meas);
 }
 
@@ -95,7 +64,7 @@
 
   off_t i, m, k, Nm, averef;
-  off_t *next;
-
-  ALLOCATE (next, off_t, Nmeasure);
+  off_t *next_meas;
+
+  ALLOCATE (next_meas, off_t, Nmeasure);
 
   /* reset the Nm, offset values for average */
@@ -108,5 +77,5 @@
     averef = measure[Nm].averef;
     m = average[averef].measureOffset;  
-    next[Nm] = -1;
+    next_meas[Nm] = -1;
 
     if (m == -1) { /* no links yet for source */
@@ -116,6 +85,6 @@
     }
 
-    for (k = 0; next[m] != -1; k++) {
-      m = next[m];
+    for (k = 0; next_meas[m] != -1; k++) {
+      m = next_meas[m];
       if (m >= Nmeasure) {
 	fprintf (stderr, "WARNING: m out of bounds (1)\n");
@@ -124,11 +93,69 @@
 
     average[averef].Nmeasure = k + 2;
-    next[m] = Nm;
+    next_meas[m] = Nm;
     if (m >= Nmeasure) {
       fprintf (stderr, "WARNING: m out of bounds (2)\n");
     }
   }
-  return (next);
-}
+  return (next_meas);
+}
+
+/* average[].measureOffset, average[].Nmeasure are valid within an addstar run */
+int add_meas_link (Average *average, off_t *next_meas, off_t Nmeasure, off_t NMEASURE) {
+
+  off_t k, m;
+
+  /* if we have trouble, check validity of next_meas[m] : m < Nmeasure */
+  m = average[0].measureOffset;  
+
+  for (k = 0; k < average[0].Nmeasure - 1; k++)  {
+    m = next_meas[m];
+    if (m >= NMEASURE) {
+      fprintf (stderr, "WARNING: m out of bounds (3)\n");
+    }
+  }
+
+  /* set up references */
+  next_meas[Nmeasure] = -1;
+  if (Nmeasure >= NMEASURE) {
+    fprintf (stderr, "WARNING: Nmeasure out of bounds (1)\n");
+  }
+
+  if (m == -1) {
+    average[0].measureOffset = Nmeasure;
+  } else {
+    next_meas[m] = Nmeasure;
+    if (m >= NMEASURE) {
+      fprintf (stderr, "WARNING: m out of bounds (4)\n");
+    }
+  }
+
+  return (TRUE);
+}
+
+Measure *sort_measure (Average *average, off_t Naverage, Measure *measure, off_t Nmeasure, off_t *next_meas) {
+
+  off_t i, k, n, N;
+  Measure *tmpmeasure;
+
+  /* fix order of Measure (memory intensive, but fast) */
+  N = 0; 
+  ALLOCATE (tmpmeasure, Measure, Nmeasure);
+  for (i = 0; i < Naverage; i++) {
+    n = average[i].measureOffset;
+    average[i].measureOffset = N;
+    for (k = 0; k < average[i].Nmeasure; k++, N++) {
+      if (n == -1) abort();
+      tmpmeasure[N] = measure[n]; 
+      if (measure[n].averef != i) abort();
+      tmpmeasure[N].averef = i;
+      n = next_meas[n];
+    }
+  }
+  free (measure);
+  return (tmpmeasure);
+}
+
+/*******************************************************************************************/
 
 /* build the initial links assuming the table is sorted */
@@ -136,15 +163,15 @@
 
   off_t i, j, N;
-  off_t *next;
+  off_t *next_miss;
 
   N = 0;
 
-  ALLOCATE (next, off_t, Nmissing);
+  ALLOCATE (next_miss, off_t, Nmissing);
   for (i = 0; i < Naverage; i++) {
     for (j = 0; j < average[i].Nmissing - 1; j++, N++) {
-      next[N] = N + 1;
+      next_miss[N] = N + 1;
     }
     if (average[i].Nmissing > 0) {
-      next[N] = -1;
+      next_miss[N] = -1;
       if (N >= Nmissing) {
 	fprintf (stderr, "overflow in init_missing_links");
@@ -155,8 +182,8 @@
 
   }
-  return (next);
-}
-
-int add_miss_link (Average *average, off_t *next, off_t Nmissing) {
+  return (next_miss);
+}
+
+int add_miss_link (Average *average, off_t *next_miss, off_t Nmissing) {
 
   off_t k, m;
@@ -165,13 +192,13 @@
   if (average[0].Nmissing < 1) {
     average[0].missingOffset = Nmissing;
-    next[Nmissing] = -1;
+    next_miss[Nmissing] = -1;
     return (TRUE);
   }
 
   m = average[0].missingOffset;  
-  for (k = 0; k < average[0].Nmissing - 1; k++) m = next[m];
+  for (k = 0; k < average[0].Nmissing - 1; k++) m = next_miss[m];
   /* set up references */
-  next[Nmissing] = -1;
-  next[m] = Nmissing;
+  next_miss[Nmissing] = -1;
+  next_miss[m] = Nmissing;
   return (TRUE);
 }
@@ -180,5 +207,5 @@
    we must always save the missing table, if it exists */
 
-Missing *sort_missing (Average *average, off_t Naverage, Missing *missing, off_t Nmissing, off_t *next) {
+Missing *sort_missing (Average *average, off_t Naverage, Missing *missing, off_t Nmissing, off_t *next_miss) {
 
   off_t i, k, n, N;
@@ -193,5 +220,5 @@
     for (k = 0; k < average[i].Nmissing; k++, N++) {
       tmpmissing[N] = missing[n]; 
-      n = next[n];
+      n = next_miss[n];
     }
   }
@@ -199,2 +226,154 @@
   return (tmpmissing);
 }
+
+/*******************************************************************************************/
+
+/* build the initial links assuming the table is sorted, 
+   not partial, and has a correct set of average[].lensingOffset,Nlensing values */
+off_t *init_lensing_links (Average *average, off_t Naverage, Lensing *lensing, off_t Nlensing) {
+
+  off_t i, j, N;
+  off_t *next_lens;
+
+  N = 0;
+
+  ALLOCATE (next_lens, off_t, Nlensing);
+  for (i = 0; i < Naverage; i++) {
+    if (!average[i].Nlensing) continue;
+    for (j = 0; j < average[i].Nlensing - 1; j++, N++) {
+      next_lens[N] = N + 1;
+      if (N >= Nlensing) {
+	fprintf (stderr, "WARNING: N out of bounds (1)\n");
+      }
+    }
+    next_lens[N] = -1;
+    if (N >= Nlensing) {
+      fprintf (stderr, "WARNING: N out of bounds (2)\n");
+    }
+
+    if (N >= Nlensing) {
+      fprintf (stderr, "overflow in init_lensing_links\n");
+      abort ();
+    }
+    N++;
+  }
+  return (next_lens);
+}
+
+/* construct lensing links which are valid FOR THIS LOAD
+ * - if we have a full load, we will get links which can
+ *   be used by other programs (eg, relphot, etc)
+ * - if we have a partial load, the links are only valid
+ *   for that partial load
+ */ 
+
+off_t *build_lensing_links (Average *average, off_t Naverage, Lensing *lensing, off_t Nlensing) {
+
+  off_t i, m, k, Nm, averef;
+  off_t *next_lens;
+
+  ALLOCATE (next_lens, off_t, Nlensing);
+
+  /* reset the Nm, offset values for average */
+  for (i = 0; i < Naverage; i++) {
+    average[i].lensingOffset = -1;
+    average[i].Nlensing     =  0;
+  }
+
+  for (Nm = 0; Nm < Nlensing; Nm++) {
+    averef = lensing[Nm].averef;
+    m = average[averef].lensingOffset;  
+    next_lens[Nm] = -1;
+
+    if (m == -1) { /* no links yet for source */
+      average[averef].lensingOffset = Nm;
+      average[averef].Nlensing     = 1;
+      continue;
+    }
+
+    for (k = 0; next_lens[m] != -1; k++) {
+      m = next_lens[m];
+      if (m >= Nlensing) {
+	fprintf (stderr, "WARNING: m out of bounds (1)\n");
+      }
+    }
+
+    average[averef].Nlensing = k + 2;
+    next_lens[m] = Nm;
+    if (m >= Nlensing) {
+      fprintf (stderr, "WARNING: m out of bounds (2)\n");
+    }
+  }
+  return (next_lens);
+}
+
+/* average[].lensingOffset, average[].Nlensing are valid within an addstar run */
+int add_lens_link (Average *average, off_t *next_lens, off_t Nlensing, off_t NLENSING) {
+
+  off_t k, m;
+
+  /* if we have trouble, check validity of next_lens[m] : m < Nlensing */
+  m = average[0].lensingOffset;  
+
+  for (k = 0; k < average[0].Nlensing - 1; k++)  {
+    m = next_lens[m];
+    if (m >= NLENSING) {
+      fprintf (stderr, "WARNING: m out of bounds (3)\n");
+    }
+  }
+
+  /* set up references */
+  next_lens[Nlensing] = -1;
+  if (Nlensing >= NLENSING) {
+    fprintf (stderr, "WARNING: Nlensing out of bounds (1)\n");
+  }
+
+  if (m == -1) {
+    average[0].lensingOffset = Nlensing;
+  } else {
+    next_lens[m] = Nlensing;
+    if (m >= NLENSING) {
+      fprintf (stderr, "WARNING: m out of bounds (4)\n");
+    }
+  }
+
+  return (TRUE);
+}
+
+Lensing *sort_lensing (Average *average, off_t Naverage, Lensing *lensing, off_t Nlensing, off_t *next_lens) {
+
+  off_t i, k, n, np, N;
+  Lensing *tmplensing;
+
+  /*
+  for (i = 0; i < Naverage; i++) {
+    if (average[i].Nlensing != 4) {
+      fprintf (stderr, "check %d %d %d\n", (int) i, (int) average[i].Nlensing, (int) average[i].lensingOffset);
+    }
+  }
+  */
+
+  /* fix order of Lensing (memory intensive, but fast) */
+  N = 0; 
+  ALLOCATE (tmplensing, Lensing, Nlensing);
+  for (i = 0; i < Naverage; i++) {
+    if (!average[i].Nlensing) continue;
+    n = average[i].lensingOffset;
+    average[i].lensingOffset = N;
+    for (k = 0; k < average[i].Nlensing; k++, N++) {
+      if (n == -1) {
+	fprintf (stderr, "entry after %d has a problem\n", (int) np);
+	abort();
+      }
+      tmplensing[N] = lensing[n]; 
+      if (lensing[n].averef != i) abort();
+      tmplensing[N].averef = i;
+      np = n;
+      n = next_lens[n];
+    }
+  }
+  free (lensing);
+  return (tmplensing);
+}
+
+
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvo_image_merge_dbs.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvo_image_merge_dbs.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvo_image_merge_dbs.c	(revision 37403)
@@ -172,6 +172,12 @@
   }
 
+  if (!IDmap->Nmap) {
+    fprintf (stderr, "input database has image IDs, but no Image table\n");
+    return FALSE;
+  }
+
   off_t lastID = IDmap->old[IDmap->Nmap-1];
 
+  // update measure.imageID
   for (i = 0; i < catalog[0].Nmeasure; i++) {
     oldID = catalog[0].measure[i].imageID;
@@ -195,4 +201,27 @@
     catalog[0].measure[i].imageID = newID;
   }
+
+  // also update lensing.imageID if lensing exists
+  for (i = 0; i < catalog[0].Nlensing; i++) {
+    oldID = catalog[0].lensing[i].imageID;
+    if (oldID == 0) continue;
+
+    newID = dvo_map_image_ID (IDmap, oldID);
+    if (newID == 0) {
+      if (oldID > lastID) {
+	fprintf (stderr, "problem with image IDs : input out of range\n");
+	fprintf (stderr, "old ID: "OFF_T_FMT", last ID: "OFF_T_FMT"\n", oldID, lastID);
+	exit (2);
+      }
+      if (!IDmap->notFound[oldID]) {
+	fprintf (stderr, "cannot find image ID "OFF_T_FMT"\n",  oldID);
+	IDmap->notFound[oldID] = TRUE;
+	// once we discover an imageID is not found, record that fact so we do not complain for every detection
+      }
+      // optionally exit here? or wait until end to report an error?
+      // exit (2);
+    }
+    catalog[0].lensing[i].imageID = newID;
+  }
   return TRUE;
 }
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvomergeContinue.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvomergeContinue.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvomergeContinue.c	(revision 37403)
@@ -131,6 +131,4 @@
       merge_catalogs_old (&outsky[0].regions[j], &outcatalog, &incatalog, RADIUS, secfiltMap);
 
-      outcatalog.catflags = LOAD_AVES | LOAD_MEAS | LOAD_MISS | LOAD_SECF;
-
       // if we receive a signal which would cause us to exit, wait until the full catalog is written
       SetProtect (TRUE);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvomergeContinue_threaded.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvomergeContinue_threaded.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvomergeContinue_threaded.c	(revision 37403)
@@ -74,6 +74,4 @@
       merge_catalogs_old (&threadData->outsky->regions[j], &outcatalog, &incatalog, RADIUS, threadData->secfiltMap);
 
-      outcatalog.catflags = LOAD_AVES | LOAD_MEAS | LOAD_MISS | LOAD_SECF;
-
       // if we receive a signal which would cause us to exit, wait until the full catalog is written
       SetProtect (TRUE);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvomergeCreate.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvomergeCreate.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvomergeCreate.c	(revision 37403)
@@ -178,5 +178,4 @@
     SkyListFree (inlist);
 
-    outcatalog.catflags = LOAD_AVES | LOAD_MEAS | LOAD_MISS | LOAD_SECF;
     dvo_catalog_save (&outcatalog, VERBOSE);
     dvo_catalog_unlock (&outcatalog);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvomergeFromList.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvomergeFromList.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvomergeFromList.c	(revision 37403)
@@ -143,6 +143,4 @@
     merge_catalogs_old (&skyregion, &outcatalog, &incatalog, RADIUS, secfiltMap);
     
-    outcatalog.catflags = LOAD_AVES | LOAD_MEAS | LOAD_MISS | LOAD_SECF;
-
     dmhObjectAdd (outstat[0].history, &outcatalog.header, inStats);
 
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvomergeImageIDs.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvomergeImageIDs.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvomergeImageIDs.c	(revision 37403)
@@ -18,4 +18,6 @@
   if (inDB.dbstate == LCK_EMPTY) {
     dvo_image_unlock (&inDB); // unlock input
+    IDmap->old = NULL;
+    IDmap->new = NULL;
     IDmap->Nmap = 0;
     return TRUE;
@@ -99,4 +101,6 @@
   if (inDB.dbstate == LCK_EMPTY) {
     dvo_image_unlock (&inDB); // unlock input
+    IDmap->old = NULL;
+    IDmap->new = NULL;
     IDmap->Nmap = 0;
     return TRUE;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvomergeUpdate.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvomergeUpdate.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvomergeUpdate.c	(revision 37403)
@@ -13,7 +13,5 @@
   int NsecfiltInput, NsecfiltOutput;
 
-  double dtime;
-  struct timeval start, stop;
-  gettimeofday (&start, NULL);
+  INITTIME;
 
   CONTINUE = FALSE;
@@ -121,13 +119,10 @@
   }
 
-  gettimeofday (&stop, NULL);
-  dtime = DTIME (stop, start);
-
   if (!status) {
-    fprintf (stderr, "ERROR: elapsed time %9.4f sec\n", dtime);
+    MARKTIME ("ERROR: elapsed time %9.4f sec\n", dtime);
     exit (3);
   }
 
-  fprintf (stderr, "SUCCESS: elapsed time %9.4f sec\n", dtime);
+  MARKTIME ("SUCCESS: elapsed time %9.4f sec\n", dtime);
   exit (0);
 }
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvomergeUpdate_catalogs.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvomergeUpdate_catalogs.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvomergeUpdate_catalogs.c	(revision 37403)
@@ -140,4 +140,9 @@
     }
 
+    if (!incatalog.sorted) {
+      fprintf (stderr, "ERROR: input catalog %s is not sorted (and must be for dvomerge)\n", filename_input);
+      exit (1);
+    }
+
     dvo_update_image_IDs (IDmap, &incatalog);
 
@@ -158,7 +163,10 @@
       LoadCatalog (&outcatalog, outlist[0].regions[j], outcatalog.filename, "w", NsecfiltOutput);
 
+      // if no catalog already exists, use the input catalog to define the format
+      if (outcatalog.Naves_disk == 0) {
+	outcatalog.catformat = incatalog.catformat;
+      }
+
       merge_catalogs_old (outlist[0].regions[j], &outcatalog, &incatalog, RADIUS, secfiltMap);
-
-      outcatalog.catflags = LOAD_AVES | LOAD_MEAS | LOAD_MISS | LOAD_SECF;
 
       if (outstat[j].missed) {
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvomergeUpdate_threaded.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvomergeUpdate_threaded.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvomergeUpdate_threaded.c	(revision 37403)
@@ -72,6 +72,4 @@
       merge_catalogs_old (&threadData->outsky->regions[j], &outcatalog, &incatalog, RADIUS, threadData->secfiltMap);
 
-      outcatalog.catflags = LOAD_AVES | LOAD_MEAS | LOAD_MISS | LOAD_SECF;
-
       // if we receive a signal which would cause us to exit, wait until the full catalog is written
       SetProtect (TRUE);
@@ -115,7 +113,5 @@
   int NsecfiltInput, NsecfiltOutput;
 
-  double dtime;
-  struct timeval start, stop;
-  gettimeofday (&start, NULL);
+  INITTIME;
 
   CONTINUE = FALSE;
@@ -134,4 +130,5 @@
 
   fprintf (stderr, "WARNING / ERROR : multi-threaded dvomerge does not handle merge tracking yet\n");
+  fprintf (stderr, "WARNING / ERROR : multi-threaded dvomerge does work in a parallel context\n");
   exit (2);
 
@@ -293,8 +290,5 @@
   }
 
-  gettimeofday (&stop, NULL);
-  dtime = DTIME (stop, start);
-  fprintf (stderr, "SUCCESS: elapsed time %9.4f sec\n", dtime);
-
+  MARKTIME ("SUCCESS: elapsed time %9.4f sec\n", dtime);
   exit (0);
 
@@ -318,4 +312,5 @@
     }
   }
+  MARKTIME ("ERROR: elapsed time %9.4f sec\n", dtime);
   exit (1);
 }
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvorepair.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvorepair.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvorepair.c	(revision 37403)
@@ -2,4 +2,8 @@
 
 int main (int argc, char **argv) {
+
+  fprintf (stderr, "this program needs to be updated to load old format Measure tables (pre PV1_V5) in which dR,dD are saved, not R,D\n");
+  fprintf (stderr, "reminder: relastro can re-construct R,D from X,Y; FtableToMeasure and vice versa could just NAN those values\n");
+  exit (2);
 
   dvorepair_help(argc, argv);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvorepairCPT.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvorepairCPT.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvorepairCPT.c	(revision 37403)
@@ -76,5 +76,5 @@
   }
 
-  measure = FtableToMeasure (&cpmFtable, &Nmeasure, &catformat);
+  measure = FtableToMeasure (&cpmFtable, NULL, &Nmeasure, &catformat);
   myAssert(measure, "failed to convert ftable to measure data");
 
@@ -126,5 +126,6 @@
     average[Nave].measureOffset = -1;
     average[Nave].missingOffset = -1;
-    average[Nave].extendOffset = -1;
+    average[Nave].refColorBlue = NAN;
+    average[Nave].refColorRed = NAN;
 
     average[Nave].objID = measure[i].objID;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvorepairDeleteImageList.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvorepairDeleteImageList.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvorepairDeleteImageList.c	(revision 37403)
@@ -250,5 +250,5 @@
 	gfits_scan(&cpmHeaderTBL, "NAXIS1", "%d", 1, &NbytesPerRow);
 
-	measure = FtableToMeasure (&cpmFtable, &Nmeasure, &catformat);
+	measure = FtableToMeasure (&cpmFtable, NULL, &Nmeasure, &catformat);
 	myAssert(measure, "failed to convert ftable to measure data");
     
@@ -288,5 +288,5 @@
 
 	// convert internal to external format 
-	if (!MeasureToFtable (&cpmFtable, measureNew, NmeasureNew, catformat)) {
+	if (!MeasureToFtable (&cpmFtable, NULL, measureNew, NmeasureNew, catformat)) {
 	  myAbort("trouble converting format");
 	}
@@ -411,5 +411,6 @@
     average[Nave].measureOffset = -1;
     average[Nave].missingOffset = -1;
-    average[Nave].extendOffset = -1;
+    average[Nave].refColorBlue = NAN;
+    average[Nave].refColorRed = NAN;
 
     average[Nave].objID = measure[i].objID;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvorepairFixCPT.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvorepairFixCPT.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvorepairFixCPT.c	(revision 37403)
@@ -120,5 +120,5 @@
   }
 
-  measure = FtableToMeasure (&cpmFtable, &Nmeasure, &catformat);
+  measure = FtableToMeasure (&cpmFtable, NULL, &Nmeasure, &catformat);
   myAssert(measure, "failed to convert ftable to measure data");
 
@@ -127,5 +127,5 @@
 
   // convert internal to external format 
-  if (!MeasureToFtable (&cpmFtable, measure, Nmeasure, catformat)) {
+  if (!MeasureToFtable (&cpmFtable, NULL, measure, Nmeasure, catformat)) {
     myAbort("trouble converting format");
   }
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvorepairFixTables.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvorepairFixTables.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvorepairFixTables.c	(revision 37403)
@@ -103,5 +103,5 @@
 
       // convert internal to external format 
-      if (!MeasureToFtable (&cpmFtable, measureNew, NmeasureNew, catformat)) {
+      if (!MeasureToFtable (&cpmFtable, NULL, measureNew, NmeasureNew, catformat)) {
 	myAbort("trouble converting format");
       }
@@ -183,5 +183,5 @@
   gfits_scan(&cpmHeaderTBL, "NAXIS2", "%d", 1, &Nrows);
 
-  measure = FtableToMeasure (&cpmFtable, &Nmeasure, &catformat);
+  measure = FtableToMeasure (&cpmFtable, NULL, &Nmeasure, &catformat);
   myAssert(measure, "failed to convert ftable to measure data");
     
@@ -266,5 +266,6 @@
     average[Nave].measureOffset = -1;
     average[Nave].missingOffset = -1;
-    average[Nave].extendOffset = -1;
+    average[Nave].refColorBlue = NAN;
+    average[Nave].refColorRef = NAN;
 
     average[Nave].objID = measure[i].objID;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvorepairImageVsMeasure.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvorepairImageVsMeasure.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvorepairImageVsMeasure.c	(revision 37403)
@@ -128,5 +128,5 @@
       gfits_scan(&cpmHeaderTBL, "NAXIS1", "%d", 1, &NbytesPerRow);
 
-      measure = FtableToMeasure (&cpmFtable, &Nmeasure, &catformat);
+      measure = FtableToMeasure (&cpmFtable, NULL, &Nmeasure, &catformat);
       myAssert(measure, "failed to convert ftable to measure data");
     
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvorepairImagesVsMeasures.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvorepairImagesVsMeasures.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvorepairImagesVsMeasures.c	(revision 37403)
@@ -134,5 +134,5 @@
       gfits_scan(&cpmHeaderTBL, "NAXIS1", "%d", 1, &NbytesPerRow);
 
-      measure = FtableToMeasure (&cpmFtable, &Nmeasure, &catformat);
+      measure = FtableToMeasure (&cpmFtable, NULL, &Nmeasure, &catformat);
       myAssert(measure, "failed to convert ftable to measure data");
     
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvoverify_args.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvoverify_args.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvoverify_args.c	(revision 37403)
@@ -56,7 +56,5 @@
   }
 
-  /*** dvoverify -parallel (dvoverify_client, actually) ignores this argument
-       dvoverify should save a subset table of just the IDs, and dvoverify_client should load it
-       dvoverify -cpt should have CHECK_IMAGE_ID = F as default ***/
+  /*** dvoverify -cpt should have CHECK_IMAGE_ID = F as default ***/
        
   CHECK_IMAGE_ID = TRUE;
@@ -150,4 +148,10 @@
   }
 
+  CHECK_IMAGE_ID = TRUE;
+  if ((N = get_argument (*argc, argv, "-skip-image-ids"))) {
+    CHECK_IMAGE_ID = FALSE;
+    remove_argument (N, argc, argv);
+  }
+
   // restrict to a portion of the sky
   UserPatch.Rmin = 0;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvoverify_catalogs.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvoverify_catalogs.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvoverify_catalogs.c	(revision 37403)
@@ -47,4 +47,18 @@
     }
 
+    sprintf (filename, "%s/%s.cpx", mycatdir, skylist[0].regions[i][0].name);
+    if (!VerifyTableFile (filename)) {
+      Nbad ++;
+      skipIndexCheck = TRUE;
+      AddFailures (filename);
+    }
+
+    sprintf (filename, "%s/%s.cpy", mycatdir, skylist[0].regions[i][0].name);
+    if (!VerifyTableFile (filename)) {
+      Nbad ++;
+      skipIndexCheck = TRUE;
+      AddFailures (filename);
+    }
+
     sprintf (filename, "%s/%s.cpt", mycatdir, skylist[0].regions[i][0].name);
     if (!skipIndexCheck) {
@@ -80,4 +94,14 @@
     exit (1);
   }    
+
+  // save the IDlist as a smaller FITS table
+  if (CHECK_IMAGE_ID) {
+    char filename[DVO_MAX_PATH];
+    snprintf (filename, DVO_MAX_PATH, "%s/ImageIDs.fits", CATDIR);
+    if (!SaveImageIDsSmall (filename)) {
+      fprintf (stderr, "ERROR: failure to save image IDs\n");
+      exit (2);
+    }
+  }
 
   int i;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvoverify_client.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvoverify_client.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvoverify_client.c	(revision 37403)
@@ -22,5 +22,10 @@
     // XXX in client mode, we should be reading a reduced table generated by the calling
     // serial program
-    LoadImageIDs (CATDIR);
+    char filename[DVO_MAX_PATH];
+    snprintf (filename, DVO_MAX_PATH, "%s/ImageIDs.fits", CATDIR);
+    if (!LoadImageIDsSmall (filename)) {
+      fprintf (stderr, "ERROR: failure to load image IDs\n");
+      exit (2);
+    }
   }
 
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvoverify_utils.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvoverify_utils.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/dvoverify_utils.c	(revision 37403)
@@ -178,5 +178,5 @@
   catalog.catformat = DVO_FORMAT_UNDEF; // read-only,do not set the catformat
   catalog.catmode   = DVO_MODE_UNDEF; // read-only, do not set the catmode
-  catalog.catflags  = LOAD_AVES | LOAD_MEAS;
+  catalog.catflags  = LOAD_AVES | LOAD_MEAS | LOAD_LENSING | LOAD_LENSOBJ;
   catalog.Nsecfilt  = 0;
   
@@ -214,4 +214,8 @@
   int NmeasureTotal = 0;
   int measureOffsetOK = TRUE;
+  int NlensingTotal = 0;
+  int lensingOffsetOK = TRUE;
+  int NlensobjTotal = 0;
+  int lensobjOffsetOK = TRUE;
   for (i = 0; i < catalog.Naverage; i++) {
     NmeasureTotal += catalog.average[i].Nmeasure;
@@ -227,4 +231,32 @@
       fprintf (stderr, "measureOffset + Nmeasure > catalog.Nmeasure : %d %d %d\n", i, catalog.average[i].Nmeasure, (int) catalog.Nmeasure);
     }
+
+    // sum of Nlensing for each object < Nlensing for catalog
+    NlensingTotal += catalog.average[i].Nlensing;
+    if (VERBOSE && !(NlensingTotal <= catalog.Nlensing)) {
+      fprintf (stderr, "NlensingTotal > catalog.Nlensing: %d %d %d\n", i, catalog.average[i].Nlensing, (int) catalog.Nlensing);
+    }
+    // lensingOffset needs to be in range for each object
+    lensingOffsetOK &= (catalog.average[i].lensingOffset < catalog.Nlensing);
+    if (VERBOSE && !(catalog.average[i].lensingOffset < catalog.Nlensing)) {
+      fprintf (stderr, "lensingOffset >= catalog.Nlensing: %d %d %d\n", i, catalog.average[i].lensingOffset, (int) catalog.Nlensing);
+    }
+    lensingOffsetOK &= (catalog.average[i].lensingOffset + catalog.average[i].Nlensing <= catalog.Nlensing);
+    if (VERBOSE && !(catalog.average[i].lensingOffset + catalog.average[i].Nlensing <= catalog.Nlensing)) {
+      fprintf (stderr, "lensingOffset + Nlensing > catalog.Nlensing : %d %d %d\n", i, catalog.average[i].Nlensing, (int) catalog.Nlensing);
+    }
+
+    NlensobjTotal += catalog.average[i].Nlensobj;
+    if (VERBOSE && !(NlensobjTotal <= catalog.Nlensobj)) {
+      fprintf (stderr, "NlensobjTotal > catalog.Nlensobj: %d %d %d\n", i, catalog.average[i].Nlensobj, (int) catalog.Nlensobj);
+    }
+    lensobjOffsetOK &= (catalog.average[i].lensobjOffset < catalog.Nlensobj);
+    if (VERBOSE && !(catalog.average[i].lensobjOffset < catalog.Nlensobj)) {
+      fprintf (stderr, "lensobjOffset >= catalog.Nlensobj: %d %d %d\n", i, catalog.average[i].lensobjOffset, (int) catalog.Nlensobj);
+    }
+    lensobjOffsetOK &= (catalog.average[i].lensobjOffset + catalog.average[i].Nlensobj <= catalog.Nlensobj);
+    if (VERBOSE && !(catalog.average[i].lensobjOffset + catalog.average[i].Nlensobj <= catalog.Nlensobj)) {
+      fprintf (stderr, "lensobjOffset + Nlensobj > catalog.Nlensobj : %d %d %d\n", i, catalog.average[i].Nlensobj, (int) catalog.Nlensobj);
+    }
   }
 
@@ -236,4 +268,24 @@
   if (NmeasureTotal != catalog.Nmeasure) {
     fprintf (stderr, "ERROR: catalog %s has an invalid Nmeasure\n", catalog.filename);
+    status = FALSE;
+  }
+
+  if (!lensingOffsetOK) {
+    fprintf (stderr, "ERROR: catalog %s has an invalid lensingOffset\n", catalog.filename);
+    status = FALSE;
+  }
+
+  if (NlensingTotal != catalog.Nlensing) {
+    fprintf (stderr, "ERROR: catalog %s has an invalid Nlensing\n", catalog.filename);
+    status = FALSE;
+  }
+
+  if (!lensobjOffsetOK) {
+    fprintf (stderr, "ERROR: catalog %s has an invalid lensobjOffset\n", catalog.filename);
+    status = FALSE;
+  }
+
+  if (NlensobjTotal != catalog.Nlensobj) {
+    fprintf (stderr, "ERROR: catalog %s has an invalid Nlensobj\n", catalog.filename);
     status = FALSE;
   }
@@ -247,28 +299,83 @@
   }
 
-  int objIDsOK = TRUE;
-  int catIDsOK = TRUE;
-  int averefOK = TRUE;
-
-  for (i = 0; i < catalog.Naverage; i++) {
-    m = catalog.average[i].measureOffset;
-    for (j = 0; j < catalog.average[i].Nmeasure; j++) {
-      objIDsOK &= (catalog.average[i].objID == catalog.measure[m+j].objID);
-      catIDsOK &= (catalog.average[i].catID == catalog.measure[m+j].catID);
-      averefOK &= (catalog.measure[m+j].averef == i);
-    }
-  }
+  // check measure <-> average links
+  {
+    int objIDsOK = TRUE;
+    int catIDsOK = TRUE;
+    int averefOK = TRUE;
+
+    for (i = 0; i < catalog.Naverage; i++) {
+      m = catalog.average[i].measureOffset;
+      for (j = 0; j < catalog.average[i].Nmeasure; j++) {
+	objIDsOK &= (catalog.average[i].objID == catalog.measure[m+j].objID);
+	catIDsOK &= (catalog.average[i].catID == catalog.measure[m+j].catID);
+	averefOK &= (catalog.measure[m+j].averef == i);
+      }
+    }
     
-  if (!objIDsOK) {
-    fprintf (stderr, "ERROR: catalog %s has invalid obj IDs\n", catalog.filename);
-    status = FALSE;
-  }
-  if (!catIDsOK) {
-    fprintf (stderr, "ERROR: catalog %s has invalid cat IDs\n", catalog.filename);
-    status = FALSE;
-  }
-  if (!averefOK) {
-    fprintf (stderr, "ERROR: catalog %s has invalid averef values\n", catalog.filename);
-    status = FALSE;
+    if (!objIDsOK) {
+      fprintf (stderr, "ERROR: catalog %s has invalid obj IDs\n", catalog.filename);
+      status = FALSE;
+    }
+    if (!catIDsOK) {
+      fprintf (stderr, "ERROR: catalog %s has invalid cat IDs\n", catalog.filename);
+      status = FALSE;
+    }
+    if (!averefOK) {
+      fprintf (stderr, "ERROR: catalog %s has invalid averef values\n", catalog.filename);
+      status = FALSE;
+    }
+  }
+
+  // check lensing <-> average links
+  {
+    int objIDsOK = TRUE;
+    int catIDsOK = TRUE;
+    int averefOK = TRUE;
+
+    for (i = 0; i < catalog.Naverage; i++) {
+      m = catalog.average[i].lensingOffset;
+      for (j = 0; j < catalog.average[i].Nlensing; j++) {
+	objIDsOK &= (catalog.average[i].objID == catalog.lensing[m+j].objID);
+	catIDsOK &= (catalog.average[i].catID == catalog.lensing[m+j].catID);
+	averefOK &= (catalog.lensing[m+j].averef == i);
+      }
+    }
+    
+    if (!objIDsOK) {
+      fprintf (stderr, "ERROR: catalog %s has invalid lensing obj IDs\n", catalog.filename);
+      status = FALSE;
+    }
+    if (!catIDsOK) {
+      fprintf (stderr, "ERROR: catalog %s has invalid lensing cat IDs\n", catalog.filename);
+      status = FALSE;
+    }
+    if (!averefOK) {
+      fprintf (stderr, "ERROR: catalog %s has invalid lensing averef values\n", catalog.filename);
+      status = FALSE;
+    }
+  }
+
+  // check lensobj <-> average links
+  {
+    int objIDsOK = TRUE;
+    int catIDsOK = TRUE;
+
+    for (i = 0; i < catalog.Naverage; i++) {
+      m = catalog.average[i].lensobjOffset;
+      for (j = 0; j < catalog.average[i].Nlensobj; j++) {
+	objIDsOK &= (catalog.average[i].objID == catalog.lensobj[m+j].objID);
+	catIDsOK &= (catalog.average[i].catID == catalog.lensobj[m+j].catID);
+      }
+    }
+    
+    if (!objIDsOK) {
+      fprintf (stderr, "ERROR: catalog %s has invalid lensobj obj IDs\n", catalog.filename);
+      status = FALSE;
+    }
+    if (!catIDsOK) {
+      fprintf (stderr, "ERROR: catalog %s has invalid lensobj cat IDs\n", catalog.filename);
+      status = FALSE;
+    }
   }
 
@@ -321,4 +428,29 @@
     }
   }
+
+  for (i = 0; i < catalog[0].Naverage; i++) {
+    m = catalog[0].average[i].lensingOffset;
+    for (j = 0; j < catalog[0].average[i].Nlensing; j++) {
+      id = catalog[0].lensing[m+j].imageID;
+      if (id == 0) continue; // detections from ref photcodes can (should) have unset image IDs
+      if (id > maxID) {
+	Nfail ++;
+	continue;
+	// is this sufficient to catch IDs set without an image table?
+      }
+      if (IDlist) {
+	if (IDlist[id] < 0) {
+	  Nfail ++;
+	  continue;
+	}
+      } else {
+	if (id > 0) {
+	  Nfail ++;
+	  continue;
+	}
+      }
+    }
+  }
+
   return Nfail;
 }
@@ -382,2 +514,127 @@
   return TRUE;
 }
+
+# define GET_COLUMN(OUT,NAME,TYPE) \
+  OUT = gfits_get_bintable_column_data (&theader, &ftable, NAME, type, &Nrow, &Ncol); \
+  myAssert (!strcmp(type, #TYPE), "wrong column type");
+
+// STATUS is value expected for success
+# define CHECK_STATUS(STATUS,MSG,...)					\
+  if (!(STATUS)) {							\
+    fprintf (stderr, MSG, __VA_ARGS__);					\
+    return FALSE;							\
+  }
+
+// write out the IDmap data for clients to read
+int SaveImageIDsSmall(char *filename) {
+
+  Header header;
+  Header theader;
+  Matrix matrix;
+  FTable ftable;
+
+  gfits_init_header (&header);
+  header.extend = TRUE;
+  gfits_create_header (&header);
+  gfits_create_matrix (&header, &matrix);
+
+  gfits_create_table_header (&theader, "BINTABLE", "IMAGE_IDS");
+
+  gfits_define_bintable_column (&theader, "J", "IMAGE_IDS", "image IDs", NULL, 1.0, FT_BZERO_INT32);
+
+  // generate the output array that carries the data
+  gfits_create_table (&theader, &ftable);
+
+  // add the columns to the output array
+  gfits_set_bintable_column (&theader, &ftable, "IMAGE_IDS", IDlist, maxID + 1);
+
+  FILE *f = fopen (filename, "w");
+  if (!f) {
+    fprintf (stderr, "ERROR: cannot open image ID file for output %s\n", filename);
+    return FALSE;
+  }
+
+  int status;
+  status = gfits_fwrite_header  (f, &header);
+  CHECK_STATUS (status, "ERROR: cannot write header for image ID file %s\n", filename);
+
+  status = gfits_fwrite_matrix  (f, &matrix);
+  CHECK_STATUS (status, "ERROR: cannot write matrix for image ID file %s\n", filename);
+
+  status = gfits_fwrite_Theader (f, &theader);
+  CHECK_STATUS (status, "ERROR: cannot write table header for image ID file %s\n", filename);
+
+  status = gfits_fwrite_table  (f, &ftable);
+  CHECK_STATUS (status, "ERROR: cannot write table data for image ID file %s\n", filename);
+
+  gfits_free_header (&header);
+  gfits_free_matrix (&matrix);
+  gfits_free_header (&theader);
+  gfits_free_table (&ftable);
+
+  int fd = fileno (f);
+
+  status = fflush (f);
+  CHECK_STATUS (!status, "ERROR: cannot flush file image ID file %s\n", filename);
+
+  status = fsync (fd);
+  CHECK_STATUS (!status, "ERROR: cannot flush file image ID file %s\n", filename);
+
+  status = fclose (f);
+  CHECK_STATUS (!status, "ERROR: problem closing image ID file file %s\n", filename);
+
+  return TRUE;
+}
+
+int LoadImageIDsSmall (char *filename) {
+
+  int Ncol;
+  off_t Nrow;
+  Header header;
+  Header theader;
+  Matrix matrix;
+  FTable ftable;
+
+  FILE *f = fopen (filename, "r");
+  if (!f) {
+    fprintf (stderr, "ERROR: cannot open image subset file %s\n", filename);
+    return FALSE;
+  }
+
+  /* load in PHU segment (ignore) */
+  if (!gfits_fread_header (f, &header)) {
+    if (VERBOSE) fprintf (stderr, "can't read image subset header\n");
+    fclose (f);
+    return FALSE;
+  }
+  if (!gfits_fread_matrix (f, &matrix, &header)) {
+    if (VERBOSE) fprintf (stderr, "can't read image subset matrix\n");
+    gfits_free_header (&header);
+    fclose (f);
+    return FALSE;
+  }
+
+  ftable.header = &theader;
+
+  // load data for this header 
+  if (!gfits_load_header (f, &theader)) {
+    fclose (f);
+    return FALSE;
+  }
+
+  // read the fits table bytes
+  if (!gfits_fread_ftable_data (f, &ftable, FALSE)) {
+    fclose (f);
+    return FALSE;
+  }
+  fclose (f);
+
+  char type[16];
+
+  GET_COLUMN (IDlist, "IMAGE_IDS", int);
+  maxID = Nrow - 1;
+  fprintf (stderr, "loaded data for %lld images\n", (long long) Nrow);
+
+  return TRUE;
+}
+
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/merge_catalogs_new.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/merge_catalogs_new.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/merge_catalogs_new.c	(revision 37403)
@@ -8,10 +8,8 @@
 // input entries always define new objects
 
-#define notyet 1
-
 int merge_catalogs_new (SkyRegion *region, Catalog *output, Catalog *input, int *secfiltMap) {
   
   off_t i, j, offset;
-  off_t NAVERAGE, NMEASURE, Naverage, Nmeasure, NsecfiltIn, NsecfiltOut, Nm;
+  off_t NAVERAGE, NMEASURE, NLENSING, Naverage, Nmeasure, Nlensing, NsecfiltIn, NsecfiltOut, Nm;
 
   Naverage = output[0].Naverage;
@@ -63,4 +61,21 @@
       }
       output[0].average[Naverage].Nmeasure = Nm;
+
+      Nm = 0;
+      for (j = 0; j < input[0].average[i].Nlensing; j++) {
+	  offset = input[0].average[i].lensingOffset + j;
+
+	  output[0].lensing[Nlensing] = input[0].lensing[offset];
+	  output[0].lensing[Nlensing].averef = Naverage;
+
+	  Nlensing ++;
+	  Nm ++;
+	  if (Nlensing == NLENSING) {
+	      NLENSING += 1000;
+	      REALLOCATE (output[0].lensing, Lensing, NLENSING);
+	  }
+      }
+      output[0].average[Naverage].Nlensing = Nm;
+
       Naverage ++;
       if (Naverage == NAVERAGE) {
@@ -72,7 +87,8 @@
   REALLOCATE (output[0].average, Average, MAX (Naverage, 1));
   REALLOCATE (output[0].measure, Measure, MAX (Nmeasure, 1));
+  REALLOCATE (output[0].lensing, Lensing, MAX (Nlensing, 1));
   REALLOCATE (output[0].secfilt, SecFilt, NsecfiltOut*MAX (Naverage, 1));
   output[0].Naverage = Naverage;
-  output[0].Nmeasure = Nmeasure;
+  output[0].Nlensing = Nlensing;
   output[0].Nsecf_mem = Naverage * NsecfiltOut;
 
@@ -84,8 +100,9 @@
   
   if (VERBOSE) {
-      fprintf (stderr, OFF_T_FMT": using "OFF_T_FMT" stars ("OFF_T_FMT" measures) for catalog\n", 
+      fprintf (stderr, OFF_T_FMT": using "OFF_T_FMT" stars ("OFF_T_FMT" measures, "OFF_T_FMT" lensing) for catalog\n", 
 	        i, 
 	        output[0].Naverage, 
-	        output[0].Nmeasure);
+	        output[0].Nmeasure, 
+	        output[0].Nlensing);
   }
   return (TRUE);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/merge_catalogs_old.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/merge_catalogs_old.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/merge_catalogs_old.c	(revision 37403)
@@ -1,12 +1,4 @@
 # include "dvomerge.h"
 # define PSPS_ID TRUE
-
-# define MARKTIME(MSG,...) {			\
-    float dtime;				\
-    gettimeofday (&stop, (void *) NULL);	\
-    dtime = DTIME (stop, start);		\
-    fprintf (stderr, MSG, __VA_ARGS__);		\
-    gettimeofday (&start, (void *) NULL);	\
-  }
 
 # define IN_REGION(R,D) (					\
@@ -19,9 +11,9 @@
 
   off_t i, j, k, Nin, offset, J, Jmin, status, Nstars;
-  double RADIUS2, Rmin, Rin, Din;
+  double RADIUS2, Rmin;
   double *X1, *Y1, *X2, *Y2;
   double dX, dY, dR;
-  off_t *N1, *N2,  *next_meas;
-  off_t Nave, NAVE, Nmeas, NMEAS, Nmatch;
+  off_t *N1, *N2, *next_meas, *next_lens;
+  off_t Nave, NAVE, Nmeas, NMEAS, Nmatch, Nlens, NLENS;
   int NsecfiltIn;
   int NsecfiltOut;
@@ -29,6 +21,5 @@
   Coords tcoords;
   
-  // struct timeval start, stop;
-  // gettimeofday (&start, (void *) NULL);
+  // INITTIME;
 
   NsecfiltOut = output[0].Nsecfilt;
@@ -40,5 +31,9 @@
   ALLOCATE (Y1, double, input[0].Naverage);
   ALLOCATE (N1, off_t,  input[0].Naverage);
-  ALLOCATE (input[0].found, off_t, input[0].Naverage);
+  if (!input[0].found_t) {
+    ALLOCATE (input[0].found_t, off_t, input[0].Naverage);
+  } else {
+    REALLOCATE (input[0].found_t, off_t, input[0].Naverage);
+  }
 
   /** allocate local arrays (catalog) **/
@@ -47,5 +42,9 @@
   ALLOCATE (Y2, double, NAVE);
   ALLOCATE (N2, off_t,    NAVE);
-  ALLOCATE (output[0].found, off_t, NAVE);
+  if (!output[0].found_t) {
+    ALLOCATE (output[0].found_t, off_t, NAVE);
+  } else {
+    REALLOCATE (output[0].found_t, off_t, NAVE);
+  }
   /* for secfilt j and star i, secfilt[i*Nsecfilt+j] */
 
@@ -53,4 +52,5 @@
   Nmatch = 0;
   NMEAS = Nmeas = output[0].Nmeasure;
+  NLENS = Nlens = output[0].Nlensing;
 
   // current max obj ID for this catalog
@@ -87,10 +87,8 @@
     N1[Nstars] = i;
     Nstars ++;
-    input[0].found[i] = -1;
+    input[0].found_t[i] = -1;
   }
   if (Nstars < 1) {
     if (VERBOSE) fprintf (stderr, "skipping %s, no overlapping stars\n", output[0].filename);
-    free (output[0].found);
-    free (input[0].found);
     free (X1);
     free (Y1);
@@ -106,5 +104,5 @@
   for (i = 0; i < Nave; i++) {
     RD_to_XY (&X2[i], &Y2[i], output[0].average[i].R, output[0].average[i].D, &tcoords);
-    output[0].found[i] = -1;
+    output[0].found_t[i] = -1;
     N2[i] = i;
   }
@@ -115,5 +113,4 @@
     exit (3);
   }
-
 
   /* set up pointers for linked list of measure */
@@ -122,6 +119,8 @@
     // is sorted while processed
     next_meas = init_measure_links (output[0].average, Nave, output[0].measure, Nmeas);
+    next_lens = init_lensing_links (output[0].average, Nave, output[0].lensing, Nlens);
   } else {
     next_meas = build_measure_links (output[0].average, Nave, output[0].measure, Nmeas);
+    next_lens = build_lensing_links (output[0].average, Nave, output[0].lensing, Nlens);
   }    
 
@@ -185,4 +184,9 @@
       REALLOCATE (output[0].measure, Measure, NMEAS);
     }
+    if (Nlens + input[0].average[N].Nmeasure >= NLENS) {
+      NLENS = Nlens + input[0].average[N].Nmeasure + 1000;
+      REALLOCATE (next_lens, off_t, NLENS);
+      REALLOCATE (output[0].lensing, Lensing, NLENS);
+    }
 
     // 4) average properties from the input and the output db need to be properly merged.
@@ -194,7 +198,8 @@
       if (REPLACE_BY_PHOTCODE) {
 	// index to first measure for this object
+	// XXX this does not support lensing measurements
 	int Mout = output[0].average[n].measureOffset;  
 	if (replace_match(&output[0].average[n], &output[0].measure[Mout], &input[0].average[N], &input[0].measure[offset])) {
-	  input[0].found[N] = Mout;
+	  input[0].found_t[N] = Mout;
 	  continue;
 	}
@@ -206,10 +211,11 @@
       output[0].measure[Nmeas] = input[0].measure[offset];
 
-      Rin = input[0].average[N].R - input[0].measure[offset].dR / 3600.0;
-      Din = input[0].average[N].D - input[0].measure[offset].dD / 3600.0;
-
-      /** dR,dD now represent arcsec **/
-      output[0].measure[Nmeas].dR       = 3600.0*(output[0].average[n].R - Rin);  // XXX update these based on choice of astromety
-      output[0].measure[Nmeas].dD       = 3600.0*(output[0].average[n].D - Din);  // XXX update these based on choice of astromety
+      // old code: find R,D using average_in[0], the get offset relative to average_out[0].  no longer
+      // needed since we carry around R,D
+      // Rin = input[0].average[N].R - input[0].measure[offset].dR / 3600.0;
+      // Din = input[0].average[N].D - input[0].measure[offset].dD / 3600.0;
+      // output[0].measure[Nmeas].dR = 3600.0*(output[0].average[n].R - Rin);
+      // output[0].measure[Nmeas].dD = 3600.0*(output[0].average[n].D - Din);
+
       output[0].measure[Nmeas].dbFlags  = 0;  // XXX why reset these?
       output[0].measure[Nmeas].averef   = n;
@@ -221,30 +227,49 @@
       // fprintf (stderr, "Nave : "OFF_T_FMT", Nmeas : "OFF_T_FMT", dR: %f, dD: %f, catID: %d\n",  n,  Nmeas, output[0].measure[Nmeas].dR, output[0].measure[Nmeas].dD, output[0].measure[i].catID);
 
-      // rationalize dR
-      if (output[0].measure[Nmeas].dR > +180.0*3600.0) {
+      float dRoff = dvoOffsetR(&output[0].measure[Nmeas], &output[0].average[n]);
+
+      // rationalize R
+      if (dRoff > +180.0*3600.0) {
 	// average on high end of boundary, move star up
-	Rin += 360.0;
-	output[0].measure[Nmeas].dR = 3600.0*(output[0].average[n].R - Rin);
-      }
-      if (output[0].measure[Nmeas].dR < -180.0*3600.0) {
+	output[0].measure[Nmeas].R += 360.0;
+	dRoff -= 360.0*3600.0;
+      }
+      if (dRoff < -180.0*3600.0) {
 	// average on low end of boundary, move star down
-	Rin -= 360.0;
-	output[0].measure[Nmeas].dR = 3600.0*(output[0].average[n].R - Rin);
-      }
-      if (fabs(output[0].measure[Nmeas].dR) > 10*RADIUS) {
-        // ok take declination into account and check again.
-        double cosD = cos(RAD_DEG*Din);
-        if (fabs(output[0].measure[Nmeas].dR*cosD) > 10*RADIUS) {
-
-            fprintf (stderr, "error: %10.6f,%10.6f vs %10.6f,%10.6f (%f,%f vs %f,%f)\n", 
-             output[0].average[n].R, output[0].average[n].D, Rin, Din,
-             X1[i], X2[Jmin], Y1[i], Y2[Jmin]);
-
-            // XXX abort on this? -- this is a bad failure...
+	output[0].measure[Nmeas].R -= 360.0;
+	dRoff += 360.0*3600.0;
+      }
+      if (fabs(dRoff) > 10*RADIUS) {
+        // take declination into account and check again.
+        double cosD = cos(RAD_DEG*output[0].average[n].D);
+        if (fabs(dRoff*cosD) > 10*RADIUS) {
+	  fprintf (stderr, "error: %10.6f,%10.6f vs %10.6f,%10.6f (%f,%f vs %f,%f)\n", 
+		   output[0].average[n].R, output[0].average[n].D, 
+		   output[0].measure[Nmeas].R, output[0].measure[Nmeas].D,
+		   X1[i], X2[Jmin], Y1[i], Y2[Jmin]);
+	  // XXX abort on this? -- this is a bad failure...
         }
       }
-      input[0].found[N] = Nmeas;
+      input[0].found_t[N] = Nmeas;
       output[0].average[n].Nmeasure ++;
       Nmeas ++;
+    }
+
+    // if lensing measurements exist, add them too
+    if (output[0].lensing) {
+      for (Nin = 0; Nin < input[0].average[N].Nlensing; Nin++) {
+	/* add to end of lensing list */
+	add_lens_link (&output[0].average[n], next_lens, Nlens, NLENS);
+	
+	// set the new lensing
+	off_t lensoff = input[0].average[N].lensingOffset + Nin;
+	output[0].lensing[Nlens] = input[0].lensing[lensoff];
+
+	output[0].lensing[Nlens].averef   = n;
+	output[0].lensing[Nlens].objID    = output[0].average[n].objID;
+	output[0].lensing[Nlens].catID    = output[0].catID;
+	output[0].average[n].Nlensing ++;
+	Nlens ++;
+      }
     }
 
@@ -273,5 +298,5 @@
     /* Nm is updated, but not written out in -update mode (for existing entries)
        Nm is recalculated in build_meas_links if loaded table is not sorted */
-    output[0].found[n] = Nmeas;
+    output[0].found_t[n] = Nmeas;
     i++;
   }
@@ -289,4 +314,9 @@
       REALLOCATE (output[0].measure, Measure, NMEAS);
     }
+    if (Nlens + input[0].average[N].Nlensing >= NLENS) {
+      NLENS = Nlens + input[0].average[N].Nlensing + 1000;
+      REALLOCATE (next_lens, off_t, NLENS);
+      REALLOCATE (output[0].lensing, Lensing, NLENS);
+    }
     if (Nave >= NAVE) {
       NAVE = Nave + 1000;
@@ -295,5 +325,5 @@
     }
 
-    if (input[0].found[N] >= 0) continue;
+    if (input[0].found_t[N] >= 0) continue;
     if (!IN_REGION (input[0].average[N].R, input[0].average[N].D)) continue;
 
@@ -348,5 +378,5 @@
 
       /* we set next[Nmeas] to -1 here, and update correctly below */
-      input[0].found[N] = Nmeas;
+      input[0].found_t[N] = Nmeas;
       next_meas[Nmeas] = -1;
       Nmeas ++;
@@ -356,4 +386,31 @@
       next_meas[Nmeas - Ngroup + j] = Nmeas - Ngroup + j + 1;
     }
+
+    /** add lensing for this input average object **/
+    if (output[0].lensing) {
+      output[0].average[Nave].lensingOffset  = Nlens;
+      for (Nin = 0; Nin < input[0].average[N].Nlensing; Nin ++) {
+	// supply the lensing values from this detection
+	off_t lensoff = input[0].average[N].lensingOffset + Nin;
+	output[0].lensing[Nlens]           = input[0].lensing[lensoff];
+
+	// the following lensing elements cannot be set until here:
+	output[0].lensing[Nlens].averef   = Nave;
+	output[0].lensing[Nlens].objID    = output[0].average[Nave].objID;
+	output[0].lensing[Nlens].catID    = output[0].catID;
+
+	// as we add lensing, update Nlensing to match
+	output[0].average[Nave].Nlensing ++;
+
+	/* we set next[Nlens] to -1 here, and update correctly below */
+	next_lens[Nlens] = -1;
+	Nlens ++;
+      }
+      int Ngroup = input[0].average[N].Nlensing;
+      for (j = 0; j < Ngroup - 1; j++) {
+	next_lens[Nlens - Ngroup + j] = Nlens - Ngroup + j + 1;
+      }
+    }
+
     Nave ++;
   }
@@ -363,4 +420,5 @@
   REALLOCATE (output[0].average, Average, Nave);
   REALLOCATE (output[0].measure, Measure, Nmeas);
+  REALLOCATE (output[0].lensing, Lensing, Nlens);
  
 # define NOSORT 0
@@ -370,12 +428,13 @@
     output[0].sorted = TRUE;
     output[0].measure = sort_measure (output[0].average, Nave, output[0].measure, Nmeas, next_meas);
+    output[0].lensing = sort_lensing (output[0].average, Nave, output[0].lensing, Nlens, next_lens);
   }
 
   /* note stars which have been found in this catalog */
   for (i = 0; i < input[0].Naverage; i++) {
-    if (input[0].found[i] > -1) {
-      input[0].found[i] = -2;
+    if (input[0].found_t[i] > -1) {
+      input[0].found_t[i] = -2;
     } else {
-      input[0].found[i] = -3;
+      input[0].found_t[i] = -3;
     }
   }
@@ -385,14 +444,14 @@
   output[0].Naverage = Nave;
   output[0].Nmeasure = Nmeas;
+  output[0].Nlensing = Nlens;
   output[0].Nsecf_mem = Nave*NsecfiltOut;
-  if (VERBOSE) fprintf (stderr, "Nstars, Nave, Nmeas: "OFF_T_FMT" "OFF_T_FMT" "OFF_T_FMT", ("OFF_T_FMT" matches)\n",  Nstars,  Nave,  Nmeas,  Nmatch);
+  if (VERBOSE) fprintf (stderr, "Nstars, Nave, Nmeas, Nlens: "OFF_T_FMT" "OFF_T_FMT" "OFF_T_FMT" "OFF_T_FMT", ("OFF_T_FMT" matches)\n",  Nstars,  Nave,  Nmeas,  Nlens, Nmatch);
 
   free (next_meas);
-
-  free (output[0].found);
+  free (next_lens);
+
   free (X2);
   free (Y2);
   free (N2);
-  free (input[0].found);
   free (X1);
   free (Y1);
@@ -411,5 +470,5 @@
    images have boundaries which are lines in pixels coords, but curve in RA and DEC
    
-   output[0].found[Ncat] but stars[Nstar].found
+   output[0].found_t[Ncat] but stars[Nstar].found
    
 */
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/replace_match.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/replace_match.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvomerge/src/replace_match.c	(revision 37403)
@@ -7,5 +7,4 @@
   unsigned int averef;
   unsigned int catID;
-  double Rin, Din;
 
   // find the matching photcode in the object's list of measurements
@@ -18,10 +17,11 @@
     measure_out[Nout] = measure_in[0];
 
-    Rin = average_in[0].R - measure_in[0].dR / 3600.0;
-    Din = average_in[0].D - measure_in[0].dD / 3600.0;
+    // old code: find R,D using average_in[0], the get offset relative to average_out[0].  no longer
+    // needed since we carry around R,D
+    // double Rin = average_in[0].R - measure_in[0].dR / 3600.0;
+    // double Din = average_in[0].D - measure_in[0].dD / 3600.0;
+    // measure_out[Nout].dR = 3600.0*(average_out[0].R - Rin);
+    // measure_out[Nout].dD = 3600.0*(average_out[0].D - Din);
 
-    /** dR,dD now represent arcsec **/
-    measure_out[Nout].dR       = 3600.0*(average_out[0].R - Rin);
-    measure_out[Nout].dD       = 3600.0*(average_out[0].D - Din);
     measure_out[Nout].dbFlags  = 0;  // XXX why reset these?
     measure_out[Nout].averef   = averef;
@@ -29,24 +29,25 @@
     measure_out[Nout].catID    = catID;
 
+    float dRoff = dvoOffsetR(&measure_out[Nout], average_out);
+
     // rationalize dR
-    if (measure_out[Nout].dR > +180.0*3600.0) {
+    if (dRoff > +180.0*3600.0) {
       // average on high end of boundary, move star up
-      Rin += 360.0;
-      measure_out[Nout].dR = 3600.0*(average_out[0].R - Rin);
+      measure_out[Nout].R += 360.0;
+      dRoff -= 360.0*3600.0;
     }
-    if (measure_out[Nout].dR < -180.0*3600.0) {
+    if (dRoff < -180.0*3600.0) {
       // average on low end of boundary, move star down
-      Rin -= 360.0;
-      measure_out[Nout].dR = 3600.0*(average_out[0].R - Rin);
+      measure_out[Nout].R -= 360.0;
+      dRoff += 360.0*3600.0;
     }
 
     // warn on surprisingly distant detections
-    if (fabs(measure_out[Nout].dR) > 10*RADIUS) {
+    if (fabs(dRoff) > 10*RADIUS) {
       // ok take declination into account and check again.
-      double cosD = cos(RAD_DEG*Din);
-      if (fabs(measure_out[Nout].dR*cosD) > 10*RADIUS) {
-
+      double cosD = cos(RAD_DEG*average_out[0].D);
+      if (fabs(dRoff*cosD) > 10*RADIUS) {
 	fprintf (stderr, "surprisingly distant detection: %10.6f,%10.6f vs %10.6f,%10.6f\n", 
-		 average_out[0].R, average_out[0].D, Rin, Din);
+		 average_out[0].R, average_out[0].D, measure_out[Nout].R, measure_out[Nout].D);
       }
     }
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvopsps/include/dvopsps.h
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvopsps/include/dvopsps.h	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvopsps/include/dvopsps.h	(revision 37403)
@@ -9,19 +9,27 @@
 
 typedef struct {
-  int imageID;
-  unsigned int ippDetectID;
+  uint64_t objID;
   uint64_t detectID;
   uint64_t ippObjID;
-  uint64_t objID;
-  int      photcode;
-  unsigned int flags;
-  float zp;
-  float zpErr;
-  float airMass;
-  float expTime;
+  unsigned int ippDetectID;
+  int imageID;
+  int catID;
   double ra;
   double dec;
   float raErr;
   float decErr;
+  float zp;
+  float telluricExt;
+  float airmass;
+  float expTime;
+
+  float Mpsf;
+  float dMpsf;
+  float Mkron;
+  float dMkron;
+  float Map;
+  float dMap;
+
+  unsigned int flags;
 } Detections;
 
@@ -78,9 +86,10 @@
       
 int    insert_detections_mysql_commit     PROTO((IOBuffer *buffer, MYSQL *mysql));
-int    insert_detections_mysql_value      PROTO((IOBuffer *buffer, Average *average, Measure *measure));
+// int    insert_detections_mysql_value      PROTO((IOBuffer *buffer, Average *average, Measure *measure));
 int    insert_detections_mysql_init       PROTO((IOBuffer *buffer));
 
 int    insert_detections_mysql_array      PROTO((MYSQL *mysql, Detections *detections, int Ndetections));
 int    insert_detections_mysql_detvalue   PROTO((IOBuffer *buffer, Detections *detection));
+int    assign_detection_values            PROTO((Detections *detection, Measure *measure, Average *average));
 
 int    init_detections                    PROTO(());
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvopsps/src/DetectionOps.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvopsps/src/DetectionOps.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvopsps/src/DetectionOps.c	(revision 37403)
@@ -1,6 +1,3 @@
 # include "dvopsps.h"
-# define BZERO_INT16 1.0*0x8000
-# define BZERO_INT32 1.0*0x80000000
-# define BZERO_INT64 1.0*0x8000000000000000
 
 # define GET_COLUMN(OUT,NAME,TYPE)					\
@@ -49,19 +46,25 @@
  
   // need to create and assign to flat-field correction
-  GET_COLUMN(imageID     , "imageID",     int);
-  GET_COLUMN(ippDetectID , "ippDetectID", int);
+  GET_COLUMN(objID       , "objID",       int64_t);
   GET_COLUMN(detectID    , "detectID",    int64_t);
   GET_COLUMN(ippObjID    , "ippObjID",    int64_t);
-  GET_COLUMN(objID       , "objID",       int64_t);
-  GET_COLUMN(photcode    , "photcode",    int);
-  GET_COLUMN(flags       , "flags",       int);
-  GET_COLUMN(zp          , "zp",          float);
-  GET_COLUMN(zpErr       , "zpErr",       float);
-  GET_COLUMN(airMass     , "airMass",     float);
-  GET_COLUMN(expTime     , "expTime",     float);
+  GET_COLUMN(ippDetectID , "ippDetectID", int);
+  GET_COLUMN(imageID     , "imageID",     int);
+  GET_COLUMN(catID       , "catID",       int);
   GET_COLUMN(ra          , "ra",          double); // XXX signed vs unsigned?
   GET_COLUMN(dec         , "dec",         double);
   GET_COLUMN(raErr       , "raErr",       float);
   GET_COLUMN(decErr      , "decErr",      float);
+  GET_COLUMN(zp          , "zp",          float);
+  GET_COLUMN(telluricExt , "telluricExt", float);
+  GET_COLUMN(airmass     , "airmass",     float);
+  GET_COLUMN(expTime     , "expTime",     float);
+  GET_COLUMN(Mpsf        , "Mpsf",        float);
+  GET_COLUMN(dMpsf       , "dMpsf",       float);
+  GET_COLUMN(Mkron       , "Mkron",       float);
+  GET_COLUMN(dMkron      , "dMkron",      float);
+  GET_COLUMN(Map         , "Map",         float);
+  GET_COLUMN(dMap        , "dMap",        float);
+  GET_COLUMN(flags       , "flags",       int);
   gfits_free_header (&theader);
   gfits_free_table  (&ftable);
@@ -69,37 +72,49 @@
   ALLOCATE (detections, Detections, Nrow);
   for (i = 0; i < Nrow; i++) {
-    detections[i].imageID      = imageID[i];    
-    detections[i].ippDetectID  = ippDetectID[i];
+    detections[i].objID        = objID[i];      
     detections[i].detectID     = detectID[i];   
     detections[i].ippObjID     = ippObjID[i];   
-    detections[i].objID        = objID[i];      
-    detections[i].photcode     = photcode[i];      
-    detections[i].flags        = flags[i];      
-    detections[i].zp           = zp[i];         
-    detections[i].zpErr        = zpErr[i];      
-    detections[i].airMass      = airMass[i];    
-    detections[i].expTime      = expTime[i];    
+    detections[i].ippDetectID  = ippDetectID[i];
+    detections[i].imageID      = imageID[i];    
+    detections[i].catID        = catID[i];    
     detections[i].ra           = ra[i];         
     detections[i].dec          = dec[i];        
     detections[i].raErr        = raErr[i];      
     detections[i].decErr       = decErr[i];     
+    detections[i].zp           = zp[i];         
+    detections[i].telluricExt  = telluricExt[i];      
+    detections[i].airmass      = airmass[i];    
+    detections[i].expTime      = expTime[i];    
+    detections[i].Mpsf         = Mpsf[i];    
+    detections[i].dMpsf        = dMpsf[i];    
+    detections[i].Mkron        = Mkron[i];    
+    detections[i].dMkron       = dMkron[i];    
+    detections[i].Map          = Map[i];    
+    detections[i].dMap         = dMap[i];    
+    detections[i].flags        = flags[i];      
   }
   fprintf (stderr, "loaded data for %lld detections\n", (long long) Nrow);
 
-  free (imageID    );
-  free (ippDetectID);
+  free (objID      );
   free (detectID   );
   free (ippObjID   );
-  free (objID      );
-  free (photcode   );
-  free (flags      );
-  free (zp         );
-  free (zpErr      );
-  free (airMass    );
-  free (expTime    );
+  free (ippDetectID);
+  free (imageID    );
+  free (catID      );
   free (ra         );
   free (dec        );
   free (raErr      );
   free (decErr     );
+  free (zp         );
+  free (telluricExt);
+  free (airmass    );
+  free (expTime    );
+  free (Mpsf       );
+  free (dMpsf      );
+  free (Mkron      );
+  free (dMkron     );
+  free (Map        );
+  free (dMap       );
+  free (flags      );
 
   gfits_free_header (&header);
@@ -149,22 +164,25 @@
 
   // XXX need to get the bzero values right
-  gfits_define_bintable_column (&theader, "J", "imageID",     NULL, NULL, 1.0, BZERO_INT32);
-  gfits_define_bintable_column (&theader, "J", "ippDetectID", NULL, NULL, 1.0, BZERO_INT32);
+  gfits_define_bintable_column (&theader, "K", "objID",       NULL, NULL, 1.0, 0);
   gfits_define_bintable_column (&theader, "K", "detectID",    NULL, NULL, 1.0, 0);
   gfits_define_bintable_column (&theader, "K", "ippObjID",    NULL, NULL, 1.0, 0);
-  gfits_define_bintable_column (&theader, "K", "objID",       NULL, NULL, 1.0, 0);
-  // gfits_define_bintable_column (&theader, "K", "detectID",    NULL, NULL, 1.0, BZERO_INT64);
-  // gfits_define_bintable_column (&theader, "K", "ippObjID",    NULL, NULL, 1.0, BZERO_INT64);
-  // gfits_define_bintable_column (&theader, "K", "objID",       NULL, NULL, 1.0, BZERO_INT64);
-  gfits_define_bintable_column (&theader, "J", "photcode",    NULL, NULL, 1.0, 0.0);
-  gfits_define_bintable_column (&theader, "J", "flags",       NULL, NULL, 1.0, BZERO_INT32);
-  gfits_define_bintable_column (&theader, "E", "zp",          NULL, NULL, 1.0, 0.0);
-  gfits_define_bintable_column (&theader, "E", "zpErr",       NULL, NULL, 1.0, 0.0);
-  gfits_define_bintable_column (&theader, "E", "airMass",     NULL, NULL, 1.0, 0.0);
-  gfits_define_bintable_column (&theader, "E", "expTime",     NULL, NULL, 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "J", "ippDetectID", NULL, NULL, 1.0, FT_BZERO_INT32);
+  gfits_define_bintable_column (&theader, "J", "imageID",     NULL, NULL, 1.0, FT_BZERO_INT32);
+  gfits_define_bintable_column (&theader, "J", "catID",       NULL, NULL, 1.0, FT_BZERO_INT32);
   gfits_define_bintable_column (&theader, "D", "ra",          NULL, NULL, 1.0, 0.0);
   gfits_define_bintable_column (&theader, "D", "dec",         NULL, NULL, 1.0, 0.0);
   gfits_define_bintable_column (&theader, "E", "raErr",       NULL, NULL, 1.0, 0.0);
   gfits_define_bintable_column (&theader, "E", "decErr",      NULL, NULL, 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E", "zp",          NULL, NULL, 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E", "telluricExt", NULL, NULL, 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E", "airmass",     NULL, NULL, 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E", "expTime",     NULL, NULL, 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E", "Mpsf",        NULL, NULL, 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E", "dMpsf",       NULL, NULL, 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E", "Mkron",       NULL, NULL, 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E", "dMkron",      NULL, NULL, 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E", "Map",         NULL, NULL, 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E", "dMap",        NULL, NULL, 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "J", "flags",       NULL, NULL, 1.0, FT_BZERO_INT32);
 
   // generate the output array that carries the data
@@ -172,71 +190,95 @@
 
   // create intermediate storage arrays
-   int32_t   *imageID     ; ALLOCATE (imageID     ,   int32_t, Ndetections);
-  uint32_t   *ippDetectID ; ALLOCATE (ippDetectID ,  uint32_t, Ndetections);
+  uint64_t   *objID       ; ALLOCATE (objID       ,  uint64_t, Ndetections);
   uint64_t   *detectID    ; ALLOCATE (detectID    ,  uint64_t, Ndetections);
   uint64_t   *ippObjID    ; ALLOCATE (ippObjID    ,  uint64_t, Ndetections);
-  uint64_t   *objID       ; ALLOCATE (objID       ,  uint64_t, Ndetections);
-  int        *photcode    ; ALLOCATE (photcode    ,  int,      Ndetections);
-  uint32_t   *flags       ; ALLOCATE (flags       ,  uint32_t, Ndetections);
-  float      *zp          ; ALLOCATE (zp          ,  float,    Ndetections);
-  float      *zpErr       ; ALLOCATE (zpErr       ,  float,    Ndetections);
-  float      *airMass     ; ALLOCATE (airMass     ,  float,    Ndetections);
-  float      *expTime     ; ALLOCATE (expTime     ,  float,    Ndetections);
+  uint32_t   *ippDetectID ; ALLOCATE (ippDetectID ,  uint32_t, Ndetections);
+   int32_t   *imageID     ; ALLOCATE (imageID     ,   int32_t, Ndetections);
+   int32_t   *catID       ; ALLOCATE (catID       ,   int32_t, Ndetections);
   double     *ra          ; ALLOCATE (ra          ,  double,   Ndetections);
   double     *dec         ; ALLOCATE (dec         ,  double,   Ndetections);
   float      *raErr       ; ALLOCATE (raErr       ,  float,    Ndetections);
   float      *decErr      ; ALLOCATE (decErr      ,  float,    Ndetections);
+  float      *zp          ; ALLOCATE (zp          ,  float,    Ndetections);
+  float      *telluricExt ; ALLOCATE (telluricExt ,  float,    Ndetections);
+  float      *airmass     ; ALLOCATE (airmass     ,  float,    Ndetections);
+  float      *expTime     ; ALLOCATE (expTime     ,  float,    Ndetections);
+  float      *Mpsf        ; ALLOCATE (Mpsf        ,  float,    Ndetections);
+  float      *dMpsf       ; ALLOCATE (dMpsf       ,  float,    Ndetections);
+  float      *Mkron       ; ALLOCATE (Mkron       ,  float,    Ndetections);
+  float      *dMkron      ; ALLOCATE (dMkron      ,  float,    Ndetections);
+  float      *Map         ; ALLOCATE (Map         ,  float,    Ndetections);
+  float      *dMap        ; ALLOCATE (dMap        ,  float,    Ndetections);
+  uint32_t   *flags       ; ALLOCATE (flags       ,  uint32_t, Ndetections);
 
   // assign the storage arrays
   for (i = 0; i < Ndetections; i++) {
-    imageID[i]     = detections[i].imageID     ;
-    ippDetectID[i] = detections[i].ippDetectID ;
+    objID[i]       = detections[i].objID       ;
     detectID[i]    = detections[i].detectID    ;
     ippObjID[i]    = detections[i].ippObjID    ;
-    objID[i]       = detections[i].objID       ;
-    photcode[i]    = detections[i].photcode    ;
-    flags[i]       = detections[i].flags       ;
-    zp[i]          = detections[i].zp          ;
-    zpErr[i]       = detections[i].zpErr       ;
-    airMass[i]     = detections[i].airMass     ;
-    expTime[i]     = detections[i].expTime     ;
+    ippDetectID[i] = detections[i].ippDetectID ;
+    imageID[i]     = detections[i].imageID     ;
+    catID[i]       = detections[i].catID       ;
     ra[i]          = detections[i].ra          ;
     dec[i]         = detections[i].dec         ;
     raErr[i]       = detections[i].raErr       ;
     decErr[i]      = detections[i].decErr      ;
+    zp[i]          = detections[i].zp          ;
+    telluricExt[i] = detections[i].telluricExt ;
+    airmass[i]     = detections[i].airmass     ;
+    expTime[i]     = detections[i].expTime     ;
+    Mpsf[i]        = detections[i].Mpsf        ;
+    dMpsf[i]       = detections[i].dMpsf       ;
+    Mkron[i]       = detections[i].Mkron       ;
+    dMkron[i]      = detections[i].dMkron      ;
+    Map[i]         = detections[i].Map         ;
+    dMap[i]        = detections[i].dMap        ;
+    flags[i]       = detections[i].flags       ;
   }
 
   // add the columns to the output array
-  gfits_set_bintable_column (&theader, &ftable, "imageID",     imageID     , Ndetections);
-  gfits_set_bintable_column (&theader, &ftable, "ippDetectID", ippDetectID , Ndetections);
+  gfits_set_bintable_column (&theader, &ftable, "objID",       objID       , Ndetections);
   gfits_set_bintable_column (&theader, &ftable, "detectID",    detectID    , Ndetections);
   gfits_set_bintable_column (&theader, &ftable, "ippObjID",    ippObjID    , Ndetections);
-  gfits_set_bintable_column (&theader, &ftable, "objID",       objID       , Ndetections);
-  gfits_set_bintable_column (&theader, &ftable, "photcode",    photcode    , Ndetections);
-  gfits_set_bintable_column (&theader, &ftable, "flags",       flags       , Ndetections);
-  gfits_set_bintable_column (&theader, &ftable, "zp",          zp          , Ndetections);
-  gfits_set_bintable_column (&theader, &ftable, "zpErr",       zpErr       , Ndetections);
-  gfits_set_bintable_column (&theader, &ftable, "airMass",     airMass     , Ndetections);
-  gfits_set_bintable_column (&theader, &ftable, "expTime",     expTime     , Ndetections);
+  gfits_set_bintable_column (&theader, &ftable, "ippDetectID", ippDetectID , Ndetections);
+  gfits_set_bintable_column (&theader, &ftable, "imageID",     imageID     , Ndetections);
+  gfits_set_bintable_column (&theader, &ftable, "catID",       catID       , Ndetections);
   gfits_set_bintable_column (&theader, &ftable, "ra",          ra          , Ndetections);
   gfits_set_bintable_column (&theader, &ftable, "dec",         dec         , Ndetections);
   gfits_set_bintable_column (&theader, &ftable, "raErr",       raErr       , Ndetections);
   gfits_set_bintable_column (&theader, &ftable, "decErr",      decErr      , Ndetections);
-
-  free (imageID     );
-  free (ippDetectID );
+  gfits_set_bintable_column (&theader, &ftable, "zp",          zp          , Ndetections);
+  gfits_set_bintable_column (&theader, &ftable, "telluricExt", telluricExt , Ndetections);
+  gfits_set_bintable_column (&theader, &ftable, "airmass",     airmass     , Ndetections);
+  gfits_set_bintable_column (&theader, &ftable, "expTime",     expTime     , Ndetections);
+  gfits_set_bintable_column (&theader, &ftable, "Mpsf",        Mpsf        , Ndetections);
+  gfits_set_bintable_column (&theader, &ftable, "dMpsf",       dMpsf       , Ndetections);
+  gfits_set_bintable_column (&theader, &ftable, "Mkron",       Mkron       , Ndetections);
+  gfits_set_bintable_column (&theader, &ftable, "dMkron",      dMkron      , Ndetections);
+  gfits_set_bintable_column (&theader, &ftable, "Map",         Map         , Ndetections);
+  gfits_set_bintable_column (&theader, &ftable, "dMap",        dMap        , Ndetections);
+  gfits_set_bintable_column (&theader, &ftable, "flags",       flags       , Ndetections);
+
+  free (objID       );
   free (detectID    );
   free (ippObjID    );
-  free (objID       );
-  free (photcode    );
-  free (flags       );
-  free (zp          );
-  free (zpErr       );
-  free (airMass     );
-  free (expTime     );
+  free (ippDetectID );
+  free (imageID     );
+  free (catID       );
   free (ra          );
   free (dec         );
   free (raErr       );
   free (decErr      );
+  free (zp          );
+  free (telluricExt );
+  free (airmass     );
+  free (expTime     );
+  free (Mpsf        );
+  free (dMpsf       );
+  free (Mkron       );
+  free (dMkron      );
+  free (Map         );
+  free (dMap        );
+  free (flags       );
 
   gfits_fwrite_Theader (f, &theader);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvopsps/src/insert_detections_dvopsps.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvopsps/src/insert_detections_dvopsps.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvopsps/src/insert_detections_dvopsps.c	(revision 37403)
@@ -2,10 +2,4 @@
 # define USE_MYSQL 1
 // # define SAVE_REMOTE 1
-
-# define MARKTIME(MSG,...) {			\
-    float dtime;				\
-    gettimeofday (&stop, (void *) NULL);	\
-    dtime = DTIME (stop, start);		\
-    fprintf (stderr, MSG, __VA_ARGS__); }
 
 // we have two ways of writing to the mysql database:
@@ -74,5 +68,5 @@
     catalog.Nsecfilt  = GetPhotcodeNsecfilt ();
 
-    if (!dvo_catalog_open (&catalog, skylist[0].regions[i], VERBOSE, "w")) {
+    if (!dvo_catalog_open (&catalog, skylist[0].regions[i], VERBOSE, "r")) {
       fprintf (stderr, "ERROR: failure reading catalog %s\n", catalog.filename);
       exit (1);
@@ -101,4 +95,9 @@
     dvo_catalog_unlock (&catalog);
     dvo_catalog_free (&catalog);
+
+    if (!status) {
+      fprintf (stderr, "failure to insert data in mysql\n");
+      exit (2);
+    }
   }
 
@@ -245,6 +244,4 @@
   buffer.Nalloc = 0;
 
-  struct timeval start, stop;
-
   if (Ndetections == 0) return TRUE;
 
@@ -254,5 +251,5 @@
   int Ninsert = 0;
 
-  gettimeofday (&start, (void *) NULL);
+  INITTIME;
   for (i = 0; i < Ndetections; i++) {
 
@@ -289,24 +286,2 @@
 }
 
-# define PRINT_FLOAT(BUFFER,FIELD,FORMAT)		  \
-  if (!isfinite(FIELD)) PrintIOBuffer (BUFFER, "NULL, "); \
-  else PrintIOBuffer (BUFFER, FORMAT, FIELD); 
-
-int insert_detections_mysql_detvalue (IOBuffer *buffer, Detections *detection) {
-
-  PrintIOBuffer (buffer, "(%d, ", detection->imageID);	  // imageID
-  PrintIOBuffer (buffer, "%u, ", detection->ippDetectID); // ippDetectID
-  PrintIOBuffer (buffer, "%lu, ", detection->detectID);	  // detectID
-  PrintIOBuffer (buffer, "%lu, ", detection->ippObjID);	  // ippObjID
-  PrintIOBuffer (buffer, "%lu, ", detection->objID);	  // objID
-  PrintIOBuffer (buffer, "%u, ", detection->flags);	  // flags
-  PRINT_FLOAT(buffer, detection->zp,      "%.6f, ");
-  PRINT_FLOAT(buffer, detection->zpErr,   "%.6f, ");
-  PRINT_FLOAT(buffer, detection->airMass, "%.6f, ");
-  PRINT_FLOAT(buffer, detection->expTime, "%.6f, ");
-  PRINT_FLOAT(buffer, detection->ra,      "%.8f, ");
-  PRINT_FLOAT(buffer, detection->dec,     "%.8f, ");
-  PRINT_FLOAT(buffer, detection->raErr,   "%.6f, ");
-  PRINT_FLOAT(buffer, detection->decErr,  "%.6f),\n");
-  return TRUE;
-}
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvopsps/src/insert_detections_dvopsps_catalog.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvopsps/src/insert_detections_dvopsps_catalog.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvopsps/src/insert_detections_dvopsps_catalog.c	(revision 37403)
@@ -1,10 +1,4 @@
 # include "dvopsps.h"
 # define DEBUG 0
-
-# define MARKTIME(MSG,...) {			\
-    float dtime;				\
-    gettimeofday (&stop, (void *) NULL);	\
-    dtime = DTIME (stop, start);		\
-    fprintf (stderr, MSG, __VA_ARGS__); }
 
 int Ndetections = 0;
@@ -12,4 +6,6 @@
 Detections *detections = NULL;
 
+static float ZeroPoint = 25.0;
+
 int init_detections () {
   NDETECTIONS = 1000;
@@ -21,4 +17,6 @@
 
   off_t i, j;
+
+  ZeroPoint = GetZeroPoint();
 
   int missingID = 0;
@@ -53,25 +51,7 @@
       if (measure->photcode >=  PHOTCODE_END) continue;
 
-      PhotCode *code = GetPhotcodebyCode(measure->photcode);
-
-      detections[Ndetections].imageID     = measure->imageID;    // imageID
-      detections[Ndetections].ippDetectID = measure->detID;   // ippDetectID
-      detections[Ndetections].detectID    = measure->extID;   // detectID
-      detections[Ndetections].ippObjID    = ((uint64_t)average->catID * 1000000000) + (uint64_t)average->objID; // ippObjID
-      // NOTE: this is better, but the above is the current ippToPsps value
-      // detections[Ndetections]. ((uint64_t)average->catID << 32) + (uint64_t)average->objID; // ippObjID
-      detections[Ndetections].objID	   = average->extID;   // objID
-      detections[Ndetections].photcode	   = measure->photcode;   // photcode
-      detections[Ndetections].flags 	   = measure->dbFlags;  // flags
-      detections[Ndetections].zp 	   = code->C * 0.001 + code->K * (measure->airmass - 1) - measure->Mcal;   // zp
-      detections[Ndetections].zpErr 	   = measure->dMcal;    // zpErr
-      detections[Ndetections].airMass      = measure->airmass;
-      detections[Ndetections].expTime      = pow(10.0, 0.4 * measure->dt);    // expTime
-      detections[Ndetections].ra 	   = average->R - measure->dR / 3600.;    // ra
-      detections[Ndetections].dec 	   = average->D - measure->dD / 3600.;    // dec
-      detections[Ndetections].raErr 	   = measure->dXccd * 0.01 * fabs(measure->pltscale); // estimate of raErr
-      detections[Ndetections].decErr	   = measure->dYccd * 0.01 * fabs(measure->pltscale); // estimate of decErr
-
+      assign_detection_values (&detections[Ndetections], measure, average);
       Ndetections ++;
+
       myAssert (Ndetections <= NDETECTIONS, "programming error");
     }
@@ -107,5 +87,4 @@
   off_t i, j;
   int missingID = 0;
-  struct timeval start, stop;
 
   IOBuffer buffer;
@@ -117,5 +96,7 @@
   off_t found = 0;
 
-  gettimeofday (&start, (void *) NULL);
+  ZeroPoint = GetZeroPoint();
+
+  INITTIME;
   insert_detections_mysql_init (&buffer);
   int Ninsert = 0;
@@ -150,5 +131,8 @@
 
       // XXX check return status
-      if (!insert_detections_mysql_value (&buffer, &average[i], &measure[Nmeas])) {
+      Detections detection;
+      assign_detection_values (&detection, &measure[Nmeas], &average[i]);
+
+      if (!insert_detections_mysql_detvalue (&buffer, &detection)) {
 	fprintf (stderr, "failure to insert detections in mysql\n");
 	status = FALSE;
@@ -201,46 +185,11 @@
   }
 
-  // PrintIOBuffer (buffer, "INSERT INTO dvoDetectionFull (imageID, ippDetectID, detectID, ippObjID, objID, photcode, flags, zp, zpErr, airMass, expTime, ra, dec_, raErr, decErr) VALUES \n");
-  PrintIOBuffer (buffer, "INSERT INTO dvoDetectionFull (imageID, ippDetectID, detectID, ippObjID, objID, flags, zp, zpErr, airMass, expTime, ra, dec_, raErr, decErr) VALUES \n");
-
-  return TRUE;
-}
-
-# define PRINT_FLOAT(BUFFER,FIELD,FORMAT)		  \
-  if (isinf(FIELD) || isnan(FIELD)) PrintIOBuffer (BUFFER, "NULL, ");	\
-  else PrintIOBuffer (BUFFER, FORMAT, FIELD); 
-
-int insert_detections_mysql_value (IOBuffer *buffer, Average *average, Measure *measure) {
-
-  PhotCode *code = GetPhotcodebyCode(measure->photcode);
-  PrintIOBuffer (buffer, "(%d, ", measure->imageID);	  // imageID
-  PrintIOBuffer (buffer, "%u, ", measure->detID); // ippDetectID
-  PrintIOBuffer (buffer, "%lu, ", measure->extID);	  // detectID
-  PrintIOBuffer (buffer, "%lu, ", ((uint64_t)average->catID * 1000000000) + (uint64_t)average->objID);	  // ippObjID
-  // NOTE: the following is better, but the above is the current ippToPsps value
-  // ((uint64_t)average->catID << 32) + (uint64_t)average->objID, // ippObjID
-  PrintIOBuffer (buffer, "%lu, ", average->extID);	  // objID
-  // XXX PrintIOBuffer (buffer, "%d, ", measure->photcode);	  // photcode
-  PrintIOBuffer (buffer, "%u, ", measure->dbFlags);	  // flags
-
-  float zp = code->C * 0.001 + code->K * (measure->airmass - 1) - measure->Mcal;
-  float exptime = pow(10.0, 0.4 * measure->dt);
-  double ra  = average->R - measure->dR / 3600.0;
-  double dec = average->D - measure->dD / 3600.0;
-  double dR = measure->dXccd * 0.01 * fabs(measure->pltscale);
-  double dD = measure->dYccd * 0.01 * fabs(measure->pltscale);
-
-  PRINT_FLOAT(buffer, zp,               "%.6f, ");
-  PRINT_FLOAT(buffer, measure->dMcal,   "%.6f, ");
-  PRINT_FLOAT(buffer, measure->airmass, "%.6f, ");
-  PRINT_FLOAT(buffer, exptime,          "%.6f, ");
-  PRINT_FLOAT(buffer, ra,               "%.8f, ");
-  PRINT_FLOAT(buffer, dec,              "%.8f, ");
-  PRINT_FLOAT(buffer, dR,               "%.6f, ");
-  PRINT_FLOAT(buffer, dD,               "%.6f),\n");
-  
-  return TRUE;
-}
-    
+  PrintIOBuffer (buffer, "INSERT INTO dvoDetectionFull (objID, detectID, ippObjID, ippDetectID, imageID, catID, ");
+  PrintIOBuffer (buffer, "ra, dec_, raErr, decErr, zp, telluricExt, airmass, expTime, ");
+  PrintIOBuffer (buffer, "Mpsf, dMpsf, Mkron, dMkron, Map, dMap, flags) VALUES \n");
+
+  return TRUE;
+}
+
 int insert_detections_mysql_commit (IOBuffer *buffer, MYSQL *mysql) {
 
@@ -261,5 +210,4 @@
   // XXX check return status
   if (mysql) {
-    if (DEBUG) fprintf (stderr, "%s\n", buffer->buffer);
     int mysqlStatus = mysql_query(mysql, buffer->buffer); 
     if (mysqlStatus) {
@@ -267,4 +215,5 @@
       fprintf (stderr, "%s\n", mysql_error(mysql));
       fprintf (stderr, "Nbuffer: %d\n", buffer->Nbuffer);
+      if (DEBUG) fprintf (stderr, "%s\n", buffer->buffer);
       status = FALSE;
     }
@@ -277,2 +226,117 @@
   return status;
 }
+
+# define PRINT_FLOAT(BUFFER,FIELD,FORMAT)		  \
+  if (!isfinite(FIELD)) PrintIOBuffer (BUFFER, "NULL, "); \
+  else PrintIOBuffer (BUFFER, FORMAT, FIELD); 
+
+int insert_detections_mysql_detvalue (IOBuffer *buffer, Detections *detection) {
+
+  if (detection->detectID == 164458937060000101) {
+    fprintf (stderr, "isfinite: %d\n", isfinite(detection->dMpsf));
+    fprintf (stderr, "isnan: %d\n", isnan(detection->dMpsf));
+    fprintf (stderr, "isinf: %d\n", isinf(detection->dMpsf));
+  }
+
+  PrintIOBuffer (buffer, "(%lu, ", detection->objID);	    // objID
+  PrintIOBuffer (buffer,  "%lu, ", detection->detectID);    // detectID
+  PrintIOBuffer (buffer,  "%lu, ", detection->ippObjID);    // ippObjID
+  PrintIOBuffer (buffer,  "%u,  ", detection->ippDetectID); // ippDetectID
+  PrintIOBuffer (buffer,  "%d,  ", detection->imageID);	    // imageID
+  PrintIOBuffer (buffer,  "%d,  ", detection->catID);	    // DVO Catalog ID
+
+  PRINT_FLOAT(buffer, detection->ra,          "%.8f, ");
+  PRINT_FLOAT(buffer, detection->dec,         "%.8f, ");
+  PRINT_FLOAT(buffer, detection->raErr,       "%.6f, ");
+  PRINT_FLOAT(buffer, detection->decErr,      "%.6f, ");
+  PRINT_FLOAT(buffer, detection->zp,          "%.6f, ");
+  PRINT_FLOAT(buffer, detection->telluricExt, "%.6f, ");
+  PRINT_FLOAT(buffer, detection->airmass,     "%.6f, ");
+  PRINT_FLOAT(buffer, detection->expTime,     "%.6f, ");
+
+  PRINT_FLOAT(buffer, detection->Mpsf,        "%.6f, ");
+  PRINT_FLOAT(buffer, detection->dMpsf,       "%.6f, ");
+  PRINT_FLOAT(buffer, detection->Mkron,       "%.6f, ");
+  PRINT_FLOAT(buffer, detection->dMkron,      "%.6f, ");
+  PRINT_FLOAT(buffer, detection->Map,         "%.6f, ");
+  PRINT_FLOAT(buffer, detection->dMap,        "%.6f, ");
+
+  PrintIOBuffer (buffer, "%u),\n", detection->flags);	  // flags
+  return TRUE;
+}
+
+float getMagFromValueOrFlux (float flux, float mag, float zp) {
+
+  // first, if mag is finite, use mag:
+  if (isfinite(mag)) {
+    return (zp + mag - ZeroPoint);
+  }
+
+  if (isfinite(flux) && (flux > 0.0)) {
+    // fprintf (stderr, "funny flux: %f with mag %f\n", flux, mag);
+    return (zp - 2.5*log10(flux));
+  }
+
+  if (isfinite(flux) && (flux <= 0.0)) {
+    return (NAN);
+  }
+  return (NAN);
+}
+
+float getdMagFromValueOrFlux (float flux, float dflux, float dmag) {
+
+  // first, if mag is finite, use mag:
+  if (isfinite(dmag)) {
+    return (dmag);
+  }
+
+  if (isfinite(flux) && isfinite(dflux)) {
+    return (dflux / fabs(flux));
+  }
+  return (NAN);
+}
+
+int assign_detection_values (Detections *detection, Measure *measure, Average *average) {
+
+  PhotCode *code = GetPhotcodebyCode(measure->photcode);
+
+  uint64_t ippObjID = ((uint64_t)average->catID << 32) + (uint64_t)average->objID; // ippObjID
+
+  float nominalZP   = code->C * 0.001 + code->K * (measure->airmass - 1);
+  float zp          = nominalZP - measure->Mcal;
+  float telluricExt = - measure->Mcal;
+  float expTime     = pow(10.0, 0.4 * measure->dt);
+  float airmass     = measure->airmass;
+
+  detection->objID	  = average->extID;   // objID
+  detection->detectID     = measure->extID;   // detectID
+  detection->ippObjID     = ippObjID;	      // ippObjID
+  detection->ippDetectID  = measure->detID;   // ippDetectID
+  detection->imageID      = measure->imageID; // imageID
+  detection->catID        = measure->catID;   // catID
+
+  detection->ra 	  = measure->R;    // ra
+  detection->dec 	  = measure->D;    // dec
+  detection->raErr 	  = measure->dXccd * 0.01 * fabs(measure->pltscale); // estimate of raErr
+  detection->decErr	  = measure->dYccd * 0.01 * fabs(measure->pltscale); // estimate of decErr
+
+  detection->zp 	  = zp;
+  detection->telluricExt  = telluricExt;
+  detection->airmass      = airmass;
+  detection->expTime      = expTime;
+
+  // XXX clean this up with dvo_photcode_ops calls:
+  // if (isfinite(measure->FluxPSF) && (measure->FluxPSF < 0.0)) 
+  detection->Mpsf  = getMagFromValueOrFlux (measure->FluxPSF,  measure->M,     zp);
+  detection->Mkron = getMagFromValueOrFlux (measure->FluxKron, measure->Mkron, zp);
+  detection->Map   = getMagFromValueOrFlux (measure->FluxAp,   measure->Map,   zp);
+
+  detection->dMpsf  = getdMagFromValueOrFlux (measure->FluxPSF,  measure->dFluxPSF,  measure->dM);
+  detection->dMkron = getdMagFromValueOrFlux (measure->FluxKron, measure->dFluxKron, measure->dMkron);
+  detection->dMap   = getdMagFromValueOrFlux (measure->FluxAp,   measure->dFluxAp,   measure->dMap);
+
+  detection->flags  = measure->dbFlags;  // flags
+
+  return TRUE;
+}
+
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvopsps/src/insert_objects_dvopsps.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvopsps/src/insert_objects_dvopsps.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvopsps/src/insert_objects_dvopsps.c	(revision 37403)
@@ -56,5 +56,5 @@
     catalog.Nsecfilt  = GetPhotcodeNsecfilt ();
 
-    if (!dvo_catalog_open (&catalog, skylist[0].regions[i], VERBOSE, "w")) {
+    if (!dvo_catalog_open (&catalog, skylist[0].regions[i], VERBOSE, "r")) {
       fprintf (stderr, "ERROR: failure reading catalog %s\n", catalog.filename);
       exit (1);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvopsps/src/insert_objects_dvopsps_catalog.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvopsps/src/insert_objects_dvopsps_catalog.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvopsps/src/insert_objects_dvopsps_catalog.c	(revision 37403)
@@ -2,15 +2,8 @@
 # define DEBUG 0
 
-# define MARKTIME(MSG,...) {			\
-    float dtime;				\
-    gettimeofday (&stop, (void *) NULL);	\
-    dtime = DTIME (stop, start);		\
-    fprintf (stderr, MSG, __VA_ARGS__); }
-
 int insert_objects_dvopsps_catalog (Catalog *catalog, char *basename, MYSQL *mysql) {
 
   off_t i;
   int missingID = 0;
-  struct timeval start, stop;
 
   IOBuffer ave_buffer, sec_buffer;
@@ -31,5 +24,5 @@
   insert_objects_mysql_create_tables (cleanname, mysql);
 
-  gettimeofday (&start, (void *) NULL);
+  INITTIME;
   insert_objects_mysql_init (&ave_buffer, &sec_buffer, cleanname);
   int Ninsert = 0;
@@ -95,37 +88,47 @@
   bzero (buffer.buffer, buffer.Nalloc);
 
+  // Only send the necessary fields (eg, do not sent parallax and pm)
   PrintIOBuffer (&buffer, "CREATE TABLE %s_cpt ("
-		 "RA DOUBLE,  "          
-		 "DEC_ DOUBLE,  "         
-		 "RA_ERR FLOAT,  "      
-		 "DEC_ERR FLOAT,  "     
-		 "U_RA FLOAT,  "        
-		 "U_DEC FLOAT,  "       
-		 "V_RA_ERR FLOAT,  "    
-		 "V_DEC_ERR FLOAT,  "   
-		 "PAR FLOAT,  "         
-		 "PAR_ERR FLOAT,  "     
-		 "CHISQ_POS FLOAT,  "   
-		 "CHISQ_PM FLOAT,  "    
-		 "CHISQ_PAP FLOAT,  "   
-		 "MEAN_EPOCH INT,  "  
-		 "TIME_RANGE INT,  "  
-		 "PSF_QF FLOAT, "      
-		 "PSF_QF_PERF FLOAT,  " 
-		 "STARGAL_SEP FLOAT,  " 
-		 "NUMBER_POS SMALLINT,  "  
-		 "NMEASURE SMALLINT,  "    
-		 "NMISSING SMALLINT,  "    
-		 "NEXTEND SMALLINT,  "     
-		 "OFF_MEASURE INT,  " 
-		 "OFF_MISSING INT,  " 
-		 "OFF_EXTEND INT,  "  
-		 "FLAGS INT,  "       
-		 "PHOTFLAGS_U INT,  " 
-		 "PHOTFLAGS_L INT,  " 
-		 "OBJ_ID INT,  "      
-		 "CAT_ID INT,  "      
-		 "EXT_ID BIGINT"
+		 "EXT_ID        BIGINT,   "
+		 "OBJ_ID        INT,      "      
+		 "CAT_ID        INT,      " 
+		 "TESS_ID       TINYINT,  " 
+		 "PROJECTION_ID SMALLINT, " 
+		 "SKYCELL_ID    TINYINT,  " 
+		 "RA_STK        DOUBLE,   "          
+		 "DEC_STK       DOUBLE,   "         
+		 "RA_STK_ERR    FLOAT,    "      
+		 "DEC_STK_ERR   FLOAT,    "     
+		 "RA_MEAN       DOUBLE,   "          
+		 "DEC_MEAN      DOUBLE,   "         
+		 "RA_ERR        FLOAT,    "      
+		 "DEC_ERR       FLOAT,    "     
+		 "CHISQ_POS     FLOAT,    "   
+		 "CHISQ_PM      FLOAT,    "    
+		 "CHISQ_PAR     FLOAT,    "   
+		 "FLAGS         INT       "       
 		 ")\n", basename);
+
+// skipping these cpt fields:
+// 		 "U_RA        FLOAT,  "        
+// 		 "U_DEC       FLOAT,  "       
+// 		 "V_RA_ERR    FLOAT,  "    
+// 		 "V_DEC_ERR   FLOAT,  "   
+// 		 "PAR         FLOAT,  "         
+// 		 "PAR_ERR     FLOAT,  "     
+//		 "OFF_MEASURE INT,  " 
+//		 "OFF_MISSING INT,  " 
+//		 "OFF_EXTEND  INT,  "  
+//		 "PSF_QF      FLOAT, "      
+//		 "PSF_QF_PERF FLOAT,  " 
+//		 "STARGAL_SEP FLOAT,  " 
+//		 "NUMBER_POS  SMALLINT,  "  
+//		 "NMEASURE    SMALLINT,  "    
+//		 "NMISSING    SMALLINT,  "    
+//		 "NEXTEND     SMALLINT,  "     
+//		 "PHOTFLAGS_U INT,  " 
+//		 "PHOTFLAGS_L INT,  " 
+
+
 
   if (DEBUG) fprintf (stderr, "%s\n", buffer.buffer);
@@ -152,28 +155,23 @@
 
   PrintIOBuffer (&buffer, "CREATE TABLE %s_cps ("
-		 "MAG FLOAT,  "             
-		 "MAG_AP FLOAT,  "             
-		 "MAG_KRON FLOAT,  "        
-		 "MAG_KRON_ERR FLOAT,  "    
-		 "MAG_ERR FLOAT,  "         
-		 "MAG_CHI FLOAT,  "         
-		 "STACK_PSF_MAG FLOAT,  "        
-		 "STACK_PSF_MAG_ERR FLOAT,  "    
-		 "STACK_KRON_MAG FLOAT,  "       
-		 "STACK_KRON_MAG_ERR FLOAT,  "   
-		 "FLAGS INT,  "           
-		 "NCODE SMALLINT,  "           
-		 "NUSED SMALLINT,  "           
-		 "MAG_20 SMALLINT,  "          
-		 "MAG_80 SMALLINT,  "          
-		 "UBERCAL_DIST SMALLINT,  "    
-		 "MAG_STDEV SMALLINT,  "       
-		 "STACK_DETECT_ID BIGINT" 
+		 "MAG            FLOAT,  "             
+		 "MAG_ERR        FLOAT,  "         
+		 "MAG_STDEV      FLOAT,  "         
+		 "MAG_MIN        FLOAT,  "         
+		 "MAG_MAX        FLOAT,  "         
+		 "NUSED          SMALLINT,  "           
+		 "MAG_KRON       FLOAT,  "        
+		 "MAG_KRON_ERR   FLOAT,  "    
+		 "MAG_KRON_STDEV FLOAT,  "    
+		 "NUSED_KRON     SMALLINT,  "    
+		 "MAG_AP         FLOAT,  "             
+		 "MAG_AP_ERR     FLOAT,  "             
+		 "MAG_AP_STDEV   FLOAT,  "             
+		 "NUSED_AP       SMALLINT,  "    
+		 "NCODE          SMALLINT,  "           
+		 "NSTACK_DET     SMALLINT,  "           
+		 "PSF_QF_PERF_MAX FLOAT, "           
+		 "FLAGS          INT "           
 		 ")\n", basename);
-
- // 		 "FLUX_PSF FLOAT,  "        
- //  		 "FLUX_PSF_ERR FLOAT,  "    
- //  		 "FLUX_KRON FLOAT,  "       
- //  		 "FLUX_KRON_ERR FLOAT,  "   
 
   if (DEBUG) fprintf (stderr, "%s\n", buffer.buffer);
@@ -198,35 +196,22 @@
 
   PrintIOBuffer (ave_buffer, "INSERT INTO %s_cpt ("
-		 "RA, "          
-		 "DEC_, "         
-		 "RA_ERR, "      
-		 "DEC_ERR, "     
-		 "U_RA, "        
-		 "U_DEC, "       
-		 "V_RA_ERR, "    
-		 "V_DEC_ERR, "   
-		 "PAR, "         
-		 "PAR_ERR, "     
-		 "CHISQ_POS, "   
-		 "CHISQ_PM, "    
-		 "CHISQ_PAP, "   
-		 "MEAN_EPOCH, "  
-		 "TIME_RANGE, "  
-		 "PSF_QF, "      
-		 "PSF_QF_PERF, " 
-		 "STARGAL_SEP, " 
-		 "NUMBER_POS, "  
-		 "NMEASURE, "    
-		 "NMISSING, "    
-		 "NEXTEND, "     
-		 "OFF_MEASURE, " 
-		 "OFF_MISSING, " 
-		 "OFF_EXTEND, "  
-		 "FLAGS, "       
-		 "PHOTFLAGS_U, " 
-		 "PHOTFLAGS_L, " 
-		 "OBJ_ID, "      
-		 "CAT_ID, "      
-		 "EXT_ID"
+		 "EXT_ID,        "
+		 "OBJ_ID,        "      
+		 "CAT_ID,        "      
+		 "TESS_ID,       "      
+		 "PROJECTION_ID, "      
+		 "SKYCELL_ID,    "      
+		 "RA_STK,        "          
+		 "DEC_STK,       "         
+		 "RA_STK_ERR,    "      
+		 "DEC_STK_ERR,   "     
+		 "RA_MEAN,       "          
+		 "DEC_MEAN,      "         
+		 "RA_ERR,        "      
+		 "DEC_ERR,       "     
+		 "CHISQ_POS,     "   
+		 "CHISQ_PM,      "    
+		 "CHISQ_PAR,     "   
+		 "FLAGS          "       
 		 ") VALUES \n", basename);
 
@@ -237,21 +222,24 @@
   PrintIOBuffer (sec_buffer, "INSERT INTO %s_cps ("
 		 "MAG, "             
-		 "MAG_AP, "             
+		 "MAG_ERR, "         
+		 "MAG_STDEV, "       
+		 "MAG_MIN, "          
+		 "MAG_MAX, "          
+		 "NUSED, "           
+
 		 "MAG_KRON, "        
 		 "MAG_KRON_ERR, "    
-		 "MAG_ERR, "         
-		 "MAG_CHI, "         
-		 "STACK_PSF_MAG, "        
-		 "STACK_PSF_MAG_ERR, "    
-		 "STACK_KRON_MAG, "       
-		 "STACK_KRON_MAG_ERR, "   
-		 "FLAGS, "           
+		 "MAG_KRON_STDEV, "    
+		 "NUSED_KRON, "           
+
+		 "MAG_AP, "             
+		 "MAG_AP_ERR, "             
+		 "MAG_AP_STDEV, "             
+		 "NUSED_AP, "           
+
 		 "NCODE, "           
-		 "NUSED, "           
-		 "MAG_20, "          
-		 "MAG_80, "          
-		 "UBERCAL_DIST, "    
-		 "MAG_STDEV, "       
-		 "STACK_DETECT_ID " 
+		 "NSTACK_DET,  "           
+		 "PSF_QF_PERF_MAX, "           
+		 "FLAGS "           
 		 ") VALUES \n", basename);
   return TRUE;
@@ -268,96 +256,85 @@
 // XXX this bit could/should be autocoded...
   PrintIOBuffer (ave_buffer, " (");
+  PrintIOBuffer (ave_buffer, "%lu, ", average->extID);          
+  PrintIOBuffer (ave_buffer, "%u,  ", average->objID);          
+  PrintIOBuffer (ave_buffer, "%u,  ", average->catID);          
+
+  PrintIOBuffer (ave_buffer, "%hhd, ", average->tessID);          
+  PrintIOBuffer (ave_buffer, "%hd,  ", average->projectionID);          
+  PrintIOBuffer (ave_buffer, "%hhd, ", average->skycellID);          
+
+  PRINT_FLOAT(ave_buffer, average->Rstk,     "%.8f, ");  // 0.036 mas precision 
+  PRINT_FLOAT(ave_buffer, average->Dstk,     "%.8f, ");  // 0.036 mas precision 
+  PRINT_FLOAT(ave_buffer, average->dRstk,    "%.5f, ");  // 0.010 mas precision
+  PRINT_FLOAT(ave_buffer, average->dDstk,    "%.5f, ");  // 0.010 mas precision
+
   PRINT_FLOAT(ave_buffer, average->R,  	     "%.8f, ");  // 0.036 mas precision 
   PRINT_FLOAT(ave_buffer, average->D,  	     "%.8f, ");  // 0.036 mas precision 
   PRINT_FLOAT(ave_buffer, average->dR, 	     "%.5f, ");  // 0.010 mas precision
   PRINT_FLOAT(ave_buffer, average->dD, 	     "%.5f, ");  // 0.010 mas precision
-  PRINT_FLOAT(ave_buffer, average->uR, 	     "%.5f, ");  // 0.010 mas/yr precision
-  PRINT_FLOAT(ave_buffer, average->uD, 	     "%.5f, ");
-  PRINT_FLOAT(ave_buffer, average->duR,      "%.5f, ");
-  PRINT_FLOAT(ave_buffer, average->duD,      "%.5f, ");
-  PRINT_FLOAT(ave_buffer, average->P,        "%.5f, ");
-  PRINT_FLOAT(ave_buffer, average->dP,       "%.5f, ");
+
   PRINT_FLOAT(ave_buffer, average->ChiSqAve, "%.4f, ");
   PRINT_FLOAT(ave_buffer, average->ChiSqPM,  "%.4f, ");
   PRINT_FLOAT(ave_buffer, average->ChiSqPar, "%.4f, ");
-  PrintIOBuffer (ave_buffer, "%d, ",  average->Tmean);          
-  PrintIOBuffer (ave_buffer, "%d, ",  average->Trange);         
-  PRINT_FLOAT(ave_buffer, average->psfQF,     "%.3f, ");
-  PRINT_FLOAT(ave_buffer, average->psfQFperf, "%.3f, ");
-  PRINT_FLOAT(ave_buffer, average->stargal,   "%.3f, ");
-  PrintIOBuffer (ave_buffer, "%hu, ", average->Npos);           
-  PrintIOBuffer (ave_buffer, "%hu, ", average->Nmeasure);       
-  PrintIOBuffer (ave_buffer, "%hu, ", average->Nmissing);       
-  PrintIOBuffer (ave_buffer, "%hu, ", average->Nextend);        
-  PrintIOBuffer (ave_buffer, "%d, ",  average->measureOffset);  
-  PrintIOBuffer (ave_buffer, "%d, ",  average->missingOffset);  
-  PrintIOBuffer (ave_buffer, "%d, ",  average->extendOffset);   
-  PrintIOBuffer (ave_buffer, "%u, ",  average->flags);          
-  PrintIOBuffer (ave_buffer, "%u, ",  average->photFlagsUpper); 
-  PrintIOBuffer (ave_buffer, "%u, ",  average->photFlagsLower); 
-  PrintIOBuffer (ave_buffer, "%u, ",  average->objID);          
-  PrintIOBuffer (ave_buffer, "%u, ",  average->catID);          
-  PrintIOBuffer (ave_buffer, "%lu",   average->extID);          
+
+  PrintIOBuffer (ave_buffer, "%u ",  average->flags);          
+
   PrintIOBuffer (ave_buffer, "),\n");
 
+  // XXX what rules for keeping or NAN-ing various mags?
   for (i = 0; i < Nsecfilt; i++) {
     float meanPSFMag    = -999.0;
     float meanPSFMagErr = -999.0;
+    float meanPSFMagStd = -999.0;
+    float meanPSFMagMin = -999.0;
+    float meanPSFMagMax = -999.0;
     if (isfinite(secfilt->dM) && isfinite(secfilt->M)) {
-      meanPSFMag = secfilt->M;
+      meanPSFMag    = secfilt->M;
       meanPSFMagErr = secfilt->dM;
+      meanPSFMagStd = secfilt->Mstdev;
+      meanPSFMagMin = secfilt->Mmin;
+      meanPSFMagMax = secfilt->Mmax;
     }
 
     float meanKronMag    = -999.0;
     float meanKronMagErr = -999.0;
+    float meanKronMagStd = -999.0;
     if (isfinite(secfilt->dMkron) && isfinite(secfilt->Mkron) && (secfilt->dMkron < 0.333)) {
-      meanKronMag = secfilt->Mkron;
+      meanKronMag    = secfilt->Mkron;
       meanKronMagErr = secfilt->dMkron;
+      meanKronMagStd = secfilt->sMkron;
     }
 
     float meanApMag    = -999.0;
-    if (isfinite(secfilt->Map)) {
-      meanApMag = secfilt->Map;
-    }
-
-    float stackPSFMag    = -999.0;
-    float stackPSFMagErr = -999.0;
-    if (isfinite(secfilt->dFluxPSF) && isfinite(secfilt->FluxPSF) && (secfilt->dFluxPSF > 0.0)) {
-      float SN = secfilt->FluxPSF / secfilt->dFluxPSF;
-      if (SN > 3.0) {
-	stackPSFMag = -2.5 * log10(secfilt->FluxPSF) + 8.9;
-	stackPSFMagErr = secfilt->dFluxPSF / secfilt->FluxPSF;
-      }
-    }
-
-    float stackKronMag    = -999.0;
-    float stackKronMagErr = -999.0;
-    if (isfinite(secfilt->dFluxKron) && isfinite(secfilt->FluxKron) && (secfilt->dFluxKron > 0.0)) {
-      float SN = secfilt->FluxKron / secfilt->dFluxKron;
-      if (SN > 3.0) {
-	stackKronMag = -2.5 * log10(secfilt->FluxKron) + 8.9;
-	stackKronMagErr = secfilt->dFluxKron / secfilt->FluxKron;
-      }
+    float meanApMagErr = -999.0;
+    float meanApMagStd = -999.0;
+    if (isfinite(secfilt->dMap) && isfinite(secfilt->Map)) {
+      meanApMag    = secfilt->Map;
+      meanApMagErr = secfilt->dMap;
+      meanApMagStd = secfilt->sMap;
     }
 
     PrintIOBuffer (sec_buffer, " (");
     PRINT_FLOAT(sec_buffer, meanPSFMag,      "%.6f, "); // umag precision
-    PRINT_FLOAT(sec_buffer, meanApMag,       "%.6f, "); // umag precision
+    PRINT_FLOAT(sec_buffer, meanPSFMagErr,   "%.6f, "); // umag precision
+    PRINT_FLOAT(sec_buffer, meanPSFMagStd,   "%.6f, "); // umag precision
+    PRINT_FLOAT(sec_buffer, meanPSFMagMin,   "%.6f, "); // umag precision
+    PRINT_FLOAT(sec_buffer, meanPSFMagMax,   "%.6f, "); // umag precision
+    PrintIOBuffer (sec_buffer, "%hd,  ", secfilt->Nused);        
+
     PRINT_FLOAT(sec_buffer, meanKronMag,     "%.6f, "); // umag precision
     PRINT_FLOAT(sec_buffer, meanKronMagErr,  "%.6f, "); // umag precision
-    PRINT_FLOAT(sec_buffer, meanPSFMagErr,   "%.6f, "); // umag precision
-    PRINT_FLOAT(sec_buffer, secfilt->Xm,     "%.6f, ");
-    PRINT_FLOAT(sec_buffer, stackPSFMag,     "%.6f, "); // umag precision
-    PRINT_FLOAT(sec_buffer, stackPSFMagErr,  "%.6f, "); // umag precision
-    PRINT_FLOAT(sec_buffer, stackKronMag,    "%.6f, "); // umag precision
-    PRINT_FLOAT(sec_buffer, stackKronMagErr, "%.6f, "); // 0.36 umag precision
-    PrintIOBuffer (sec_buffer, "%u,  ", secfilt->flags);       
-    PrintIOBuffer (sec_buffer, "%hd, ", secfilt->Ncode);        
-    PrintIOBuffer (sec_buffer, "%hd, ", secfilt->Nused);        
-    PrintIOBuffer (sec_buffer, "%hd, ", secfilt->M_20);         
-    PrintIOBuffer (sec_buffer, "%hd, ", secfilt->M_80);         
-    PrintIOBuffer (sec_buffer, "%hd, ", secfilt->ubercalDist);  
-    PrintIOBuffer (sec_buffer, "%hd, ", secfilt->Mstdev);       
-    PrintIOBuffer (sec_buffer, "%lu  ", secfilt->stackDetectID);
+    PRINT_FLOAT(sec_buffer, meanKronMagStd,  "%.6f, "); // umag precision
+    PrintIOBuffer (sec_buffer, "%hd,  ", secfilt->NusedKron);        
+
+    PRINT_FLOAT(sec_buffer, meanApMag,     "%.6f, "); // umag precision
+    PRINT_FLOAT(sec_buffer, meanApMagErr,  "%.6f, "); // umag precision
+    PRINT_FLOAT(sec_buffer, meanApMagStd,  "%.6f, "); // umag precision
+    PrintIOBuffer (sec_buffer, "%hd,  ", secfilt->NusedAp);        
+    PrintIOBuffer (sec_buffer, "%hd,  ", secfilt->Ncode);        
+    PrintIOBuffer (sec_buffer, "%hd,  ", secfilt->NstackDet);        
+
+    PRINT_FLOAT(sec_buffer, secfilt->psfQfPerfMax, "%.6f,");       
+    PrintIOBuffer (sec_buffer, "%u ", secfilt->flags);       
     PrintIOBuffer (sec_buffer, "),\n");
     secfilt ++;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvopsps/src/insert_skytable.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvopsps/src/insert_skytable.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvopsps/src/insert_skytable.c	(revision 37403)
@@ -2,10 +2,4 @@
 # define DEBUG 1
 # define USE_MYSQL 1
-
-# define MARKTIME(MSG,...) {			\
-    float dtime;				\
-    gettimeofday (&stop, (void *) NULL);	\
-    dtime = DTIME (stop, start);		\
-    fprintf (stderr, MSG, __VA_ARGS__); }
 
 // determine the relevant catalogs, launch parallel clients if desired
@@ -13,5 +7,4 @@
 
   off_t i;
-  struct timeval start, stop;
   SkyTable *sky = NULL;
 
@@ -34,5 +27,6 @@
 # endif
 
-  gettimeofday (&start, (void *) NULL);
+  INITTIME;
+
   insert_skytable_mysql_init (&buffer);
   int Ninsert = 0;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvosplit/src/dvosplit.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvosplit/src/dvosplit.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvosplit/src/dvosplit.c	(revision 37403)
@@ -16,4 +16,12 @@
   ConfigInit (&argc, argv);
   args (argc, argv);
+
+  /*
+  fprintf (stderr, 
+  "this program has the ability to split dvo catalogs one file (cpt, cpm, etc) at a time.
+  however, new updates to the cpm format requires the average RA,DEC coords to load the
+  measures.  update the code to handle that first");
+  exit (2);
+  */
 
   CATDIR = strcreate (argv[1]);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvosplit/src/split_averages.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvosplit/src/split_averages.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvosplit/src/split_averages.c	(revision 37403)
@@ -1,4 +1,4 @@
 # include "dvosplit.h"
-# define NROWS 100000 /* ~10MB per block for measures */
+# define NROWS 1000000 /* ~10MB per block for measures */
 # define DNOUT 1000
 
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvosplit/src/split_measures.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvosplit/src/split_measures.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/dvosplit/src/split_measures.c	(revision 37403)
@@ -1,4 +1,4 @@
 # include "dvosplit.h"
-# define NROWS 100000 /* ~10MB per row for measures */
+# define NROWS 1000000 /* ~10MB per row for measures */
 # define DNOUT 1000
 
@@ -19,5 +19,6 @@
 
   // split out the measure entries:
-  incatalog[0].catflags = LOAD_MEAS;
+  incatalog[0].catflags = LOAD_MEAS | LOAD_AVES | LOAD_SECF;
+
   // if ((incatalog[0].catformat == DVO_FORMAT_ELIXIR) || (incatalog[0].catformat == DVO_FORMAT_LONEOS)) {
   //   // for these two formats, we need the average and secfilt values around until we do the measures...
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/gastro2/src/gstars2.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/gastro2/src/gstars2.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/gastro2/src/gstars2.c	(revision 37403)
@@ -125,5 +125,5 @@
   /* read from FITS table or from text table */
   /* Is NAXIS == 0 a better test?? */
-  gfits_scan_alt (&Target[0].header, "NAXIS",  "%t", 1, &naxis);
+  gfits_scan_alt (&Target[0].header, "NAXIS",  "%d", 1, &naxis);
   if ((naxis == 0) && !TEXTMODE) {
     Nskip = gfits_data_size (&Target[0].header);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/getstar/src/GetFileMode.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/getstar/src/GetFileMode.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/getstar/src/GetFileMode.c	(revision 37403)
@@ -8,4 +8,5 @@
   int simple, extend, haveNaxis, haveCTYPE;
 
+  // NOTE target of %t must be int length
   gfits_scan_alt (header, "SIMPLE", "%t", 1, &simple);
   haveNaxis = gfits_scan (header, "NAXIS",  "%d", 1, &Naxis);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/getstar/src/ReadImageFiles.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/getstar/src/ReadImageFiles.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/getstar/src/ReadImageFiles.c	(revision 37403)
@@ -138,5 +138,7 @@
 	  !strcmp (tmpword, "PS1_V1") ||  
 	  !strcmp (tmpword, "PS1_V2") ||  
-	  !strcmp (tmpword, "PS1_V3")) {
+	  !strcmp (tmpword, "PS1_V3") ||  
+	  !strcmp (tmpword, "PS1_V4") ||  
+	  !strcmp (tmpword, "PS1_V5")) {
 
 	  exttype[Nimage] = strcreate (tmpword);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/getstar/src/getstar.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/getstar/src/getstar.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/getstar/src/getstar.c	(revision 37403)
@@ -14,5 +14,5 @@
   set_db (&db);
 
-  sky = SkyTableLoadOptimal (CATDIR, SKY_TABLE, GSCFILE, TRUE, SKY_DEPTH, VERBOSE);
+  sky = SkyTableLoadOptimal (CATDIR, SKY_TABLE, GSCFILE, FALSE, SKY_DEPTH, VERBOSE);
   if (!sky) exit (1);
     
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/getstar/src/select_by_region.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/getstar/src/select_by_region.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/getstar/src/select_by_region.c	(revision 37403)
@@ -73,5 +73,5 @@
         for (m = 0; m < catalog[0].average[i].Nmeasure; m++) {
           if (catalog[0].measure[offset + m].photcode == code) {
-            mag = PhotRel (&catalog[0].measure[offset + m], &catalog[0].average[i], &catalog[0].secfilt[i*Nsecfilt]);
+            mag = PhotRel (&catalog[0].measure[offset + m], &catalog[0].average[i], &catalog[0].secfilt[i*Nsecfilt], MAG_CLASS_PSF);
             break;
           }
@@ -126,5 +126,5 @@
         for (m = 0; m < catalog[0].average[i].Nmeasure; m++) {
           if (catalog[0].measure[offset + m].photcode == code) {
-            mag = PhotRel (&catalog[0].measure[offset + m], &catalog[0].average[i], &catalog[0].secfilt[i*Nsecfilt]);
+            mag = PhotRel (&catalog[0].measure[offset + m], &catalog[0].average[i], &catalog[0].secfilt[i*Nsecfilt], MAG_CLASS_PSF);
             break;
           }
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/getstar/src/write_getstar_ps1_dev_0.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/getstar/src/write_getstar_ps1_dev_0.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/getstar/src/write_getstar_ps1_dev_0.c	(revision 37403)
@@ -61,5 +61,5 @@
       for (m = 0; m < average[i].Nmeasure; m++) {
         if (measure[offset + m].photcode == code_c0) {
-          output[i].mag = PhotRel (&measure[offset + m], &average[i], &secfilt[i*Nsecfilt]);
+          output[i].mag = PhotRel (&measure[offset + m], &average[i], &secfilt[i*Nsecfilt], MAG_CLASS_PSF);
 	  break;
         }
@@ -75,5 +75,5 @@
       for (m = 0; m < average[i].Nmeasure; m++) {
         if (measure[offset + m].photcode == code_c1) {
-          output[i].c1 = PhotRel (&measure[offset + m], &average[i], &secfilt[i*Nsecfilt]);
+          output[i].c1 = PhotRel (&measure[offset + m], &average[i], &secfilt[i*Nsecfilt], MAG_CLASS_PSF);
 	  break;
         }
@@ -89,5 +89,5 @@
       for (m = 0; m < average[i].Nmeasure; m++) {
         if (measure[offset + m].photcode == code_c2) {
-          output[i].c2 = PhotRel (&measure[offset + m], &average[i], &secfilt[i*Nsecfilt]);
+          output[i].c2 = PhotRel (&measure[offset + m], &average[i], &secfilt[i*Nsecfilt], MAG_CLASS_PSF);
 	  break;
         }
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/getstar/src/write_getstar_ps1_dev_1.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/getstar/src/write_getstar_ps1_dev_1.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/getstar/src/write_getstar_ps1_dev_1.c	(revision 37403)
@@ -64,5 +64,5 @@
       for (m = 0; m < average[i].Nmeasure; m++) {
         if (measure[offset + m].photcode == code_c0) {
-          output[i].mag = PhotRel (&measure[offset + m], &average[i], &secfilt[i*Nsecfilt]);
+          output[i].mag = PhotRel (&measure[offset + m], &average[i], &secfilt[i*Nsecfilt], MAG_CLASS_PSF);
 	  break;
         }
@@ -78,5 +78,5 @@
       for (m = 0; m < average[i].Nmeasure; m++) {
         if (measure[offset + m].photcode == code_c1) {
-          output[i].c1 = PhotRel (&measure[offset + m], &average[i], &secfilt[i*Nsecfilt]);
+          output[i].c1 = PhotRel (&measure[offset + m], &average[i], &secfilt[i*Nsecfilt], MAG_CLASS_PSF);
 	  break;
         }
@@ -92,5 +92,5 @@
       for (m = 0; m < average[i].Nmeasure; m++) {
         if (measure[offset + m].photcode == code_c2) {
-          output[i].c2 = PhotRel (&measure[offset + m], &average[i], &secfilt[i*Nsecfilt]);
+          output[i].c2 = PhotRel (&measure[offset + m], &average[i], &secfilt[i*Nsecfilt], MAG_CLASS_PSF);
 	  break;
         }
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/getstar/src/write_getstar_ps1_dev_2.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/getstar/src/write_getstar_ps1_dev_2.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/getstar/src/write_getstar_ps1_dev_2.c	(revision 37403)
@@ -70,5 +70,5 @@
       for (m = 0; m < average[i].Nmeasure; m++) {
         if (measure[offset + m].photcode == code_c0) {
-          output[i].mag = PhotRel (&measure[offset + m], &average[i], &secfilt[i*Nsecfilt]);
+          output[i].mag = PhotRel (&measure[offset + m], &average[i], &secfilt[i*Nsecfilt], MAG_CLASS_PSF);
 	  break;
         }
@@ -84,5 +84,5 @@
       for (m = 0; m < average[i].Nmeasure; m++) {
         if (measure[offset + m].photcode == code_c1) {
-          output[i].c1 = PhotRel (&measure[offset + m], &average[i], &secfilt[i*Nsecfilt]);
+          output[i].c1 = PhotRel (&measure[offset + m], &average[i], &secfilt[i*Nsecfilt], MAG_CLASS_PSF);
 	  break;
         }
@@ -98,5 +98,5 @@
       for (m = 0; m < average[i].Nmeasure; m++) {
         if (measure[offset + m].photcode == code_c2) {
-          output[i].c2 = PhotRel (&measure[offset + m], &average[i], &secfilt[i*Nsecfilt]);
+          output[i].c2 = PhotRel (&measure[offset + m], &average[i], &secfilt[i*Nsecfilt], MAG_CLASS_PSF);
 	  break;
         }
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/kapa2/src/CheckPipe.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/kapa2/src/CheckPipe.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/kapa2/src/CheckPipe.c	(revision 37403)
@@ -1,3 +1,4 @@
 # include "Ximage.h"
+# include <errno.h>
 # define STRCONST(A) ((int)(0x1000000*A[0] + 0x10000*A[1] + 0x100*A[2] + 0x1*A[3]))
 
@@ -41,6 +42,11 @@
   word[4] = 0;
   switch (status) {
-  case -1:                          /* no input from pipe: continue */
-    return (TRUE);
+  case -1:
+    if (errno == EAGAIN) {
+      /* no input from pipe: continue */
+      return (TRUE);
+    } 
+    perror ("exiting due to problem with socket connection in CheckPipe");
+    return (FALSE);
     break;
 
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/kapa2/src/DrawObjects.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/kapa2/src/DrawObjects.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/kapa2/src/DrawObjects.c	(revision 37403)
@@ -608,4 +608,26 @@
     }
   }
+  if (object[0].ptype == 12) {	/* filled triangle (down) */
+    XPoint points[4];
+    for (i = 0; i < object[0].Npts; i++) {
+      if (!(finite(x[i]) && finite(y[i]))) continue;
+      sx = x[i]*mxi + y[i]*mxj + bx + XCENTER;
+      sy = x[i]*myi + y[i]*myj + by + YCENTER;
+      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy)) {
+	if (scaleColor) {
+	  if (!finite(z[i])) continue;
+	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	  XSetForeground (graphic->display, graphic->gc, graphic->cmap[pixel].pixel);
+	}
+	D = scaleSize ? dz*z[i] : ds;
+	points[0].x = sx - D;  points[0].y = sy - 0.58*D;  
+	points[1].x = sx + D;  points[1].y = sy - 0.58*D;  
+	points[2].x = sx;      points[2].y = sy + 1.15*D;  
+	points[3].x = sx - D;  points[3].y = sy - 0.58*D;  
+	XFillPolygon (graphic->display, graphic->window, graphic->gc, points, 4, Convex, CoordModeOrigin);
+      }
+    }
+  }
   if (object[0].ptype == 100) {	/* connect a pair of points */
 
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/kapa2/src/EventLoop.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/kapa2/src/EventLoop.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/kapa2/src/EventLoop.c	(revision 37403)
@@ -1,3 +1,4 @@
 # include "Ximage.h"
+# define DEBUG 0
 
 /* list events being selected below, all other masks are ignored */ 
@@ -6,9 +7,27 @@
 int LastEvent (Display *display, int type, XEvent *event) {
 
-  int found;
+  int found, Nfound;
 
   found = FALSE;
+  Nfound = 0;
   while (XCheckTypedEvent (display, type, event)) {
+    // If the link is slow, then I should wait a little while for some config events to
+    // build up (typically, the window is being dragged around, so we get a whole series of 
+    // config events.  the flush / sync time is slow on a slow link, so we should try to wait
+    // for the config events to stop, but on a timescale deteremined by the flush/sync time
+    // if (type == ConfigureNotify) fprintf (stderr, "config (%d)\n", Nfound);
+    Nfound ++;
     found = TRUE;
+  }
+  if (DEBUG && found) {
+    if (type == ConfigureNotify) fprintf (stderr, "config (%d)\n", Nfound);
+    if (type == CirculateNotify) fprintf (stderr, "circul (%d)\n", Nfound);
+    if (type == Expose) fprintf (stderr, "expose (%d)\n", Nfound);
+  }
+
+  // if I have a ConfigureNotify event, I should purge all Expose events as well:
+  if (found && (type == ConfigureNotify)) {
+    XEvent discard;
+    while (XCheckTypedEvent (display, Expose, &discard));
   }
   return (found);
@@ -38,13 +57,14 @@
 
     if (XEventsQueued (display, QueuedAfterFlush) < 1) {
-      /* fprintf (stderr, "."); */
       usleep (50000);
       continue;
     }
 
+    // If I have a config event, I want to also purge all expose events
+
     /* grab the last entry for these events */
-    if (LastEvent (display, ConfigureNotify, &event)) Reconfig (&event);
-    if (LastEvent (display, CirculateNotify, &event)) Reconfig (&event);
-    if (LastEvent (display, Expose,          &event)) Refresh ();
+    if (LastEvent (display, ConfigureNotify, &event)) { Reconfig (&event); continue; }
+    if (LastEvent (display, CirculateNotify, &event)) { Reconfig (&event); continue; }
+    if (LastEvent (display, Expose,          &event)) { Refresh (); continue; }
     if (LastEvent (display, MappingNotify,   &event)) XRefreshKeyboardMapping ((XMappingEvent *) &event);
     if (LastEvent (display, MotionNotify,    &event)) UpdatePointer (graphic, (XMotionEvent *) &event);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/kapa2/src/FlushDisplay.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/kapa2/src/FlushDisplay.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/kapa2/src/FlushDisplay.c	(revision 37403)
@@ -30,5 +30,7 @@
 
   if (flush) {
-    XFlush (graphic->display);
+    // I changed XFlush to XSync to avoid lag
+    // of the display (build up of config events)
+    XSync (graphic->display, FALSE);
     reftime = now;
   }
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/kapa2/src/Refresh.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/kapa2/src/Refresh.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/kapa2/src/Refresh.c	(revision 37403)
@@ -47,5 +47,4 @@
   Y0 = graphic[0].dy - graphic[0].dy * section[0].y - dY;
   X0 = graphic[0].dx * section[0].x;
-  // fprintf (stderr, "section: (%s) %d %d - %d %d\n", section[0].name, X0, Y0, dX, dY);
 
   XFillRectangle (graphic[0].display,  graphic[0].window, graphic[0].gc, X0, Y0, dX, dY);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/kapa2/src/bDrawObjects.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/kapa2/src/bDrawObjects.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/kapa2/src/bDrawObjects.c	(revision 37403)
@@ -540,4 +540,26 @@
 	FillCircle (buffer, sx, sy, D);
 	// out-of-range points skipped by bDrawLineHorizontal
+      }
+    }
+  }
+  if (object[0].ptype == 12) {	/* filled triangle (down) */
+    for (i = 0; i < object[0].Npts; i++) {
+      if (!(finite(x[i]) && finite(y[i]))) continue;
+      sx = x[i]*mxi + y[i]*mxj + bx;
+      sy = x[i]*myi + y[i]*myj + by;
+      if ((sx > graph[0].axis[0].fx) && (sx < graph[0].axis[0].fx + graph[0].axis[0].dfx) &&
+	  (sy < graph[0].axis[1].fy) && (sy > graph[0].axis[1].fy + graph[0].axis[1].dfy))
+      {
+	if (scaleColor) {
+	  if (!finite(z[i])) continue;
+	  int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+	  buffer->bColor_R = pixel1[pixel];
+	  buffer->bColor_G = pixel2[pixel];
+	  buffer->bColor_B = pixel3[pixel];
+	}
+	D = scaleSize ? dz*z[i] : ds;
+	// FillTriangle (buffer, sx - D, sy - 0.58*D, sx + D, sy - 0.58*D, sx, sy + 1.15*D);
+	FillTriangle (buffer, sx, sy + 0.58*D, D, 1.73*D);
+	// out-of-range points skipped by bDrawPoint
       }
     }
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/Makefile.Targets
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/Makefile.Targets	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/Makefile.Targets	(revision 37403)
@@ -12,4 +12,5 @@
 $(ASRC)/average-ps1-v3.$(ARCH).o \
 $(ASRC)/average-ps1-v4.$(ARCH).o \
+$(ASRC)/average-ps1-v5.$(ARCH).o \
 $(ASRC)/average-ps1-ref.$(ARCH).o \
 $(ASRC)/secfilt.$(ARCH).o \
@@ -24,4 +25,5 @@
 $(ASRC)/secfilt-ps1-v3.$(ARCH).o \
 $(ASRC)/secfilt-ps1-v4.$(ARCH).o \
+$(ASRC)/secfilt-ps1-v5.$(ARCH).o \
 $(ASRC)/secfilt-ps1-ref.$(ARCH).o \
 $(ASRC)/measure.$(ARCH).o \
@@ -36,5 +38,10 @@
 $(ASRC)/measure-ps1-v3.$(ARCH).o \
 $(ASRC)/measure-ps1-v4.$(ARCH).o \
+$(ASRC)/measure-ps1-v5.$(ARCH).o \
 $(ASRC)/measure-ps1-ref.$(ARCH).o \
+$(ASRC)/lensing.$(ARCH).o \
+$(ASRC)/lensing-ps1-v5.$(ARCH).o \
+$(ASRC)/lensobj.$(ARCH).o \
+$(ASRC)/lensobj-ps1-v5.$(ARCH).o \
 $(ASRC)/missing.$(ARCH).o \
 $(ASRC)/photcode.$(ARCH).o \
@@ -47,4 +54,5 @@
 $(ASRC)/photcode-ps1-v3.$(ARCH).o \
 $(ASRC)/photcode-ps1-v4.$(ARCH).o \
+$(ASRC)/photcode-ps1-v5.$(ARCH).o \
 $(ASRC)/photcode-ps1-ref.$(ARCH).o \
 $(ASRC)/image.$(ARCH).o \
@@ -60,4 +68,5 @@
 $(ASRC)/image-ps1-v3.$(ARCH).o \
 $(ASRC)/image-ps1-v4.$(ARCH).o \
+$(ASRC)/image-ps1-v5.$(ARCH).o \
 $(ASRC)/image-ps1-ref.$(ARCH).o \
 $(ASRC)/regimage.$(ARCH).o \
@@ -73,4 +82,5 @@
 $(ASRC)/cmf-ps1-sv1.$(ARCH).o \
 $(ASRC)/cmf-ps1-sv2.$(ARCH).o \
+$(ASRC)/cmf-ps1-dv4.$(ARCH).o \
 $(ASRC)/cmf-smpdata.$(ARCH).o \
 $(ASRC)/getstar-ps1-dev-0.$(ARCH).o \
@@ -84,4 +94,6 @@
 $(ASRC)/FlatCorrectionImage.$(ARCH).o \
 $(ASRC)/FlatCorrection.$(ARCH).o
+
+# $(ASRC)/cmf-ps1-sv3.$(ARCH).o
 
 AINCS = \
@@ -98,4 +110,5 @@
 $(AINC)/average-ps1-v3.h \
 $(AINC)/average-ps1-v4.h \
+$(AINC)/average-ps1-v5.h \
 $(AINC)/average-ps1-ref.h \
 $(AINC)/secfilt.h \
@@ -110,4 +123,5 @@
 $(AINC)/secfilt-ps1-v3.h \
 $(AINC)/secfilt-ps1-v4.h \
+$(AINC)/secfilt-ps1-v5.h \
 $(AINC)/secfilt-ps1-ref.h \
 $(AINC)/measure.h \
@@ -122,5 +136,10 @@
 $(AINC)/measure-ps1-v3.h \
 $(AINC)/measure-ps1-v4.h \
+$(AINC)/measure-ps1-v5.h \
 $(AINC)/measure-ps1-ref.h \
+$(AINC)/lensing.h \
+$(AINC)/lensing-ps1-v5.h \
+$(AINC)/lensobj.h \
+$(AINC)/lensobj-ps1-v5.h \
 $(AINC)/missing.h \
 $(AINC)/photcode.h \
@@ -133,4 +152,5 @@
 $(AINC)/photcode-ps1-v3.h \
 $(AINC)/photcode-ps1-v4.h \
+$(AINC)/photcode-ps1-v5.h \
 $(AINC)/photcode-ps1-ref.h \
 $(AINC)/image.h \
@@ -146,4 +166,5 @@
 $(AINC)/image-ps1-v3.h \
 $(AINC)/image-ps1-v4.h \
+$(AINC)/image-ps1-v5.h \
 $(AINC)/image-ps1-ref.h \
 $(AINC)/regimage.h \
@@ -159,4 +180,5 @@
 $(AINC)/cmf-ps1-sv1.h \
 $(AINC)/cmf-ps1-sv2.h \
+$(AINC)/cmf-ps1-dv4.h \
 $(AINC)/cmf-smpdata.h \
 $(AINC)/getstar-ps1-dev-0.h \
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/average-ps1-dev-2.d
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/average-ps1-dev-2.d	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/average-ps1-dev-2.d	(revision 37403)
@@ -25,5 +25,5 @@
 FIELD measureOffset,  OFF_MEASURE, int,     	    offset to first psf measurement
 FIELD missingOffset,  OFF_MISSING, int,     	    offset to first missing obs
-FIELD extendOffset,   OFF_EXTEND,  int,     	    offset to first extended measurement
+FIELD refColor,       REF_COLOR,   float,   	    color of astrometry ref stars
 
 FIELD code,           code,       unsigned short,   ID code (star; ghost; etc)
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/average-ps1-v1.d
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/average-ps1-v1.d	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/average-ps1-v1.d	(revision 37403)
@@ -30,5 +30,5 @@
 FIELD measureOffset,  OFF_MEASURE, uint32_t,   	    offset to first psf measurement
 FIELD missingOffset,  OFF_MISSING, uint32_t,   	    offset to first missing obs
-FIELD extendOffset,   OFF_EXTEND,  uint32_t,   	    offset to first extended measurement
+FIELD refColor,       REF_COLOR,   float,   	    color of astrometry ref stars
 
 # 'flags' was called 'code' prior to 2009.02.07
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/average-ps1-v2.d
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/average-ps1-v2.d	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/average-ps1-v2.d	(revision 37403)
@@ -35,5 +35,5 @@
 FIELD measureOffset,  OFF_MEASURE, uint32_t,   	    offset to first psf measurement
 FIELD missingOffset,  OFF_MISSING, uint32_t,   	    offset to first missing obs
-FIELD extendOffset,   OFF_EXTEND,  uint32_t,   	    offset to first extended measurement
+FIELD refColor,       REF_COLOR,   float,   	    color of astrometry ref stars
 
 # 'flags' was called 'code' prior to 2009.02.07
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/average-ps1-v3.d
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/average-ps1-v3.d	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/average-ps1-v3.d	(revision 37403)
@@ -35,5 +35,5 @@
 FIELD measureOffset,  OFF_MEASURE, uint32_t,   	    offset to first psf measurement
 FIELD missingOffset,  OFF_MISSING, uint32_t,   	    offset to first missing obs
-FIELD extendOffset,   OFF_EXTEND,  uint32_t,   	    offset to first extended measurement
+FIELD refColor,       REF_COLOR,   float,   	    color of astrometry ref stars
 
 # 'flags' was called 'code' prior to 2009.02.07
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/average-ps1-v4.d
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/average-ps1-v4.d	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/average-ps1-v4.d	(revision 37403)
@@ -38,5 +38,5 @@
 FIELD measureOffset,  OFF_MEASURE, uint32_t,   	    offset to first psf measurement
 FIELD missingOffset,  OFF_MISSING, uint32_t,   	    offset to first missing obs
-FIELD extendOffset,   OFF_EXTEND,  uint32_t,   	    offset to first extended measurement
+FIELD refColor,       REF_COLOR,   float,   	    color of reference stars
 
 # 'flags' was called 'code' prior to 2009.02.07
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/average-ps1-v5.d
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/average-ps1-v5.d	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/average-ps1-v5.d	(revision 37403)
@@ -0,0 +1,87 @@
+STRUCT       Average_PS1_V5
+EXTNAME      DVO_AVERAGE_PS1_V5
+TYPE         BINTABLE
+SIZE         192
+DESCRIPTION  DVO Average Object Table
+
+# elements of data structure / FITS table
+
+FIELD R,              RA,          double,          RA,                	       	  decimal degrees 
+FIELD D,              DEC,         double,          DEC,               	       	  decimal degrees 
+FIELD dR,             RA_ERR,      float,           RA error,                     arcsec
+FIELD dD,             DEC_ERR,     float,           DEC error,                    arcsec
+
+FIELD uR,             U_RA,        float,           RA*cos(D) proper-motion,      arcsec/year
+FIELD uD,             U_DEC,       float,           DEC proper-motion,            arcsec/year
+FIELD duR,            V_RA_ERR,    float,           RA*cos(D) p-m error,          arcsec/year
+FIELD duD,            V_DEC_ERR,   float,           DEC p-m error,                arcsec/year
+FIELD P,              PAR,         float,           parallax,			  arcsec
+FIELD dP,             PAR_ERR,     float,           parallax error,               arcsec
+
+FIELD Rstk,           RA_STK,      double,          RA on stack,      	       	  decimal degrees 
+FIELD Dstk,           DEC_STK,     double,          DEC on stack,      	       	  decimal degrees 
+FIELD dRstk,          RA_STK_ERR,  float,           RA error on stack,            arcsec
+FIELD dDstk,          DEC_STK_ERR, float,           DEC error on stack,           arcsec
+
+FIELD ChiSqAve,       CHISQ_POS,   float,           astrometry analysis chisq
+FIELD ChiSqPM,        CHISQ_PM,    float,           astrometry analysis chisq
+FIELD ChiSqPar,       CHISQ_PAP,   float,           astrometry analysis chisq
+FIELD Tmean,          MEAN_EPOCH,  int,   	    mean epoch (PM,PAR ref),       unix time seconds
+FIELD Trange,         TIME_RANGE,  int,   	    mean epoch (PM,PAR ref),       unix time seconds
+
+FIELD psfQF,          PSF_QF,      float,           psf coverage (bad masks)
+FIELD psfQFperf,      PSF_QF_PERF, float,           psf coverage (all masks)
+
+FIELD stargal,        STARGAL_SEP, float,           star / galaxy separator,       1/100 arcsec
+FIELD Npos,           NUMBER_POS,  unsigned short,  number of detections used for astrometry
+
+# this limits us to a max of 64k measurements per object
+FIELD Nmeasure,       NMEASURE,    unsigned short,  number of psf measurements
+FIELD Nmissing,       NMISSING,    unsigned short,  number of missings
+FIELD Nlensing,       NLENSING,    unsigned short,  number of lensing measurements
+FIELD Nlensobj,       NLENSOBJ,    unsigned short,  number of lensing measurements
+FIELD Nextend,        NEXTEND,     unsigned short,  number of extended measurements
+
+FIELD measureOffset,  OFF_MEASURE, int,   	    offset to first psf measurement
+FIELD missingOffset,  OFF_MISSING, int,   	    offset to first missing obs
+FIELD lensingOffset,  OFF_LENSING, int,   	    offset to first lensing obs
+FIELD lensobjOffset,  OFF_LENSOBJ, int,   	    offset to mean lensing data
+FIELD extendOffset,   OFF_EXTEND,  int,   	    offset to extended object entry
+FIELD paramsOffset,   OFF_PARAMS,  int,   	    offset to stellar parameter data
+
+FIELD refColorBlue,   REF_COLOR_BLUE, float,   	    color of astrometry ref stars
+FIELD refColorRed,    REF_COLOR_RED,  float,   	    color of astrometry ref stars
+
+FIELD tessID,         TESS_ID,       char,	    ID of tessellation for primary skycell
+FIELD skycellID,      SKYCELL_ID,    char,    	    ID of skycell for primary skycell
+FIELD projectionID,   PROJECTION_ID, short,	    ID of projection for primary skycell
+
+FIELD dummy,          DUMMY,         int,           unassigned bytes
+
+# 'flags' was called 'code' prior to 2009.02.07
+FIELD flags,          FLAGS,       uint32_t,        average object flags (star; ghost; etc)
+FIELD photFlagsUpper, PHOTFLAGS_U, uint32_t,        upper bit of 2 bit summary of per-measure photflags
+FIELD photFlagsLower, PHOTFLAGS_L, uint32_t,        lower bit of 2 bit summary of per-measure photflags
+
+# objID + catID gives a unique ID for all objects in the database
+FIELD objID,          OBJ_ID,      unsigned int,    unique ID for object in table
+FIELD catID,          CAT_ID,      unsigned int,    unique ID for table in which object was first realized
+FIELD extID,          EXT_ID,      uint64_t,        external ID for object (eg PSPS objID)
+FIELD extIDgc,        EXT_ID_GC,   uint64_t,        external ID for object in galactic coords
+
+# 4 double, 2 uint64_t, 17 float, 12 int, 6 short
+# 4*8 + 2*8 + 17*4 + 12*4 + 6*2 = 176
+# for 5G objects, expect 840G
+
+# photflagsUpper & photflagsLower: we have Nmeasures of a given source
+# using psphot. each of these as a photFlag field, with bits
+# describing the detection quality.  photflagsUpper and photFlagsLower
+# represent a 2 bit value (0-3) which defines the frequency of a given
+# bit in the measurements:
+# for a given bit, if that bit is raised for these percentile ranges,
+# the following bits are set:
+# min |  max | L | U
+#  0% |  25% | 0 | 0 
+# 25% |  50% | 1 | 0 
+# 50% |  75% | 0 | 1 
+# 75% | 100% | 1 | 1 
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/average.d
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/average.d	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/average.d	(revision 37403)
@@ -2,5 +2,5 @@
 EXTNAME      DVO_AVERAGE
 TYPE         BINTABLE
-SIZE         128
+SIZE         192
 DESCRIPTION  DVO Average Object Table
 
@@ -19,4 +19,9 @@
 FIELD dP,             PAR_ERR,     float,           parallax error,               arcsec
 
+FIELD Rstk,           RA_STK,      double,          RA on stack,      	       	  decimal degrees 
+FIELD Dstk,           DEC_STK,     double,          DEC on stack,      	       	  decimal degrees 
+FIELD dRstk,          RA_STK_ERR,  float,           RA error on stack,            arcsec
+FIELD dDstk,          DEC_STK_ERR, float,           DEC error on stack,           arcsec
+
 FIELD ChiSqAve,       CHISQ_POS,   float,           astrometry analysis chisq
 FIELD ChiSqPM,        CHISQ_PM,    float,           astrometry analysis chisq
@@ -34,9 +39,23 @@
 FIELD Nmeasure,       NMEASURE,    unsigned short,  number of psf measurements
 FIELD Nmissing,       NMISSING,    unsigned short,  number of missings
+FIELD Nlensing,       NLENSING,    unsigned short,  number of lensing measurements
+FIELD Nlensobj,       NLENSOBJ,    unsigned short,  number of lensing measurements
 FIELD Nextend,        NEXTEND,     unsigned short,  number of extended measurements
 
 FIELD measureOffset,  OFF_MEASURE, int,             offset to first psf measurement
 FIELD missingOffset,  OFF_MISSING, int,             offset to first missing obs
-FIELD extendOffset,   OFF_EXTEND,  int,             offset to first extended measurement
+FIELD lensingOffset,  OFF_LENSING, int,   	    offset to first lensing obs
+FIELD lensobjOffset,  OFF_LENSOBJ, int,   	    offset to mean lensing data
+FIELD extendOffset,   OFF_EXTEND,  int,   	    offset to extended object entry
+FIELD paramsOffset,   OFF_PARAMS,  int,   	    offset to stellar parameter data
+
+FIELD refColorBlue,   REF_COLOR_BLUE, float,   	    color of astrometry ref stars
+FIELD refColorRed,    REF_COLOR_RED,  float,   	    color of astrometry ref stars
+
+FIELD tessID,         TESS_ID,       char,	    ID of tessellation for primary skycell
+FIELD skycellID,      SKYCELL_ID,    char,    	    ID of skycell for primary skycell
+FIELD projectionID,   PROJECTION_ID, short,	    ID of projection for primary skycell
+
+FIELD dummy,          DUMMY,         int,           unassigned bytes
 
 # 'flags' was called 'code' prior to 2009.02.07
@@ -49,4 +68,5 @@
 FIELD catID,          CAT_ID,      unsigned int,    unique ID for table in which object was first realized
 FIELD extID,          EXT_ID,      uint64_t,        external ID for object (eg PSPS objID)
+FIELD extIDgc,        EXT_ID_GC,   uint64_t,        external ID for object in galactic coords
 
 # this structure should only be used for internal representations
@@ -56,7 +76,6 @@
 
 # *** 20090206 : new fields : ChiSq, Npos, flags (was code, uint16_t), extID
-
 # *** 20100331 : new fields needed to assess astrometry analysis quality:
-
+# *** 20140617 : new fields : Rstk, Dstk, dRstk,dDstk, Nlensing, Nlensobj, lensingOffset, lensobjOffset, refColor
 
 # photflagsUpper & photflagsLower: we have Nmeasures of a given source
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/cmf-ps1-dv4.d
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/cmf-ps1-dv4.d	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/cmf-ps1-dv4.d	(revision 37403)
@@ -0,0 +1,65 @@
+# name of structure type
+STRUCT  CMF_PS1_DV4
+EXTNAME CMF_PS1_DV4
+TYPE    BINTABLE
+SIZE    224
+
+# elements of data structure / FITS table
+FIELD detID,          IPP_IDET,          unsigned int, detection ID                     
+FIELD X,              X_PSF,             float,    x coord,               pixels
+FIELD Y,              Y_PSF,             float,    y coord,               pixels
+FIELD dX,             X_PSF_SIG,         float,    x coord error,         pixels
+FIELD dY,             Y_PSF_SIG,         float,    y coord error,         pixels
+FIELD posangle,       POSANGLE,          float,    Posangle at source,    degrees
+FIELD pltscale,       PLTSCALE,          float,    Plate Scale at source, arcsec/pixel
+FIELD M,              PSF_INST_MAG,      float,    inst mags,             mags
+FIELD dM,             PSF_INST_MAG_SIG,  float,    inst mag error,        mags
+FIELD Flux,           PSF_INST_FLUX,     float,    psf flux,	       counts
+FIELD dFlux,          PSF_INST_FLUX_SIG, float,    psf flux error,        counts      
+FIELD Map,            AP_MAG,   	 float,    standard aperture mag, mags
+FIELD MapRaw,         AP_MAG_RAW,        float,    raw aperture mag,      mags
+FIELD apRadius,       AP_MAG_RADIUS,     float,    radius used for fit,   pixels
+FIELD apFlux,         AP_FLUX,           float,    ap flux
+FIELD apFluxErr,      AP_FLUX_SIG,       float,    ap flux err
+FIELD Mpeak,          PEAK_FLUX_AS_MAG,  float,    peak flux as a mag,    mags
+FIELD Mcalib,         CAL_PSF_MAG,       float,    calibrated psf mag,    mags
+FIELD dMcal,          CAL_PSF_MAG_SIG,   float,    zero point scatter,    mags
+
+# NOTE: RA & DEC (both double) need to be on an 8-byte boundary...
+FIELD RA,             RA_PSF,            double,   PSF RA coord,          degrees
+FIELD DEC,            DEC_PSF,           double,   PSF DEC coord,         degrees
+
+FIELD sky,            SKY,               float,    sky flux,              cnts/sec
+FIELD dSky,           SKY_SIGMA,         float,    sky flux error,        cnts/sec
+FIELD psfChisq,       PSF_CHISQ,         float,    psf fit chisq
+FIELD crNsigma,       CR_NSIGMA,         float,    Nsigma deviations from PSF to CF
+FIELD extNsigma,      EXT_NSIGMA,        float,    Nsigma deviations from PSF to EXT
+FIELD fx,             PSF_MAJOR,         float,    psf fit major axis,    pixels
+FIELD fy,             PSF_MINOR,         float,    psf fit minor axis,    pixels
+FIELD df,             PSF_THETA,         float,    ellipse angle,         degrees
+FIELD psfQF,          PSF_QF,            float,    quality factor
+FIELD psfQFperf,      PSF_QF_PERFECT,    float,    quality factor perfect
+FIELD psfNdof,        PSF_NDOF,          int,      psf degrees of freedom
+FIELD psfNpix,        PSF_NPIX,          int,      psf number of pixels
+FIELD Mxx,            MOMENTS_XX,        float,    second moment X,       pixels^2
+FIELD Mxy,            MOMENTS_XY,        float,    second moment Y,       pixels^2
+FIELD Myy,            MOMENTS_YY,        float,    second moment XY,      pixels^2
+FIELD Mr1,            MOMENTS_R1,        float,    first radial moment,   pixels
+FIELD Mrh,            MOMENTS_RH,        float,    half radial moment,    pixels^1/2
+FIELD kronFlux,       KRON_FLUX,         float,    kron flux,             counts
+FIELD kronFluxErr,    KRON_FLUX_ERR,     float,    kron flux error,       counts
+FIELD kronInner,      KRON_FLUX_INNER,   float,    kron flux 1<R<2.5,     counts
+FIELD kronOuter,      KRON_FLUX_OUTER,   float,    kron flux 2.5<R<4,     counts
+FIELD D_Npos,         DIFF_NPOS,         int,      diff param
+FIELD D_Fratio,       DIFF_FRATIO,       float,    diff param
+FIELD D_Nratio_bad,   DIFF_NRATIO_BAD,   float,    diff param
+FIELD D_Nratio_mask,  DIFF_NRATIO_MASK,  float,    diff param
+FIELD D_Nratio_all,   DIFF_NRATIO_ALL,   float,    diff param
+FIELD D_Rp,           DIFF_R_P,          float,    diff param
+FIELD D_SNp,          DIFF_SN_P,         float,    diff param
+FIELD D_Rm,           DIFF_R_M,          float,    diff param
+FIELD D_SNm,          DIFF_SN_M,         float,    diff param
+FIELD flags,          FLAGS,             int,      analysis flags
+FIELD flags2,         FLAGS2,            int,      analysis flags (2)
+FIELD nFrames,        N_FRAMES,          short,    images overlapping peak
+FIELD padding,        PADDING,           short,    padding for 8byte records
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/cmf-ps1-sv3.d
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/cmf-ps1-sv3.d	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/cmf-ps1-sv3.d	(revision 37403)
@@ -0,0 +1,72 @@
+# name of structure type
+STRUCT  CMF_PS1_SV3
+EXTNAME CMF_PS1_SV3
+TYPE    BINTABLE
+SIZE    224
+
+# elements of data structure / FITS table
+FIELD detID,          IPP_IDET,          unsigned int, detection ID                     
+FIELD X,              X_PSF,             float,    x coord,               pixels
+FIELD Y,              Y_PSF,             float,    y coord,               pixels
+FIELD dX,             X_PSF_SIG,         float,    x coord error,         pixels
+FIELD dY,             Y_PSF_SIG,         float,    y coord error,         pixels
+FIELD posangle,       POSANGLE,          float,    Posangle at source,    degrees
+FIELD pltscale,       PLTSCALE,          float,    Plate Scale at source, arcsec/pixel
+FIELD M,              PSF_INST_MAG,      float,    inst mags,             mags
+FIELD dM,             PSF_INST_MAG_SIG,  float,    inst mag error,        mags
+FIELD Flux,           PSF_INST_FLUX,     float,    psf flux,	       counts
+FIELD dFlux,          PSF_INST_FLUX_SIG, float,    psf flux error,        counts      
+FIELD Map,            AP_MAG,   	 float,    standard aperture mag, mags
+FIELD MapRaw,         AP_MAG_RAW,        float,    raw aperture mag,      mags
+FIELD apRadius,       AP_MAG_RADIUS,     float,    radius used for fit,   pixels
+FIELD apFlux,         AP_FLUX,           float,    aperture flux,         counts
+FIELD apFluxErr,      AP_FLUX_SIG,       float,    error on ap flux,      counts
+FIELD apNpix,         AP_NPIX,           int,      pixels used for aper
+FIELD Mcalib,         CAL_PSF_MAG,       float,    calibrated psf mag,    mags
+FIELD dMcal,          CAL_PSF_MAG_SIG,   float,    zero point scatter,    mags
+
+# this field is in the wrong order (is between DEC and sky in cmf, but breaks byte boundary).
+# I need to move these bytes around on read (fix PS1_V5?)
+FIELD Mpeak,          PEAK_FLUX_AS_MAG,  float,    peak flux as a mag,    mags
+
+# NOTE: RA & DEC (both double) need to be on an 8-byte boundary...
+FIELD RA,             RA_PSF,            double,   PSF RA coord,          degrees
+FIELD DEC,            DEC_PSF,           double,   PSF DEC coord,         degrees
+
+FIELD sky,            SKY,               float,    sky flux,              cnts/sec
+FIELD dSky,           SKY_SIG,           float,    sky flux error,        cnts/sec
+FIELD psfChisq,       PSF_CHISQ,         float,    psf fit chisq
+ 
+FIELD crNsigma,       CR_NSIGMA,         float,    Nsigma deviations from PSF to CF
+FIELD extNsigma,      EXT_NSIGMA,        float,    Nsigma deviations from PSF to EXT
+FIELD fx,             PSF_MAJOR,         float,    psf fit major axis,    pixels
+FIELD fy,             PSF_MINOR,         float,    psf fit minor axis,    pixels
+FIELD df,             PSF_THETA,         float,    ellipse angle,         degrees
+FIELD k,              PSF_CORE,          float,    extra PSF parameter,   unitless
+FIELD fwhmMaj,        PSF_FWHM_MAJ,      float,    true fwhm of psf,      pixels
+FIELD fwhmMin,        PSF_FWHM_MIN,      float,    true fwhm (minor),     pixels
+FIELD psfQF,          PSF_QF,            float,    quality factor
+FIELD psfQFperf,      PSF_QF_PERFECT,    float,    quality factor perfect
+FIELD psfNdof,        PSF_NDOF,          int,      psf degrees of freedom
+FIELD psfNpix,        PSF_NPIX,          int,      psf number of pixels
+
+FIELD Mxx,            MOMENTS_XX,        float,    second moment X,       pixels^2
+FIELD Mxy,            MOMENTS_XY,        float,    second moment Y,       pixels^2
+FIELD Myy,            MOMENTS_YY,        float,    second moment XY,      pixels^2
+FIELD M3c,            MOMENTS_M3C,       float,    third moment cos(t),   pixels^3
+FIELD M3s,            MOMENTS_M3S,       float,    third moment sin(t),   pixels^3
+FIELD M4c,            MOMENTS_M4C,       float,    fourth moment cos(t),  pixels^4
+FIELD M4s,            MOMENTS_M4S,       float,    fourth moment sin(t),  pixels^4
+FIELD Mr1,            MOMENTS_R1,        float,    first radial moment,   pixels
+FIELD Mrh,            MOMENTS_RH,        float,    half radial moment,    pixels^1/2
+FIELD kronFlux,       KRON_FLUX,         float,    kron flux,             counts
+FIELD kronFluxErr,    KRON_FLUX_ERR,     float,    kron flux error,       counts
+FIELD kronInner,      KRON_FLUX_INNER,   float,    kron flux 1<R<2.5,     counts
+FIELD kronOuter,      KRON_FLUX_OUTER,   float,    kron flux 2.5<R<4,     counts
+FIELD flags,          FLAGS,             int,      analysis flags
+FIELD flags2,         FLAGS2,            int,      analysis flags (2)
+
+FIELD nFrames,        N_FRAMES,          short,    images overlapping peak
+FIELD padding,        PADDING,           short,    padding for 8byte records
+FIELD padding2,       PADDING2,          int,      padding for 8byte records
+
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/cmf-ps1-v5-lensing.d
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/cmf-ps1-v5-lensing.d	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/cmf-ps1-v5-lensing.d	(revision 37403)
@@ -0,0 +1,100 @@
+# name of structure type
+STRUCT  CMF_PS1_V5
+EXTNAME CMF_PS1_V5
+TYPE    BINTABLE
+SIZE    312
+
+# elements of data structure / FITS table
+FIELD detID,          IPP_IDET,          unsigned int, detection ID                     
+FIELD X,              X_PSF,             float,    x coord,               pixels
+FIELD Y,              Y_PSF,             float,    y coord,               pixels
+FIELD dX,             X_PSF_SIG,         float,    x coord error,         pixels
+FIELD dY,             Y_PSF_SIG,         float,    y coord error,         pixels
+FIELD posangle,       POSANGLE,          float,    Posangle at source,    degrees
+FIELD pltscale,       PLTSCALE,          float,    Plate Scale at source, arcsec/pixel
+FIELD M,              PSF_INST_MAG,      float,    inst mags,             mags
+FIELD dM,             PSF_INST_MAG_SIG,  float,    inst mag error,        mags
+FIELD Flux,           PSF_INST_FLUX,     float,    psf flux,              counts
+FIELD dFlux,          PSF_INST_FLUX_SIG, float,    psf flux error,        counts      
+FIELD Map,            AP_MAG,            float,    standard aperture mag, mags
+FIELD MapRaw,         AP_MAG_RAW,        float,    raw aperture mag,      mags
+FIELD apRadius,       AP_MAG_RADIUS,     float,    radius used for aper,  pixels
+FIELD apFlux,         AP_FLUX,           float,    aperture flux,         counts
+FIELD apFluxErr,      AP_FLUX_SIG,       float,    error on ap flux,      counts
+FIELD apNpix,         AP_NPIX,           int,      pixels used by aper,   pixels
+FIELD Mcalib,         CAL_PSF_MAG,       float,    calibrated psf mag,    mags
+FIELD dMcal,          CAL_PSF_MAG_SIG,   float,    zero point scatter,    mags
+
+# this field is in the wrong order (is between DEC and sky in cmf, but breaks byte boundary).
+# I need to move these bytes around on read (fix PS1_V5?)
+FIELD Mpeak,          PEAK_FLUX_AS_MAG,  float,    peak flux as a mag,    mags
+
+# NOTE: RA & DEC (both double) need to be on an 8-byte boundary...
+FIELD RA,             RA_PSF,            double,   PSF RA coord,          degrees
+FIELD DEC,            DEC_PSF,           double,   PSF DEC coord,         degrees
+
+FIELD sky,            SKY,               float,    sky flux,              cnts/sec
+FIELD dSky,           SKY_SIGMA,         float,    sky flux error,        cnts/sec
+FIELD psfChisq,       PSF_CHISQ,         float,    psf fit chisq
+FIELD crNsigma,       CR_NSIGMA,         float,    Nsigma deviations from PSF to CF
+FIELD extNsigma,      EXT_NSIGMA,        float,    Nsigma deviations from PSF to EXT
+FIELD fx,             PSF_MAJOR,         float,    psf fit major axis,    pixels
+FIELD fy,             PSF_MINOR,         float,    psf fit minor axis,    pixels
+FIELD df,             PSF_THETA,         float,    ellipse angle,         degrees
+FIELD k,              PSF_CORE,          float,    extra PSF parameter,   unitless
+FIELD fwhmMaj,        PSF_FWHM_MAJ,      float,    true fwhm of psf,      pixels
+FIELD fwhmMin,        PSF_FWHM_MIN,      float,    true fwhm (minor),     pixels
+FIELD psfQF,          PSF_QF,            float,    quality factor
+FIELD psfQFperf,      PSF_QF_PERFECT,    float,    quality factor perfect
+FIELD psfNdof,        PSF_NDOF,          int,      psf degrees of freedom
+FIELD psfNpix,        PSF_NPIX,          int,      psf number of pixels
+FIELD Mxx,            MOMENTS_XX,        float,    second moment X,       pixels^2
+FIELD Mxy,            MOMENTS_XY,        float,    second moment Y,       pixels^2
+FIELD Myy,            MOMENTS_YY,        float,    second moment XY,      pixels^2
+FIELD M3c,            MOMENTS_M3C,       float,    third moment cos(t),   pixels^3
+FIELD M3s,            MOMENTS_M3S,       float,    third moment sin(t),   pixels^3
+FIELD M4c,            MOMENTS_M4C,       float,    fourth moment cos(t),  pixels^4
+FIELD M4s,            MOMENTS_M4S,       float,    fourth moment sin(t),  pixels^4
+
+FIELD X11_sm_obj,     X11_SM_OBJ,        float,    lensing smear
+FIELD X12_sm_obj,     X12_SM_OBJ,        float,    lensing smear
+FIELD X22_sm_obj,     X22_SM_OBJ,        float,    lensing smear
+FIELD E1_sm_obj,      E1_SM_OBJ,         float,    lensing smear
+FIELD E2_sm_obj,      E2_SM_OBJ,         float,    lensing smear
+
+FIELD X11_sh_obj,     X11_SH_OBJ,        float,    lensing shear
+FIELD X12_sh_obj,     X12_SH_OBJ,        float,    lensing shear
+FIELD X22_sh_obj,     X22_SH_OBJ,        float,    lensing shear
+FIELD E1_sh_obj,      E1_SH_OBJ,         float,    lensing shear
+FIELD E2_sh_obj,      E2_SH_OBJ,         float,    lensing shear
+
+FIELD X11_sm_psf,     X11_SM_PSF,        float,    lensing smear
+FIELD X12_sm_psf,     X12_SM_PSF,        float,    lensing smear
+FIELD X22_sm_psf,     X22_SM_PSF,        float,    lensing smear
+FIELD E1_sm_psf,      E1_SM_PSF,         float,    lensing smear
+FIELD E2_sm_psf,      E2_SM_PSF,         float,    lensing smear
+
+FIELD X11_sh_psf,     X11_SH_PSF,        float,    lensing shear
+FIELD X12_sh_psf,     X12_SH_PSF,        float,    lensing shear
+FIELD X22_sh_psf,     X22_SH_PSF,        float,    lensing shear
+FIELD E1_sh_psf,      E1_SH_PSF,         float,    lensing shear
+FIELD E2_sh_psf,      E2_SH_PSF,         float,    lensing shear
+
+FIELD Mr1,            MOMENTS_R1,        float,    first radial moment,   pixels
+FIELD Mrh,            MOMENTS_RH,        float,    half radial moment,    pixels^1/2
+FIELD kronFlux,       KRON_FLUX,         float,    kron flux,             counts
+FIELD kronFluxErr,    KRON_FLUX_ERR,     float,    kron flux error,       counts
+FIELD kronInner,      KRON_FLUX_INNER,   float,    kron flux 1<R<2.5,     counts
+FIELD kronOuter,      KRON_FLUX_OUTER,   float,    kron flux 2.5<R<4,     counts
+FIELD skyLimitRad,    SKY_LIMIT_RAD,     float,    profile to sky limit (radius)
+FIELD skyLimitFlux,   SKY_LIMIT_FLUX,    float,    profile to sky limit (flux)
+FIELD skyLimitSlope,  SKY_LIMIT_SLOPE,   float,    profile to sky limit (slope)
+FIELD flags,          FLAGS,             int,      analysis flags
+FIELD flags2,         FLAGS2,            int,      analysis flags (2)
+FIELD nFrames,        N_FRAMES,          short,    images overlapping peak
+FIELD padding,        PADDING,           short,    padding for 8byte records
+
+# for an object in an image, we have three triplets that tell us about the shape:
+# second moments: Mxx, Mxy, Myy 
+# model shape parameters: F_major, F_minor, F_theta
+# centroid errors: sigma_X, sigma_Y, sigma_XY
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/cmf-ps1-v5.d
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/cmf-ps1-v5.d	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/cmf-ps1-v5.d	(revision 37403)
@@ -0,0 +1,75 @@
+# name of structure type
+STRUCT  CMF_PS1_V5
+EXTNAME CMF_PS1_V5
+TYPE    BINTABLE
+SIZE    232
+
+# elements of data structure / FITS table
+FIELD detID,          IPP_IDET,          unsigned int, detection ID                     
+FIELD X,              X_PSF,             float,    x coord,               pixels
+FIELD Y,              Y_PSF,             float,    y coord,               pixels
+FIELD dX,             X_PSF_SIG,         float,    x coord error,         pixels
+FIELD dY,             Y_PSF_SIG,         float,    y coord error,         pixels
+FIELD posangle,       POSANGLE,          float,    Posangle at source,    degrees
+FIELD pltscale,       PLTSCALE,          float,    Plate Scale at source, arcsec/pixel
+FIELD M,              PSF_INST_MAG,      float,    inst mags,             mags
+FIELD dM,             PSF_INST_MAG_SIG,  float,    inst mag error,        mags
+FIELD Flux,           PSF_INST_FLUX,     float,    psf flux,              counts
+FIELD dFlux,          PSF_INST_FLUX_SIG, float,    psf flux error,        counts      
+FIELD Map,            AP_MAG,            float,    standard aperture mag, mags
+FIELD MapRaw,         AP_MAG_RAW,        float,    raw aperture mag,      mags
+FIELD apRadius,       AP_MAG_RADIUS,     float,    radius used for aper,  pixels
+FIELD apFlux,         AP_FLUX,           float,    aperture flux,         counts
+FIELD apFluxErr,      AP_FLUX_SIG,       float,    error on ap flux,      counts
+FIELD apNpix,         AP_NPIX,           int,      pixels used by aper,   pixels
+FIELD Mcalib,         CAL_PSF_MAG,       float,    calibrated psf mag,    mags
+FIELD dMcal,          CAL_PSF_MAG_SIG,   float,    zero point scatter,    mags
+
+# this field is in the wrong order (is between DEC and sky in cmf, but breaks byte boundary).
+# I need to move these bytes around on read (fix PS1_V5?)
+FIELD Mpeak,          PEAK_FLUX_AS_MAG,  float,    peak flux as a mag,    mags
+
+# NOTE: RA & DEC (both double) need to be on an 8-byte boundary...
+FIELD RA,             RA_PSF,            double,   PSF RA coord,          degrees
+FIELD DEC,            DEC_PSF,           double,   PSF DEC coord,         degrees
+
+FIELD sky,            SKY,               float,    sky flux,              cnts/sec
+FIELD dSky,           SKY_SIGMA,         float,    sky flux error,        cnts/sec
+FIELD psfChisq,       PSF_CHISQ,         float,    psf fit chisq
+FIELD crNsigma,       CR_NSIGMA,         float,    Nsigma deviations from PSF to CF
+FIELD extNsigma,      EXT_NSIGMA,        float,    Nsigma deviations from PSF to EXT
+FIELD fx,             PSF_MAJOR,         float,    psf fit major axis,    pixels
+FIELD fy,             PSF_MINOR,         float,    psf fit minor axis,    pixels
+FIELD df,             PSF_THETA,         float,    ellipse angle,         degrees
+FIELD k,              PSF_CORE,          float,    extra PSF parameter,   unitless
+FIELD fwhmMaj,        PSF_FWHM_MAJ,      float,    true fwhm of psf,      pixels
+FIELD fwhmMin,        PSF_FWHM_MIN,      float,    true fwhm (minor),     pixels
+FIELD psfQF,          PSF_QF,            float,    quality factor
+FIELD psfQFperf,      PSF_QF_PERFECT,    float,    quality factor perfect
+FIELD psfNdof,        PSF_NDOF,          int,      psf degrees of freedom
+FIELD psfNpix,        PSF_NPIX,          int,      psf number of pixels
+FIELD Mxx,            MOMENTS_XX,        float,    second moment X,       pixels^2
+FIELD Mxy,            MOMENTS_XY,        float,    second moment Y,       pixels^2
+FIELD Myy,            MOMENTS_YY,        float,    second moment XY,      pixels^2
+FIELD M3c,            MOMENTS_M3C,       float,    third moment cos(t),   pixels^3
+FIELD M3s,            MOMENTS_M3S,       float,    third moment sin(t),   pixels^3
+FIELD M4c,            MOMENTS_M4C,       float,    fourth moment cos(t),  pixels^4
+FIELD M4s,            MOMENTS_M4S,       float,    fourth moment sin(t),  pixels^4
+FIELD Mr1,            MOMENTS_R1,        float,    first radial moment,   pixels
+FIELD Mrh,            MOMENTS_RH,        float,    half radial moment,    pixels^1/2
+FIELD kronFlux,       KRON_FLUX,         float,    kron flux,             counts
+FIELD kronFluxErr,    KRON_FLUX_ERR,     float,    kron flux error,       counts
+FIELD kronInner,      KRON_FLUX_INNER,   float,    kron flux 1<R<2.5,     counts
+FIELD kronOuter,      KRON_FLUX_OUTER,   float,    kron flux 2.5<R<4,     counts
+FIELD skyLimitRad,    SKY_LIMIT_RAD,     float,    profile to sky limit (radius)
+FIELD skyLimitFlux,   SKY_LIMIT_FLUX,    float,    profile to sky limit (flux)
+FIELD skyLimitSlope,  SKY_LIMIT_SLOPE,   float,    profile to sky limit (slope)
+FIELD flags,          FLAGS,             int,      analysis flags
+FIELD flags2,         FLAGS2,            int,      analysis flags (2)
+FIELD nFrames,        N_FRAMES,          short,    images overlapping peak
+FIELD padding,        PADDING,           short,    padding for 8byte records
+
+# for an object in an image, we have three triplets that tell us about the shape:
+# second moments: Mxx, Mxy, Myy 
+# model shape parameters: F_major, F_minor, F_theta
+# centroid errors: sigma_X, sigma_Y, sigma_XY
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/common.h
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/common.h	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/common.h	(revision 37403)
@@ -32,5 +32,5 @@
 # define rawshort short
 
-# define DVO_IMAGE_NAME_LEN 121
+# define DVO_IMAGE_NAME_LEN 117
 
 /*** rawshort is used to handle the broken pre-autocode photreg tables
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/image-ps1-v2.d
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/image-ps1-v2.d	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/image-ps1-v2.d	(revision 37403)
@@ -42,5 +42,5 @@
 FIELD     DECo,             DEC_CENTER,           float,          image center,              degrees
 FIELD     Radius,           RADIUS,               float,          image radius,              degrees
-FIELD     DUMMY,            DUMMY,                float,          dummy
+FIELD     refColor,         REF_COLOR,            float,          dummy
 
 # should we define the max length of name as a macro?
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/image-ps1-v3.d
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/image-ps1-v3.d	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/image-ps1-v3.d	(revision 37403)
@@ -42,5 +42,5 @@
 FIELD     DECo,             DEC_CENTER,           float,          image center,              degrees
 FIELD     Radius,           RADIUS,               float,          image radius,              degrees
-FIELD     DUMMY,            DUMMY,                float,          dummy
+FIELD     refColor,         REF_COLOR,            float,          dummy
 
 # should we define the max length of name as a macro?
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/image-ps1-v4.d
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/image-ps1-v4.d	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/image-ps1-v4.d	(revision 37403)
@@ -42,5 +42,5 @@
 FIELD     DECo,             DEC_CENTER,           float,          image center,              degrees
 FIELD     Radius,           RADIUS,               float,          image radius,              degrees
-FIELD     DUMMY,            DUMMY,                float,          dummy
+FIELD     refColor,         REF_COLOR,            float,          dummy
 
 # should we define the max length of name as a macro?
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/image-ps1-v5.d
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/image-ps1-v5.d	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/image-ps1-v5.d	(revision 37403)
@@ -0,0 +1,78 @@
+STRUCT       Image_PS1_V5
+EXTNAME      DVO_IMAGE_PS1_V5
+TYPE         BINTABLE
+SIZE         360
+DESCRIPTION  DVO Image Table 
+
+# elements of the image structure
+# careful of 8-byte boundaries
+
+SUBSTRUCT coords,           COORDS,               Coords,        astrometric data
+SUBFIELD  crval1,           CRVAL1,               double,   	 coordinate at reference pixel
+SUBFIELD  crval2,           CRVAL2,               double,  	 coordinate at reference pixel
+SUBFIELD  crpix1,           CRPIX1,               float,   	 coordinate of reference pixel
+SUBFIELD  crpix2,           CRPIX2,               float,   	 coordinate of reference pixel
+SUBFIELD  cdelt1,           CDELT1,               float,   	 degrees per pixel
+SUBFIELD  cdelt2,           CDELT2,               float,    	 degrees per pixel
+SUBFIELD  pc1_1,            PC1_1,                float,    	 rotation matrix
+SUBFIELD  pc1_2,            PC1_2,                float,    	 rotation matrix
+SUBFIELD  pc2_1,            PC2_1,                float,    	 rotation matrix
+SUBFIELD  pc2_2,            PC2_2,                float,    	 rotation matrix
+SUBFIELD  polyterms,        POLYTERMS,            float[7][2],	 higher order warping terms
+SUBFIELD  ctype,            CTYPE,                char[15],      coordinate type
+SUBFIELD  Npolyterms,       NPOLYTERMS,           char,     	 order of polynomial
+# 120 bytes
+
+# change this to a double mjd?
+FIELD 	  tzero,            TZERO,                e_time,         readout time (row 0)
+FIELD 	  nstar,            NSTAR,                unsigned int,   number of stars on image
+FIELD 	  secz,             SECZ,                 float,      	  airmass,                   mag
+FIELD 	  NX,               NX,                   unsigned short, image width
+FIELD 	  NY,               NY,                   unsigned short, image height
+FIELD 	  apmifit,          APMIFIT,              float,      	  aperture correction,       mag
+FIELD 	  dapmifit,         DAPMIFIT,             float,      	  apmifit error,             mag
+FIELD 	  Mcal,             MCAL,                 float,      	  calibration mag,           mag
+FIELD 	  dMcal,            DMCAL,                float,      	  error on Mcal,             mag
+FIELD 	  Xm,               XM,                   short,      	  image chisq,               10*log(value)
+FIELD 	  photcode,         PHOTCODE,             short,      	  identifier for CCD,
+FIELD 	  exptime,          EXPTIME,              float,          exposure time,             seconds
+FIELD     sidtime,          ST,			  float,          sidereal time of exposure
+FIELD     latitude,         LAT,		  float,          observatory latitude,      degrees
+# 40 bytes
+
+FIELD     RAo,              RA_CENTER,            float,          image center,              degrees
+FIELD     DECo,             DEC_CENTER,           float,          image center,              degrees
+FIELD     Radius,           RADIUS,               float,          image radius,              degrees
+FIELD     refColorBlue,     REF_COLOR_BLUE,       float,          median astrometry ref color
+FIELD     refColorRed,      REF_COLOR_RED,        float,          median astrometry ref color
+
+# should we define the max length of name as a macro?
+FIELD 	  name,             NAME,                 char[117],      name of original image 
+FIELD 	  detection_limit,  DETECTION_LIMIT,      unsigned char,  detection limit,           10*mag
+FIELD 	  saturation_limit, SATURATION_LIMIT,     unsigned char,  saturation limit,          10*mag
+FIELD 	  cerror,           CERROR,               unsigned char,  astrometric error,         50*arcsec
+FIELD 	  fwhm_x,           FWHM_X,               unsigned char,  PSF x width,               25*arcsec
+FIELD 	  fwhm_y,           FWHM_Y,               unsigned char,  PSF y width,               25*arcsec
+FIELD 	  trate,            TRATE,                unsigned char,  scan rate,                 100 usec/pixel
+FIELD 	  ccdnum,           CCDNUM,               unsigned char,  CCD ID number
+FIELD 	  flags,            FLAGS,                unsigned int,   image quality flags
+FIELD 	  imageID,          IMAGE_ID,             unsigned int,   internal image ID
+FIELD 	  parentID,         PARENT_ID,            unsigned int,   associated ref image
+FIELD 	  externID,         EXTERN_ID,            unsigned int,   external image ID
+FIELD 	  sourceID,         SOURCE_ID,            unsigned short, analysis source ID
+# 48 bytes 
+
+FIELD 	  nLinkAstrom,      NLINK_ASTROM,         short,      	  mean number of matched measurements for astrometry
+FIELD 	  nLinkPhotom,      NLINK_PHOTOM,         short,      	  mean number of matched measurements for astrometry
+FIELD 	  ubercalDist,      UBERCAL_DIST,         short,      	  distance to nearest ubercal image
+
+FIELD 	  dXpixSys,         XPIX_SYS_ERR,         float,      	  systematic astrometry error in X
+FIELD 	  dYpixSys,         YPIX_SYS_ERR,         float,      	  systematic astrometry error in Y
+
+FIELD 	  dMagSys,          MAG_SYS_ERR,          float,      	  systematic photometry error
+FIELD 	  nFitAstrom,       N_FIT_ASTROM,         short,      	  number of stars used for astrometry cal
+FIELD 	  nFitPhotom,       N_FIT_PHOTOM,         short,      	  number of stars used for photometry cal
+
+FIELD 	  photom_map_id,    PHOTOM_MAP_ID,        unsigned int,   reference to 2D zero point map
+FIELD 	  astrom_map_id,    ASTROM_MAP_ID,        unsigned int,   reference to 2D astrometry map
+# nFitPhotom lands on the old location of Mxxxx, which was used to mean nFitPhotom in some cases
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/image.d
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/image.d	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/image.d	(revision 37403)
@@ -44,7 +44,9 @@
 FIELD     DECo,             DEC_CENTER,           float,          image center,              degrees
 FIELD     Radius,           RADIUS,               float,          image radius,              degrees
-FIELD     DUMMY,            DUMMY,                float,          dummy
+FIELD     refColorBlue,     REF_COLOR_BLUE,       float,          median astrometry ref color
+FIELD     refColorRed,      REF_COLOR_RED,        float,          median astrometry ref color
 
-FIELD 	  name,             NAME,                 char[121],      name of original image 
+# should we define the max length of name as a macro?
+FIELD 	  name,             NAME,                 char[117],      name of original image 
 FIELD 	  detection_limit,  DETECTION_LIMIT,      unsigned char,  detection limit,           10*mag
 FIELD 	  saturation_limit, SATURATION_LIMIT,     unsigned char,  saturation limit,          10*mag
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/lensing-ps1-v5.d
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/lensing-ps1-v5.d	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/lensing-ps1-v5.d	(revision 37403)
@@ -0,0 +1,52 @@
+STRUCT       Lensing_PS1_V5
+EXTNAME      DVO_LENSING_PS1_V5
+TYPE         BINTABLE
+SIZE         136
+DESCRIPTION  DVO Lensing Table 
+
+FIELD X11_sm_obj,     X11_SM_OBJ,    float,          lensing smear object X11
+FIELD X12_sm_obj,     X12_SM_OBJ,    float,          lensing smear object X12
+FIELD X22_sm_obj,     X22_SM_OBJ,    float,          lensing smear object X22
+FIELD  E1_sm_obj,      E1_SM_OBJ,    float,          lensing smear object E1
+FIELD  E2_sm_obj,      E2_SM_OBJ,    float,          lensing smear object E2
+
+FIELD X11_sh_obj,     X11_SH_OBJ,    float,          lensing shear object X11
+FIELD X12_sh_obj,     X12_SH_OBJ,    float,          lensing shear object X12
+FIELD X22_sh_obj,     X22_SH_OBJ,    float,          lensing shear object X22
+FIELD  E1_sh_obj,      E1_SH_OBJ,    float,          lensing shear object E1
+FIELD  E2_sh_obj,      E2_SH_OBJ,    float,          lensing shear object E2
+
+FIELD X11_sm_psf,     X11_SM_PSF,    float,          lensing smear psf stars X11
+FIELD X12_sm_psf,     X12_SM_PSF,    float,          lensing smear psf stars X12
+FIELD X22_sm_psf,     X22_SM_PSF,    float,          lensing smear psf stars X22
+FIELD  E1_sm_psf,      E1_SM_PSF,    float,          lensing smear psf stars E1
+FIELD  E2_sm_psf,      E2_SM_PSF,    float,          lensing smear psf stars E2
+
+FIELD X11_sh_psf,     X11_SH_PSF,    float,          lensing shear psf stars X11
+FIELD X12_sh_psf,     X12_SH_PSF,    float,          lensing shear psf stars X12
+FIELD X22_sh_psf,     X22_SH_PSF,    float,          lensing shear psf stars X22
+FIELD  E1_sh_psf,      E1_SH_PSF,    float,          lensing shear psf stars E1
+FIELD  E2_sh_psf,      E2_SH_PSF,    float,          lensing shear psf stars E2
+
+FIELD F_ApR5,        FLUX_AP_R5,     float,          Flux inside r = 5
+FIELD dF_ApR5,       FLUX_ERR_AP_R5, float,          Flux inside r = 5
+FIELD sF_ApR5,       FLUX_STD_AP_R5, float,          Flux inside r = 5
+FIELD fF_ApR5,       FLUX_FIL_AP_R5, float,          Flux inside r = 5
+
+FIELD F_ApR6,        FLUX_AP_R6,     float,          Flux inside r = 5
+FIELD dF_ApR6,       FLUX_ERR_AP_R6, float,          Flux inside r = 5
+FIELD sF_ApR6,       FLUX_AP_R6,     float,          Flux inside r = 5
+FIELD fF_ApR6,       FLUX_AP_R6,     float,          Flux inside r = 5
+
+FIELD  detID,          DET_ID,       unsigned int,   detection ID
+FIELD  objID,          OBJ_ID,       unsigned int,   unique ID for object in table
+FIELD  catID,          CAT_ID,       unsigned int,   unique ID for table in which object was first realized
+FIELD  averef,         AVE_REF,      unsigned int,   reference to average entry      
+
+FIELD imageID,	       IMAGE_ID,     unsigned int,   reference to DVO image ID
+FIELD padding,	       PADDING,      unsigned int,   reference to DVO image ID
+
+# 28 x float
+# 4 x int
+# = 128 bytes / detection
+# for 2.5G objects + 60 overlaps, expect 15TB for forced warp
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/lensing.d
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/lensing.d	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/lensing.d	(revision 37403)
@@ -0,0 +1,52 @@
+STRUCT       Lensing
+EXTNAME      DVO_LENSING
+TYPE         BINTABLE
+SIZE         136
+DESCRIPTION  DVO Lensing Table 
+
+FIELD X11_sm_obj,     X11_SM_OBJ,    float,          lensing smear object X11
+FIELD X12_sm_obj,     X12_SM_OBJ,    float,          lensing smear object X12
+FIELD X22_sm_obj,     X22_SM_OBJ,    float,          lensing smear object X22
+FIELD  E1_sm_obj,      E1_SM_OBJ,    float,          lensing smear object E1
+FIELD  E2_sm_obj,      E2_SM_OBJ,    float,          lensing smear object E2
+
+FIELD X11_sh_obj,     X11_SH_OBJ,    float,          lensing shear object X11
+FIELD X12_sh_obj,     X12_SH_OBJ,    float,          lensing shear object X12
+FIELD X22_sh_obj,     X22_SH_OBJ,    float,          lensing shear object X22
+FIELD  E1_sh_obj,      E1_SH_OBJ,    float,          lensing shear object E1
+FIELD  E2_sh_obj,      E2_SH_OBJ,    float,          lensing shear object E2
+
+FIELD X11_sm_psf,     X11_SM_PSF,    float,          lensing smear psf stars X11
+FIELD X12_sm_psf,     X12_SM_PSF,    float,          lensing smear psf stars X12
+FIELD X22_sm_psf,     X22_SM_PSF,    float,          lensing smear psf stars X22
+FIELD  E1_sm_psf,      E1_SM_PSF,    float,          lensing smear psf stars E1
+FIELD  E2_sm_psf,      E2_SM_PSF,    float,          lensing smear psf stars E2
+
+FIELD X11_sh_psf,     X11_SH_PSF,    float,          lensing shear psf stars X11
+FIELD X12_sh_psf,     X12_SH_PSF,    float,          lensing shear psf stars X12
+FIELD X22_sh_psf,     X22_SH_PSF,    float,          lensing shear psf stars X22
+FIELD  E1_sh_psf,      E1_SH_PSF,    float,          lensing shear psf stars E1
+FIELD  E2_sh_psf,      E2_SH_PSF,    float,          lensing shear psf stars E2
+
+FIELD  F_ApR5,       FLUX_AP_R5,     float,          Flux inside r = 5
+FIELD dF_ApR5,       FLUX_ERR_AP_R5, float,          Flux inside r = 5
+FIELD sF_ApR5,       FLUX_STD_AP_R5, float,          Flux inside r = 5
+FIELD fF_ApR5,       FLUX_FIL_AP_R5, float,          Flux inside r = 5
+
+FIELD  F_ApR6,       FLUX_AP_R6,     float,          Flux inside r = 6
+FIELD dF_ApR6,       FLUX_ERR_AP_R6, float,          Flux inside r = 6
+FIELD sF_ApR6,       FLUX_STD_R6,    float,          Flux inside r = 6
+FIELD fF_ApR6,       FLUX_AP_R6,     float,          Flux inside r = 6
+
+FIELD   detID,          DET_ID,      int,   	     detection ID
+FIELD   objID,          OBJ_ID,      int,   	     unique ID for object in table
+FIELD   catID,          CAT_ID,      int,   	     unique ID for table in which object was first realized
+FIELD  averef,         AVE_REF,      int,   	     reference to average entry      
+
+FIELD imageID,	       IMAGE_ID,     int,   	     reference to DVO image ID
+FIELD padding,	       PADDING,      int,   	     padding
+
+# 28 x float
+# 5 x int + padding
+# = 136 bytes / detection
+# for 2.5G objects + 60 overlaps, expect 15TB for forced warp
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/lensobj-ps1-v5.d
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/lensobj-ps1-v5.d	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/lensobj-ps1-v5.d	(revision 37403)
@@ -0,0 +1,53 @@
+STRUCT       Lensobj_PS1_V5
+EXTNAME      DVO_LENSOBJ_PS1_V5
+TYPE         BINTABLE
+SIZE         136
+DESCRIPTION  DVO Lensobj Table 
+
+FIELD X11_sm_obj,     X11_SM_OBJ,    float,          mean lensing smear object X11
+FIELD X12_sm_obj,     X12_SM_OBJ,    float,          mean lensing smear object X12
+FIELD X22_sm_obj,     X22_SM_OBJ,    float,          mean lensing smear object X22
+FIELD  E1_sm_obj,      E1_SM_OBJ,    float,          mean lensing smear object E1
+FIELD  E2_sm_obj,      E2_SM_OBJ,    float,          mean lensing smear object E2
+
+FIELD X11_sh_obj,     X11_SH_OBJ,    float,          mean lensing shear object X11
+FIELD X12_sh_obj,     X12_SH_OBJ,    float,          mean lensing shear object X12
+FIELD X22_sh_obj,     X22_SH_OBJ,    float,          mean lensing shear object X22
+FIELD  E1_sh_obj,      E1_SH_OBJ,    float,          mean lensing shear object E1
+FIELD  E2_sh_obj,      E2_SH_OBJ,    float,          mean lensing shear object E2
+
+FIELD X11_sm_psf,     X11_SM_PSF,    float,          mean lensing smear psf stars X11
+FIELD X12_sm_psf,     X12_SM_PSF,    float,          mean lensing smear psf stars X12
+FIELD X22_sm_psf,     X22_SM_PSF,    float,          mean lensing smear psf stars X22
+FIELD  E1_sm_psf,      E1_SM_PSF,    float,          mean lensing smear psf stars E1
+FIELD  E2_sm_psf,      E2_SM_PSF,    float,          mean lensing smear psf stars E2
+
+FIELD X11_sh_psf,     X11_SH_PSF,    float,          mean lensing shear psf stars X11
+FIELD X12_sh_psf,     X12_SH_PSF,    float,          mean lensing shear psf stars X12
+FIELD X22_sh_psf,     X22_SH_PSF,    float,          mean lensing shear psf stars X22
+FIELD  E1_sh_psf,      E1_SH_PSF,    float,          mean lensing shear psf stars E1
+FIELD  E2_sh_psf,      E2_SH_PSF,    float,          mean lensing shear psf stars E2
+
+FIELD F_ApR5,        FLUX_AP_R5,     float,          Flux inside r = 5
+FIELD dF_ApR5,       FLUX_ERR_AP_R5, float,          Flux inside r = 5
+FIELD sF_ApR5,       FLUX_STD_AP_R5, float,          Flux inside r = 5
+FIELD fF_ApR5,       FLUX_FIL_AP_R5, float,          Flux inside r = 5
+
+FIELD F_ApR6,        FLUX_AP_R6,     float,          Flux inside r = 5
+FIELD dF_ApR6,       FLUX_ERR_AP_R6, float,          Flux inside r = 5
+FIELD sF_ApR6,       FLUX_AP_R6,     float,          Flux inside r = 5
+FIELD fF_ApR6,       FLUX_AP_R6,     float,          Flux inside r = 5
+
+FIELD  gamma,            GAMMA,      float
+FIELD     E1,               E1,      float
+FIELD     E2,               E2,      float
+
+FIELD    objID,          OBJ_ID,       unsigned int,   unique ID for object in table
+FIELD    catID,          CAT_ID,       unsigned int,   unique ID for table in which object was first realized
+FIELD photcode,         PHOTCODE,    short
+FIELD    Nmeas,            NMEAS,    short
+
+# 31 x float
+#  3 x int
+# = 136 bytes / detection
+# for 2.5G objects + 60 overlaps, expect 15TB for forced warp
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/lensobj.d
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/lensobj.d	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/lensobj.d	(revision 37403)
@@ -0,0 +1,53 @@
+STRUCT       Lensobj
+EXTNAME      DVO_LENSOBJ
+TYPE         BINTABLE
+SIZE         136
+DESCRIPTION  DVO Lensobj Table 
+
+FIELD X11_sm_obj,     X11_SM_OBJ,    float,          mean lensing smear object X11
+FIELD X12_sm_obj,     X12_SM_OBJ,    float,          mean lensing smear object X12
+FIELD X22_sm_obj,     X22_SM_OBJ,    float,          mean lensing smear object X22
+FIELD  E1_sm_obj,      E1_SM_OBJ,    float,          mean lensing smear object E1
+FIELD  E2_sm_obj,      E2_SM_OBJ,    float,          mean lensing smear object E2
+
+FIELD X11_sh_obj,     X11_SH_OBJ,    float,          mean lensing shear object X11
+FIELD X12_sh_obj,     X12_SH_OBJ,    float,          mean lensing shear object X12
+FIELD X22_sh_obj,     X22_SH_OBJ,    float,          mean lensing shear object X22
+FIELD  E1_sh_obj,      E1_SH_OBJ,    float,          mean lensing shear object E1
+FIELD  E2_sh_obj,      E2_SH_OBJ,    float,          mean lensing shear object E2
+
+FIELD X11_sm_psf,     X11_SM_PSF,    float,          mean lensing smear psf stars X11
+FIELD X12_sm_psf,     X12_SM_PSF,    float,          mean lensing smear psf stars X12
+FIELD X22_sm_psf,     X22_SM_PSF,    float,          mean lensing smear psf stars X22
+FIELD  E1_sm_psf,      E1_SM_PSF,    float,          mean lensing smear psf stars E1
+FIELD  E2_sm_psf,      E2_SM_PSF,    float,          mean lensing smear psf stars E2
+
+FIELD X11_sh_psf,     X11_SH_PSF,    float,          mean lensing shear psf stars X11
+FIELD X12_sh_psf,     X12_SH_PSF,    float,          mean lensing shear psf stars X12
+FIELD X22_sh_psf,     X22_SH_PSF,    float,          mean lensing shear psf stars X22
+FIELD  E1_sh_psf,      E1_SH_PSF,    float,          mean lensing shear psf stars E1
+FIELD  E2_sh_psf,      E2_SH_PSF,    float,          mean lensing shear psf stars E2
+
+FIELD     F_ApR5,    FLUX_AP_R5,     float,          Flux inside r = 5
+FIELD    dF_ApR5,    FLUX_ERR_AP_R5, float,          Flux inside r = 5
+FIELD    sF_ApR5,    FLUX_STD_AP_R5, float,          Flux inside r = 5
+FIELD    fF_ApR5,    FLUX_FIL_AP_R5, float,          Flux inside r = 5
+
+FIELD     F_ApR6,    FLUX_AP_R6,     float,          Flux inside r = 5
+FIELD    dF_ApR6,    FLUX_ERR_AP_R6, float,          Flux inside r = 5
+FIELD    sF_ApR6,    FLUX_AP_R6,     float,          Flux inside r = 5
+FIELD    fF_ApR6,    FLUX_AP_R6,     float,          Flux inside r = 5
+
+FIELD      gamma,        GAMMA,      float
+FIELD         E1,           E1,      float
+FIELD         E2,           E2,      float
+
+FIELD    objID,           OBJ_ID,    unsigned int,   unique ID for object in table
+FIELD    catID,           CAT_ID,    unsigned int,   unique ID for table in which object was first realized
+FIELD photcode,         PHOTCODE,    short
+FIELD    Nmeas,            NMEAS,    short
+
+# 31 x float
+#  3 x int
+# = 136 bytes / detection
+# for 2.5G objects + 60 overlaps, expect 15TB for forced warp
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/measure-ps1-v5.d
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/measure-ps1-v5.d	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/measure-ps1-v5.d	(revision 37403)
@@ -0,0 +1,108 @@
+STRUCT       Measure_PS1_V5
+EXTNAME      DVO_MEASURE_PS1_V5
+TYPE         BINTABLE
+SIZE         232
+DESCRIPTION  DVO Detection Measurement Table 
+
+FIELD R,              RA,            double,         RA at epoch,                  degrees
+FIELD D,              DEC,           double,         DEC at epoch,                 degrees
+FIELD M,              MAG,           float,          catalog mag,                  mag
+FIELD dM,             MAG_ERR,       float,          mag error,                    mag
+FIELD Map,            M_APER,        float,          aperture mag,                 mag
+FIELD dMap,           M_APER_ERR,    float,          aperture mag,                 mag
+FIELD Mkron,          M_KRON,        float,          kron magnitude,               mag
+FIELD dMkron,         M_KRON_ERR,    float,          kron magnitude error,         mag
+FIELD Mcal,           M_CAL,         float,          image cal mag,                mag
+FIELD dMcal,          MAG_CAL_ERR,   float,          systematic calibration error, mag
+FIELD dt,             M_TIME,        float,          exposure time,                2.5*log(exptime)
+
+# needed for stacks, forced warp, and diff
+FIELD FluxPSF,        FLUX_PSF,      float,          flux from psf fit,            counts/sec
+FIELD dFluxPSF,       FLUX_PSF_ERR,  float,          error on psf flux,            counts/sec
+FIELD FluxKron,       FLUX_KRON,     float,          flux from kron ap,            counts/sec
+FIELD dFluxKron,      FLUX_KRON_ERR, float,          error on kron flux,           counts/sec
+FIELD FluxAp,         FLUX_AP,       float,          flux from ap ap,              counts/sec
+FIELD dFluxAp,        FLUX_AP_ERR,   float,          error on ap flux,             counts/sec
+
+# note that with airmass = 1.0 / cos(90 - alt), we have full alt/az representation
+FIELD airmass,        AIRMASS,       float,          (airmass - 1),                airmass
+FIELD az,             AZ,            float,          telescope azimuth
+
+# new field elements needed for Pan-STARRS:
+FIELD Xccd,           X_CCD,         float,          X coord on chip (raw value),  pixels
+FIELD Yccd,           Y_CCD,         float,          Y coord on chip (raw value),  pixels
+                                     
+FIELD Xfix,           X_FIX,         float,          X coord after correction,     pixels
+FIELD Yfix,           Y_FIX,         float,          Y coord after correction,     pixels
+                                     
+FIELD XoffKH,         X_OFF_KH,      float,          X offset from correction,     pixels
+FIELD YoffKH,         Y_OFF_KH,      float,          Y offset from correction,     pixels
+FIELD XoffDCR,        X_OFF_DCR,     float,          X offset from correction,     pixels
+FIELD YoffDCR,        Y_OFF_DCR,     float,          Y offset from correction,     pixels
+FIELD RoffGAL,        R_OFF_GAL,     float,          RA offset from correction,    arcsec
+FIELD DoffGAL,        D_OFF_GAL,     float,          DEC offset from correction,   arcsec
+
+# could these be packed into fewer bits?
+FIELD Sky,            SKY_FLUX,      float,          local estimate of sky flux,   counts/sec
+FIELD dSky,           SKY_FLUX_ERR,  float,          local estimate of sky flux,   counts/sec
+
+FIELD t,              TIME,          int,            time in seconds (UNIX)
+FIELD averef,         AVE_REF,       unsigned int,   reference to average entry      
+
+# internally, this is an unsigned int; however, we do NOT convert with TZERO/TSCAL on output
+FIELD detID,          DET_ID,        unsigned int,   detection ID
+FIELD objID,          OBJ_ID,        unsigned int,   unique ID for object in table
+FIELD catID,          CAT_ID,        unsigned int,   unique ID for table in which object was first realized
+
+# extID needs to be on an 8-byte boundary
+# PSPS uses a 64-bit detection ID
+FIELD extID,          EXT_ID,        uint64_t,       external ID (eg PSPS detID)
+
+FIELD imageID,        IMAGE_ID,      unsigned int,   reference to DVO image ID
+
+# do we need more resolution than a short? should this be a log?
+FIELD psfQF,          PSF_QF,        float,          psf coverage/quality factor
+FIELD psfQFperf,      PSF_QF_PEFECT, float,          psf coverage / quality factor (all mask bits)
+FIELD psfChisq,       PSF_CHISQ,     float,          psf fit chisq
+
+FIELD psfNdof,        PSF_NDOF,      int,            psf degrees of freedom
+FIELD psfNpix,        PSF_NPIX,      int,            psf number of pixels
+FIELD photFlags2,     PHOT_FLAGS,    int,            flags supplied by photometry program
+FIELD extNsigma,      EXT_NSIGMA,    float,          Nsigma deviation towards EXT
+
+# model shape parameters
+FIELD FWx,            FWHM_MAJOR,   short,          object fwhm major axis,         1/100 of pixels
+FIELD FWy,            FWHM_MINOR,   short,          object fwhm minor axis,         1/100 of pixels 
+FIELD theta,          PSF_THETA,    short,          angle wrt ccd X dir,            (0xffff/360) deg
+
+# moments
+FIELD Mxx,            MXX,          short,          second moments in pixel coords, 1/100 of pixels
+FIELD Mxy,            MXY,          short,          second moments in pixel coords, 1/100 of pixels
+FIELD Myy,            MYY,          short,          second moments in pixel coords, 1/100 of pixels
+
+# fractional exposure time
+FIELD t_msec,         TIME_MSEC,    unsigned short, time fraction of second,        milliseconds
+FIELD photcode,       PHOTCODE,     unsigned short, photcode
+
+# position errors
+FIELD dXccd,          X_CCD_ERR,    short,          X coord error on chip,          1/100 of pixels
+FIELD dYccd,          Y_CCD_ERR,    short,          Y coord error on chip,          1/100 of pixels
+FIELD dRsys,          POS_SYS_ERR,  short,          systematic error from astrom,   1/100 of pixels
+
+# local astrometry scales
+FIELD posangle,       POSANGLE,     short,          position angle sky to chip,     (0xffff/360) deg
+FIELD pltscale,       PLTSCALE,     float,          plate scale,                    arcsec/pixel
+
+FIELD dbFlags,        DB_FLAGS,     unsigned int,   flags supplied by analysis in database
+FIELD photFlags,      PHOT_FLAGS,   unsigned int,   flags supplied by photometry program
+
+FIELD padding,        PADDING,       int,            padding to ensure 8byte blocks
+
+# 2 x double
+# 35 x float
+# 11 x int or unsigned int
+# 12 x short or unsigned short
+# 1 x uint64_t
+# = 232 bytes / detection
+# for 2.5G objects * 60 overlaps, expect 35TB for forced warp
+# for 120G detections, expect 28TB
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/measure.d
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/measure.d	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/measure.d	(revision 37403)
@@ -2,23 +2,26 @@
 EXTNAME      DVO_MEASURE
 TYPE         BINTABLE
-SIZE         184
+SIZE         228
 DESCRIPTION  DVO Detection Measurement Table 
 
-FIELD dR,             D_RA,         float,          RA offset,                      arcsec
-FIELD dD,             D_DEC,        float,          DEC offset,                     arcsec
-FIELD M,              MAG,          float,          catalog mag,                    mag
-FIELD Mcal,           M_CAL,        float,          image cal mag,                  mag
-FIELD Map,            M_APER,       float,          aperture mag,                   mag
-FIELD Mkron,          M_KRON,       float,          kron magnitude,                 mag
-FIELD dMkron,         M_KRON_ERR,   float,          kron magnitude error,           mag
-FIELD dM,             MAG_ERR,      float,          mag error,                      mag
-FIELD dMcal,          MAG_CAL_ERR,  float,          systematic calibration error,   mag
-FIELD dt,             M_TIME,       float,          exposure time,                  2.5*log(exptime)
+FIELD R,              RA,            double,         RA at epoch,                  degrees
+FIELD D,              DEC,           double,         DEC at epoch,                 degrees
+FIELD M,              MAG,           float,          catalog mag,                    mag
+FIELD dM,             MAG_ERR,       float,          mag error,                      mag
+FIELD Map,            M_APER,        float,          aperture mag,                   mag
+FIELD dMap,           M_APER,        float,          aperture mag,                   mag
+FIELD Mkron,          M_KRON,        float,          kron magnitude,                 mag
+FIELD dMkron,         M_KRON_ERR,    float,          kron magnitude error,           mag
+FIELD Mcal,           M_CAL,         float,          image cal mag,                  mag
+FIELD dMcal,          MAG_CAL_ERR,   float,          systematic calibration error,   mag
+FIELD dt,             M_TIME,        float,          exposure time,                  2.5*log(exptime)
 
 # for stacks only?
-FIELD FluxPSF,        FLUX_PSF,     float,          flux from psf fit,              counts/sec?
-FIELD dFluxPSF,       FLUX_PSF_ERR, float,          error on psf flux,              counts/sec?
-FIELD FluxKron,       FLUX_KRON,     float,         flux from kron ap,              counts/sec?
-FIELD dFluxKron,      FLUX_KRON_ERR, float,         error on kron flux,             counts/sec?
+FIELD FluxPSF,        FLUX_PSF,      float,         flux from psf fit,              counts/sec
+FIELD dFluxPSF,       FLUX_PSF_ERR,  float,         error on psf flux,              counts/sec
+FIELD FluxKron,       FLUX_KRON,     float,         flux from kron ap,              counts/sec
+FIELD dFluxKron,      FLUX_KRON_ERR, float,         error on kron flux,             counts/sec
+FIELD FluxAp,         FLUX_AP,       float,         flux from ap,                   counts/sec
+FIELD dFluxAp,        FLUX_AP_ERR,   float,         error on ap flux,               counts/sec
 
 # note that with airmass = 1.0 / cos(90 - alt), we have full alt/az representation
@@ -33,4 +36,11 @@
 FIELD Yfix,           Y_FIX,        float,          Y coord after correction,     pixels
 
+FIELD XoffKH,         X_OFF_KH,      float,          X offset from correction,     pixels
+FIELD YoffKH,         Y_OFF_KH,      float,          Y offset from correction,     pixels
+FIELD XoffDCR,        X_OFF_DCR,     float,          X offset from correction,     pixels
+FIELD YoffDCR,        Y_OFF_DCR,     float,          Y offset from correction,     pixels
+FIELD RoffGAL,        R_OFF_GAL,     float,          RA offset from correction,    arcsec
+FIELD DoffGAL,        D_OFF_GAL,     float,          DEC offset from correction,   arcsec
+
 # could these be packed into fewer bits?
 FIELD Sky,            SKY_FLUX,     float,          local estimate of sky flux,     counts/sec
@@ -38,9 +48,7 @@
 
 FIELD t,              TIME,         int,            time in seconds (UNIX)
-FIELD t_msec,         TIME_MSEC,    unsigned short, time fraction of second,        milliseconds
 FIELD averef,         AVE_REF,      unsigned int,   reference to average entry      
 
 FIELD detID,          DET_ID,       unsigned int,   detection ID
-FIELD imageID,        IMAGE_ID,     unsigned int,   reference to DVO image ID
 FIELD objID,          OBJ_ID,       unsigned int,   unique ID for object in table
 FIELD catID,          CAT_ID,       unsigned int,   unique ID for table in which object was first realized
@@ -48,4 +56,6 @@
 # PSPS uses a 64-bit detection ID
 FIELD extID,          EXT_ID,       uint64_t,       external ID (eg PSPS detID)
+
+FIELD imageID,        IMAGE_ID,     unsigned int,   reference to DVO image ID
 
 # do we need more resolution than a short? should this be a log?
@@ -56,5 +66,5 @@
 FIELD psfNdof,        PSF_NDOF,      int,            psf degrees of freedom
 FIELD psfNpix,        PSF_NPIX,      int,            psf number of pixels
-FIELD crNsigma,       CR_NSIGMA,     float,          Nsigma deviation towards CR
+FIELD photFlags2,     PHOT_FLAGS,    int,            flags supplied by photometry program
 FIELD extNsigma,      EXT_NSIGMA,    float,          Nsigma deviation towards EXT
 
@@ -69,4 +79,8 @@
 FIELD Myy,            MYY,          short,          second moments in pixel coords, 1/100 of pixels^2
 
+# fractional exposure time
+FIELD t_msec,         TIME_MSEC,    unsigned short, time fraction of second,        milliseconds
+FIELD photcode,       PHOTCODE,     unsigned short, photcode
+
 # convert this to error in pixels on load?
 FIELD dXccd,          X_CCD_ERR,    short,          X coord error on chip,          1/100 of pixels
@@ -77,5 +91,4 @@
 FIELD pltscale,       PLTSCALE,     float,          plate scale,                    arcsec/pixel
 
-FIELD photcode,       PHOTCODE,     unsigned short, photcode
 FIELD dbFlags,        DB_FLAGS,     unsigned int,   flags supplied by analysis in database
 FIELD photFlags,      PHOT_FLAGS,   unsigned int,   flags supplied by photometry program
@@ -85,3 +98,6 @@
 #                Changed dbFlags, photFlags : uint16_t to uint64_t
 
+# *** 20140617 : changed: dR,dD -> R,D (removed dependence on average.R,D)
+      	       	 added: dMap, FluxAp, dFluxAp, (X,Y)off(KH,DCR,GAL)
+
 # XXX unsigned int values are probably not being saved in the FITS file correctly: no BZERO, BSCALE
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/photcode-ps1-v2.d
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/photcode-ps1-v2.d	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/photcode-ps1-v2.d	(revision 37403)
@@ -22,9 +22,9 @@
 FIELD  astromErrScale,    ASTROM_ERR_SCALE,  	 float,          astrometric error scale
 FIELD  astromErrMagScale, ASTROM_ERR_MAG_SCALE,  float,          astrometric error / mag error scale
-FIELD  astromPoorMask,    ASTROM_POOR_MASK,      short,          detections matching this mask should only be used in emergencies
-FIELD  astromBadMask,     ASTROM_BAD_MASK,       short,          detections matching this mask should not be used
+FIELD  astromPoorMask,    ASTROM_POOR_MASK,      unsigned short,   detections matching this mask should only be used in emergencies
+FIELD  astromBadMask,     ASTROM_BAD_MASK,       unsigned short,   detections matching this mask should not be used
 FIELD  photomErrSys,   	  PHOTOM_ERR_SYS,  	 float,          systematic photometric error
-FIELD  photomPoorMask, 	  PHOTOM_POOR_MASK,  	 short,          detections matching this mask should only be used in emergencies
-FIELD  photomBadMask,  	  PHOTOM_BAD_MASK,  	 short,          detections matching this mask should not be used
+FIELD  photomPoorMask, 	  PHOTOM_POOR_MASK,  	 unsigned short,   detections matching this mask should only be used in emergencies
+FIELD  photomBadMask,  	  PHOTOM_BAD_MASK,  	 unsigned short,   detections matching this mask should not be used
 
 #   dR_total^2 =  dR_sys^2 + AS * dR_obs^2 + MS * dM_obs^2
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/photcode-ps1-v3.d
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/photcode-ps1-v3.d	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/photcode-ps1-v3.d	(revision 37403)
@@ -22,9 +22,9 @@
 FIELD  astromErrScale,    ASTROM_ERR_SCALE,  	 float,          astrometric error scale
 FIELD  astromErrMagScale, ASTROM_ERR_MAG_SCALE,  float,          astrometric error / mag error scale
-FIELD  astromPoorMask,    ASTROM_POOR_MASK,      int,            detections matching this mask should only be used in emergencies
-FIELD  astromBadMask,     ASTROM_BAD_MASK,       int,            detections matching this mask should not be used
+FIELD  astromPoorMask,    ASTROM_POOR_MASK,      unsigned int,   detections matching this mask should only be used in emergencies
+FIELD  astromBadMask,     ASTROM_BAD_MASK,       unsigned int,   detections matching this mask should not be used
 FIELD  photomErrSys,   	  PHOTOM_ERR_SYS,  	 float,          systematic photometric error
-FIELD  photomPoorMask, 	  PHOTOM_POOR_MASK,  	 int,            detections matching this mask should only be used in emergencies
-FIELD  photomBadMask,  	  PHOTOM_BAD_MASK,  	 int,            detections matching this mask should not be used
+FIELD  photomPoorMask, 	  PHOTOM_POOR_MASK,  	 unsigned int,   detections matching this mask should only be used in emergencies
+FIELD  photomBadMask,  	  PHOTOM_BAD_MASK,  	 unsigned int,   detections matching this mask should not be used
 
 #   dR_total^2 =  dR_sys^2 + AS * dR_obs^2 + MS * dM_obs^2
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/photcode-ps1-v4.d
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/photcode-ps1-v4.d	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/photcode-ps1-v4.d	(revision 37403)
@@ -22,9 +22,9 @@
 FIELD  astromErrScale,    ASTROM_ERR_SCALE,  	 float,          astrometric error scale
 FIELD  astromErrMagScale, ASTROM_ERR_MAG_SCALE,  float,          astrometric error / mag error scale
-FIELD  astromPoorMask,    ASTROM_POOR_MASK,      int,            detections matching this mask should only be used in emergencies
-FIELD  astromBadMask,     ASTROM_BAD_MASK,       int,            detections matching this mask should not be used
+FIELD  astromPoorMask,    ASTROM_POOR_MASK,      unsigned int,   detections matching this mask should only be used in emergencies
+FIELD  astromBadMask,     ASTROM_BAD_MASK,       unsigned int,   detections matching this mask should not be used
 FIELD  photomErrSys,   	  PHOTOM_ERR_SYS,  	 float,          systematic photometric error
-FIELD  photomPoorMask, 	  PHOTOM_POOR_MASK,  	 int,            detections matching this mask should only be used in emergencies
-FIELD  photomBadMask,  	  PHOTOM_BAD_MASK,  	 int,            detections matching this mask should not be used
+FIELD  photomPoorMask, 	  PHOTOM_POOR_MASK,  	 unsigned int,   detections matching this mask should only be used in emergencies
+FIELD  photomBadMask,  	  PHOTOM_BAD_MASK,  	 unsigned int,   detections matching this mask should not be used
 
 #   dR_total^2 =  dR_sys^2 + AS * dR_obs^2 + MS * dM_obs^2
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/photcode-ps1-v5.d
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/photcode-ps1-v5.d	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/photcode-ps1-v5.d	(revision 37403)
@@ -0,0 +1,33 @@
+STRUCT       PhotCode_PS1_V5
+EXTNAME      DVO_PHOTCODE_PS1_V5
+TYPE         BINTABLE
+SIZE         112
+DESCRIPTION  DVO Photcode Description Table 
+
+# elements of data structure / FITS table
+FIELD  code,         	  CODE,          	 unsigned short, code number (stored in Measure.source) 
+FIELD  name,         	  NAME,          	 char[32],       name for filter combination 
+FIELD  type,         	  TYPE,          	 char,           PRI/SEC/DEP/REF 
+FIELD  dummy,        	  DUMMY,         	 char[3],        padding
+FIELD  C,            	  C_LAM,         	 short,          primary phot calibration terms (millimags) 
+FIELD  dC,           	  C_LAM_ERR,     	 short,          primary phot calibration terms (millimags) 
+FIELD  dX,           	  X_ERR,         	 short,          primary phot calibration terms (millimags) 
+FIELD  K,            	  K,             	 float,          secondary phot calibration terms (millimags) 
+FIELD  c1,           	  C1,            	 int,            color is average.M[c1] - average.M[c2] 
+FIELD  c2,           	  C2,            	 int,            color is average.M[c1] - average.M[c2] 
+FIELD  equiv,        	  EQUIV,         	 int,            this dependent filter is equivalent to equiv PRI/SEC
+FIELD  Nc,           	  NC,            	 int,            number of color terms 
+FIELD  X,            	  X,             	 float[4],       color terms $X[0]*mc + X[1]*mc^2 + X[2]*mc^3$, etc 
+FIELD  astromErrSys,      ASTROM_ERR_SYS,  	 float,          systematic astrometry error (arcsec)
+FIELD  astromErrScale,    ASTROM_ERR_SCALE,  	 float,          astrometric error scale
+FIELD  astromErrMagScale, ASTROM_ERR_MAG_SCALE,  float,          astrometric error / mag error scale
+FIELD  astromPoorMask,    ASTROM_POOR_MASK,      unsigned int,   detections matching this mask should only be used in emergencies
+FIELD  astromBadMask,     ASTROM_BAD_MASK,       unsigned int,   detections matching this mask should not be used
+FIELD  photomErrSys,   	  PHOTOM_ERR_SYS,  	 float,          systematic photometric error
+FIELD  photomPoorMask, 	  PHOTOM_POOR_MASK,  	 unsigned int,   detections matching this mask should only be used in emergencies
+FIELD  photomBadMask,  	  PHOTOM_BAD_MASK,  	 unsigned int,   detections matching this mask should not be used
+
+#   dR_total^2 =  dR_sys^2 + AS * dR_obs^2 + MS * dM_obs^2
+#   dR_sys : systematicAstrometryError
+#   AS     : astrometryErrorScale
+#   MS     : astrometryErrorMagScale
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/photcode.d
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/photcode.d	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/photcode.d	(revision 37403)
@@ -22,9 +22,9 @@
 FIELD  astromErrScale,    ASTROM_ERR_SCALE,  	 float,          astrometric error scale
 FIELD  astromErrMagScale, ASTROM_ERR_MAG_SCALE,  float,          astrometric error / mag error scale
-FIELD  astromPoorMask,    ASTROM_POOR_MASK,      int,            detections matching this mask should only be used in emergencies
-FIELD  astromBadMask,     ASTROM_BAD_MASK,       int,            detections matching this mask should not be used
+FIELD  astromPoorMask,    ASTROM_POOR_MASK,      unsigned int,   detections matching this mask should only be used in emergencies
+FIELD  astromBadMask,     ASTROM_BAD_MASK,       unsigned int,   detections matching this mask should not be used
 FIELD  photomErrSys,   	  PHOTOM_ERR_SYS,  	 float,          systematic photometric error
-FIELD  photomPoorMask, 	  PHOTOM_POOR_MASK,  	 int,            detections matching this mask should only be used in emergencies
-FIELD  photomBadMask,  	  PHOTOM_BAD_MASK,  	 int,            detections matching this mask should not be used
+FIELD  photomPoorMask, 	  PHOTOM_POOR_MASK,  	 unsigned int,   detections matching this mask should only be used in emergencies
+FIELD  photomBadMask,  	  PHOTOM_BAD_MASK,  	 unsigned int,   detections matching this mask should not be used
 
 #   dR_total^2 =  dR_sys^2 + AS * dR_obs^2 + MS * dM_obs^2
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/secfilt-ps1-v1.d
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/secfilt-ps1-v1.d	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/secfilt-ps1-v1.d	(revision 37403)
@@ -6,9 +6,9 @@
 
 # elements of data structure / FITS table
-FIELD  M,     MAG,      float,                average mag in this band, mags
-FIELD  dM,    MAG_ERR,  float,                error on average mag,     mags
-FIELD  Xm,    MAG_CHI,  float,                chisq on average mag,     [100*log(value)]
-FIELD  Ncode, NCODE,    short,                number of detections in band
-FIELD  Nused, NUSED,    short,                number of detections used in average
-FIELD  M_20,  MAG_20,   short,                lower 20percent mag,      millimags
-FIELD  M_80,  MAG_80,   short,                upper 20percent mag,      millimags
+FIELD  M,      MAG,      float,                average mag in this band, mags
+FIELD  dM,     MAG_ERR,  float,                error on average mag,     mags
+FIELD  Mchisq, MAG_CHI,  float,                chisq on average mag,                  value
+FIELD  Ncode,  NCODE,    short,                number of detections in band
+FIELD  Nused,  NUSED,    short,                number of detections used in average
+FIELD  M_20,   MAG_20,   short,                lower 20percent mag,      millimags
+FIELD  M_80,   MAG_80,   short,                upper 20percent mag,      millimags
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/secfilt-ps1-v2.d
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/secfilt-ps1-v2.d	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/secfilt-ps1-v2.d	(revision 37403)
@@ -6,10 +6,10 @@
 
 # elements of data structure / FITS table
-FIELD  M,     MAG,      float,                average mag in this band, mags
-FIELD  dM,    MAG_ERR,  float,                error on average mag,     mags
-FIELD  Xm,    MAG_CHI,  float,                chisq on average mag,     [100*log(value)]
-FIELD  flags, FLAGS,    uint32_t,             photometry flags
-FIELD  Ncode, NCODE,    short,                number of detections in band
-FIELD  Nused, NUSED,    short,                number of detections used in average
-FIELD  M_20,  MAG_20,   short,                lower 20percent mag,      millimags
-FIELD  M_80,  MAG_80,   short,                upper 20percent mag,      millimags
+FIELD  M,      MAG,      float,                average mag in this band, mags
+FIELD  dM,     MAG_ERR,  float,                error on average mag,     mags
+FIELD  Mchisq, MAG_CHI,  float,                chisq on average mag,     value
+FIELD  flags,  FLAGS,    uint32_t,             photometry flags
+FIELD  Ncode,  NCODE,    short,                number of detections in band
+FIELD  Nused,  NUSED,    short,                number of detections used in average
+FIELD  M_20,   MAG_20,   short,                lower 20percent mag,      millimags
+FIELD  M_80,   MAG_80,   short,                upper 20percent mag,      millimags
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/secfilt-ps1-v3.d
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/secfilt-ps1-v3.d	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/secfilt-ps1-v3.d	(revision 37403)
@@ -9,5 +9,5 @@
 FIELD  Map,    	    MAG_AP,    	  float,      ave aperture mag in this band,         mags
 FIELD  dM,    	    MAG_ERR,  	  float,      formal error on average mag,           mags
-FIELD  Xm,    	    MAG_CHI,  	  float,      chisq on average mag,                  [100*log(value)]
+FIELD  Mchisq,      MAG_CHI,      float,      chisq on average mag,                  value
 FIELD  flags, 	    FLAGS,    	  uint32_t,   photometry flags
 FIELD  Ncode, 	    NCODE,    	  short,      number of detections in band
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/secfilt-ps1-v4.d
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/secfilt-ps1-v4.d	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/secfilt-ps1-v4.d	(revision 37403)
@@ -11,5 +11,5 @@
 FIELD  dMkron,        MAG_KRON_ERR,    float,      formal error on average kron mag,      mags
 FIELD  dM,            MAG_ERR,         float,      formal error on average mag,           mags
-FIELD  Xm,            MAG_CHI,         float,      chisq on average mag,                  [100*log(value)]
+FIELD  Mchisq,        MAG_CHI,         float,      chisq on average mag,                  value
 FIELD  FluxPSF,       FLUX_PSF,        float,      mean flux psf fit (PS1: stack)
 FIELD  dFluxPSF,      FLUX_PSF_ERR,    float,      mean flux psf error
@@ -23,3 +23,4 @@
 FIELD  ubercalDist,   UBERCAL_DIST,    short,      number of images from an ubercal-image
 FIELD  Mstdev,        MAG_STDEV,       short,      standard deviation of measurements,    millimags
-FIELD  stackDetectID, STACK_DETECT_ID, uint64_t,   detection ID on stack used for fluxes (if any)
+FIELD  stackPrmryOff, STACK_PRIMARY_OFF, int,      measure entry which is primary stack detection
+FIELD  stackBestOff,  STACK_BEST_OFF,    int,      measure entry which is best stack detection
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/secfilt-ps1-v5.d
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/secfilt-ps1-v5.d	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/secfilt-ps1-v5.d	(revision 37403)
@@ -0,0 +1,81 @@
+STRUCT       SecFilt_PS1_V5
+EXTNAME      DVO_SECFILT_PS1_V5
+TYPE         BINTABLE
+SIZE         176
+DESCRIPTION  DVO SecFilt : Secondary Filter Data 
+
+## *** this section is for per-exposure mean values *** (unlabled values are implicitly PSF values)
+FIELD  M,             MAG,               float,    average mag in this band,              mags
+FIELD  dM,            MAG_ERR,           float,    formal error on average mag,           mags
+FIELD  Map,           MAG_AP,            float,    ave aperture mag in this band,         mags
+FIELD  dMap,          MAG_AP_ERR,        float,    ave aperture mag in this band,         mags
+FIELD  sMap,          MAG_AP_STDEV,    float,      standard deviation of ap mags,         mags
+FIELD  Mkron,         MAG_KRON,          float,    ave kron mag in this band,             mags
+FIELD  dMkron,        MAG_KRON_ERR,      float,    formal error on average kron mag,      mags
+FIELD  sMkron,        MAG_KRON_STDEV,  float,      standard deviation of kron mags,       mags
+				         
+# XXX I could add these fields to secfilt or calculate in dvopsps?
+FIELD  psfQfMax,      PSF_QF_MAX,      float,      best psfQf for this filter
+FIELD  psfQfPerfMax,  PSF_QF_PERF_MAX, float,      best psfQfPerfect for this filter
+
+# these statistics are PSF-specific      
+FIELD  Mstdev,        MAG_STDEV,         float,    standard deviation of measurements,    mags
+FIELD  Mmin,          MAG_MIN,           float,    min accepted mag,                      mags
+FIELD  Mmax,          MAG_MAX,           float,    max accepted mag,                      mags
+FIELD  Mchisq,        MAG_CHI,           float,    chisq on average mag,                  value
+				         
+FIELD  Ncode,         NCODE,             short,    number of detections in band
+FIELD  Nused,         NUSED,             short,    number of detections used in average
+FIELD  NusedKron,     NUSED_KRON,        short,    number of detections used in average
+FIELD  NusedAp,       NUSED_AP,          short,    number of detections used in average
+				         
+FIELD  flags,         FLAGS,             uint32_t, photometry flags
+
+## *** this section is for stack values ***
+
+FIELD  MpsfStk,       MAG_PSF_STK,       float,    magnitude from stack (primary if available)
+FIELD  FpsfStk,       FLUX_PSF_STK,      float,    flux from stack (primary if available)
+FIELD  dFpsfStk,      FLUX_PSF_STK_ERR,  float,    mean flux psf error
+
+FIELD  MkronStk,      MAG_KRON_STK,      float,    magnitude from stack (primary if available)
+FIELD  FkronStk,      FLUX_KRON_STK,     float,    flux from stack (primary if available)
+FIELD  dFkronStk,     FLUX_KRON_STK_ERR, float,    mean flux kron error
+
+FIELD  MapStk,        MAG_AP_STK,        float,    magnitude from stack (primary if available)
+FIELD  FapStk,        FLUX_AP_STK,       float,    flux from stack (primary if available)
+FIELD  dFapStk,       FLUX_AP_STK_ERR,   float,    mean flux ap error
+
+FIELD  Nstack,        NSTACK,            short,    number of measurements in band (gpc1 stack only)
+FIELD  NstackDet,     NSTACK_DET,        short,    number of stack detections in band (gpc1 stack only)
+
+FIELD  stackPrmryOff, STACK_PRIMARY_OFF,  int,     measure entry which is primary stack detection
+FIELD  stackBestOff,  STACK_BEST_OFF,     int,     measure entry which is best stack detection
+
+## *** this section is for forced-warp mean values ***
+
+FIELD  MpsfWrp,       MAG_PSF_WRP,       float,    psf magnitude from stack (primary if available)
+FIELD  FpsfWrp,       FLUX_PSF_WRP,      float,    psf flux from stack (primary if available)
+FIELD  dFpsfWrp,      FLUX_PSF_WRP_ERR,  float,    mean flux psf error
+FIELD  sFpsfWrp,      FLUX_PSF_WRP_STD,  float,    mean flux psf stdev
+
+FIELD  MkronWrp,      MAG_KRON_WRP,      float,    kron magnitude from stack (primary if available)
+FIELD  FkronWrp,      FLUX_KRON_WRP,     float,    kron flux from stack (primary if available)
+FIELD  dFkronWrp,     FLUX_KRON_WRP_ERR, float,    mean flux kron error
+FIELD  sFkronWrp,     FLUX_KRON_WRP_STD, float,    mean flux kron stdev
+
+FIELD  MapWrp,        MAG_AP_WRP,        float,    aper magnitude from stack (primary if available)
+FIELD  FapWrp,        FLUX_AP_WRP,       float,    aper flux from stack (primary if available)
+FIELD  dFapWrp,       FLUX_AP_WRP_ERR,   float,    mean flux ap error
+FIELD  sFapWrp,       FLUX_AP_WRP_STD,   float,    mean flux ap stdev
+
+FIELD  NusedWrp,      NUSED_WRP,         short,    number of detections used in average
+FIELD  NusedKronWrp,  NUSED_KRON_WRP,    short,    number of detections used in average
+FIELD  NusedApWrp,    NUSED_AP_WRP,      short,    number of detections used in average
+
+FIELD  Nwarp,         NWARP,             short,    number of measurements in band (gpc1 warp only)
+FIELD  NwarpGood,     NWARP_GOOD,        short,    number of meas with psf_qf > 0.85 in band (gpc1 warp only)
+
+FIELD  ubercalDist,   UBERCAL_DIST,      short,    number of images from an ubercal-image
+
+# 31*float + uint32_t + uint64_t + 8*short = 152 bytes / object / photcode
+# for 5G objects, expect ~6TB total (over 60 machines, this is 100G)
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/secfilt.d
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/secfilt.d	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/def/secfilt.d	(revision 37403)
@@ -2,28 +2,85 @@
 EXTNAME      DVO_SECFILT
 TYPE         BINTABLE
-SIZE         64
+SIZE         176
 DESCRIPTION  DVO SecFilt : Secondary Filter Data 
 
-# elements of data structure / FITS table
+## *** this section is for per-exposure mean values *** (unlabled values are implicitly PSF values)
 FIELD  M,             MAG,             float,      average mag in this band,              mags
+FIELD  dM,            MAG_ERR,         float,      formal error on average mag,           mags
 FIELD  Map,           MAG_AP,          float,      average mag in this band,              mags
+FIELD  dMap,          MAG_AP_ERR,      float,      formal error on average mag,           mags
+FIELD  sMap,          MAG_AP_STDEV,    float,      standard deviation of ap mags,         mags
 FIELD  Mkron,         MAG_KRON,        float,      ave kron mag in this band,             mags
 FIELD  dMkron,        MAG_KRON_ERR,    float,      formal error on average kron mag,      mags
-FIELD  dM,            MAG_ERR,         float,      formal error on average mag,           mags
-FIELD  Xm,            MAG_CHI,         float,      chisq on average mag,                  [100*log(value)]
-FIELD  FluxPSF,       FLUX_PSF,        float,      mean flux psf fit (PS1: stack)
-FIELD  dFluxPSF,      FLUX_PSF_ERR,    float,      mean flux psf error
-FIELD  FluxKron,      FLUX_KRON,       float,      mean flux kron ap (PS1: stack)
-FIELD  dFluxKron,     FLUX_KRON_ERR,   float,      mean flux kron err
+FIELD  sMkron,        MAG_KRON_STDEV,  float,      standard deviation of kron mags,       mags
+
+# XXX I could add these fields to secfilt or calculate in dvopsps?
+FIELD  psfQfMax,      PSF_QF_MAX,      float,      best psfQf for this filter
+FIELD  psfQfPerfMax,  PSF_QF_PERF_MAX, float,      best psfQfPerfect for this filter
+
+# these statistics are PSF-specific      
+FIELD  Mstdev,        MAG_STDEV,       float,      standard deviation of measurements,    mags
+FIELD  Mmin,          MAG_MIN,         float,      minimum accepted mag,                  mags
+FIELD  Mmax,          MAG_MAX,         float,      maximum accepted mag,                  mags
+FIELD  Mchisq,        MAG_CHI,         float,      chisq on average mag,                  value
+
+FIELD  Ncode,         NCODE,           short,      number of detections in band (gpc1 chip only)
+FIELD  Nused,         NUSED,           short,      number of detections used to calculate secfilt.M
+FIELD  NusedKron,     NUSED_KRON,      short,      number of detections used to calculate secfilt.Mkron
+FIELD  NusedAp,       NUSED_AP,        short,      number of detections used to calculate secfilt.Map
+
 FIELD  flags,         FLAGS,           uint32_t,   photometry flags
-FIELD  Ncode,         NCODE,           short,      number of detections in band
-FIELD  Nused,         NUSED,           short,      number of detections used in average
-FIELD  M_20,          MAG_20,          short,      lower 20percent mag,                   millimags
-FIELD  M_80,          MAG_80,          short,      upper 20percent mag,                   millimags
-FIELD  ubercalDist,   UBERCAL_DIST,    short,      number of images from an ubercal-image
-FIELD  Mstdev,        MAG_STDEV,       short,      standard deviation of measurements,    millimags
-FIELD  stackDetectID, STACK_DETECT_ID, uint64_t,   detection ID on stack used for fluxes (if any)
+
+## *** this section is for stack values ***
+
+FIELD  MpsfStk,       MAG_PSF_STK,       float,    magnitude from stack (primary if available)
+FIELD  FpsfStk,       FLUX_PSF_STK,      float,    flux from stack (primary if available)
+FIELD  dFpsfStk,      FLUX_PSF_STK_ERR,  float,    mean flux psf error
+
+FIELD  MkronStk,      MAG_KRON_STK,      float,    magnitude from stack (primary if available)
+FIELD  FkronStk,      FLUX_KRON_STK,     float,    flux from stack (primary if available)
+FIELD  dFkronStk,     FLUX_KRON_STK_ERR, float,    mean flux kron error
+
+FIELD  MapStk,        MAG_AP_STK,        float,    magnitude from stack (primary if available)
+FIELD  FapStk,        FLUX_AP_STK,       float,    flux from stack (primary if available)
+FIELD  dFapStk,       FLUX_AP_STK_ERR,   float,    mean flux ap error
+
+FIELD  Nstack,        NSTACK,            short,    number of measurements in band (gpc1 stack only)
+FIELD  NstackDet,     NSTACK_DET,        short,    number of stack detections in band (gpc1 stack only)
+
+FIELD  stackPrmryOff, STACK_PRIMARY_OFF, int,      measure entry which is primary stack detection
+FIELD  stackBestOff,  STACK_BEST_OFF,    int,      measure entry which is best stack detection
+
+## *** this section is for forced-warp mean values ***
+
+FIELD  MpsfWrp,       MAG_PSF_WRP,       float,    psf magnitude from stack (primary if available)
+FIELD  FpsfWrp,       FLUX_PSF_WRP,      float,    psf flux from stack (primary if available)
+FIELD  dFpsfWrp,      FLUX_PSF_WRP_ERR,  float,    mean flux psf error
+FIELD  sFpsfWrp,      FLUX_PSF_WRP_STD,  float,    mean flux psf stdev
+
+FIELD  MkronWrp,      MAG_KRON_WRP,      float,    kron magnitude from stack (primary if available)
+FIELD  FkronWrp,      FLUX_KRON_WRP,     float,    kron flux from stack (primary if available)
+FIELD  dFkronWrp,     FLUX_KRON_WRP_ERR, float,    mean flux kron error
+FIELD  sFkronWrp,     FLUX_KRON_WRP_STD, float,    mean flux kron stdev
+
+FIELD  MapWrp,        MAG_AP_WRP,        float,    aper magnitude from stack (primary if available)
+FIELD  FapWrp,        FLUX_AP_WRP,       float,    aper flux from stack (primary if available)
+FIELD  dFapWrp,       FLUX_AP_WRP_ERR,   float,    mean flux ap error
+FIELD  sFapWrp,       FLUX_AP_WRP_STD,   float,    mean flux ap stdev
+
+FIELD  NusedWrp,      NUSED_WRP,         short,    number of detections used in average
+FIELD  NusedKronWrp,  NUSED_KRON_WRP,    short,    number of detections used in average
+FIELD  NusedApWrp,    NUSED_AP_WRP,      short,    number of detections used in average
+
+FIELD  Nwarp,         NWARP,             short,    number of measurements in band (gpc1 warp only)
+FIELD  NwarpGood,     NWARP_GOOD,        short,    number of meas with psf_qf > 0.85 in band (gpc1 warp only)
+
+FIELD  ubercalDist,   UBERCAL_DIST,      short,    number of images from an ubercal-image
 
 # *** 20090206 : new fields : M_20, M_80; dropped dummy
 # *** 20120302 : new fields : ubercalDist, Map, Mstdev
 # *** 20120710 : new fields : Mkron, dMkron, FluxPSF, dFluxPSF, FluxKron, dFluxKron, stackID
+
+# *** 20140617 : added   : dMap, NusedKron, NusedAp, MpsfStk, MkronStk, MapStk, *Wrp
+      	       : changed : Mstdev, M_20 (to Mmin,short:float),M_80 (to Mmax,short:float),
+	       : rename : FpsfStk, dFpsfStk, FkronStk, dFronStk (were FluxPSF, dFluxPSF, FluxKron, dFluxKron)
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/doc/sizes.ps1-v5.txt
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/doc/sizes.ps1-v5.txt	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libautocode/doc/sizes.ps1-v5.txt	(revision 37403)
@@ -0,0 +1,13 @@
+
+Here are the expected totals for PV1_V5 (LAP PV2):
+
+Camera detections : 122G [measured from gpc1 database directly, removing factor of 2 error]
+Stack objects: 2.5G [measured from a random sample of skycells]
+Total objects: 5.0G [generous guess]
+
+average: 168 byte / object * 5G = 840G
+secfilt: 152 byte / object / photcode * 9 (grizywJHK) * 5G = 6840G
+measure: 232 byte / detect * 122G det [camera] = 28304G
+         232 byte / detect * 2.5G obj * 85 det [warp] = 49300G
+lensing: 128 byte / detect * 2.5G obj * 85 det [warp] = 27200G
+lensobj: 136 byte / object / photcode * 2.5G obj * 5 (grizy) = 1700G
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/Makefile
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/Makefile	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/Makefile	(revision 37403)
@@ -36,6 +36,10 @@
 $(DESTINC)/ps1_v3_defs.h \
 $(DESTINC)/ps1_v4_defs.h \
+$(DESTINC)/ps1_v5_defs.h \
 $(DESTINC)/ps1_ref_defs.h \
-$(DESTINC)/cmf-ps1-dv3.h
+$(DESTINC)/cmf-ps1-dv3.h \
+$(DESTINC)/cmf-ps1-v5.h \
+$(DESTINC)/cmf-ps1-sv3.h \
+$(DESTINC)/cmf-ps1-v5-lensing.h
 
 INCS = $(DEFS) $(DESTINC)/dvo.h $(DESTINC)/autocode.h $(DESTINC)/dvo_util.h $(DESTINC)/dvodb.h $(DESTINC)/libdvo_astro.h $(DESTINC)/convert.h $(DESTINC)/get_graphdata.h
@@ -76,4 +80,5 @@
 $(SRC)/dvo_convert_PS1_V3.$(ARCH).o \
 $(SRC)/dvo_convert_PS1_V4.$(ARCH).o \
+$(SRC)/dvo_convert_PS1_V5.$(ARCH).o \
 $(SRC)/dvo_convert_PS1_REF.$(ARCH).o \
 $(SRC)/flatcorr_io.$(ARCH).o    \
@@ -86,4 +91,7 @@
 $(SRC)/cmf-ps1-sv1-alt.$(ARCH).o \
 $(SRC)/cmf-ps1-dv3.$(ARCH).o \
+$(SRC)/cmf-ps1-sv3.$(ARCH).o \
+$(SRC)/cmf-ps1-v5.$(ARCH).o \
+$(SRC)/cmf-ps1-v5-lensing.$(ARCH).o \
 $(SRC)/dvo_util.$(ARCH).o \
 $(SRC)/dbBooleanCond.$(ARCH).o		\
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/doc/notes.ps1v5.txt
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/doc/notes.ps1v5.txt	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/doc/notes.ps1v5.txt	(revision 37403)
@@ -0,0 +1,27 @@
+
+changes to make:
+
+Average: add: Rstk, Dstk, dRstk,dDstk, Nlensing, Nlensobj, lensingOffset, lensobjOffset, refColor
+Measure: mod: dR,dD -> R,D (change Measure_*_ToInteral to pass Average)
+      	 add: dMap, FluxAp, dFluxAp, (X,Y)off(KH,DCR,GAL)
+SecFilt: add: dMap, NusedKron, NusedAp, MpsfStk, MkronStk, MapStk, *Wrp
+      	 mod: Mstdev, M_20 (to Mmin,short:float),M_80 (to Mmax,short:float),
+         mod: FpsfStk, dFpsfStk, FkronStk, dFronStk (were FluxPSF, dFluxPSF, FluxKron, dFluxKron)
+
+name changes:
+Measure:
+dR,dD -> R,D (done)
+SecFilt
+    out[i].FpsfStk       = in[i].FluxPSF;
+    out[i].dFpsfStk      = in[i].dFluxPSF;
+    out[i].FkronStk      = in[i].FluxKron;
+    out[i].dFkronStk     = in[i].dFluxKron;
+    out[i].Mmin          = in[i].M_20*0.001;      
+    out[i].Mmax          = in[i].M_80*0.001;      
+
+    out[i].FluxPSF     	 = in[i].FpsfStk;
+    out[i].dFluxPSF    	 = in[i].dFpsfStk;
+    out[i].FluxKron    	 = in[i].FkronStk;
+    out[i].dFluxKron   	 = in[i].dFkronStk;
+    out[i].M_20        	 = in[i].Mmin*1000.0;      
+    out[i].M_80        	 = in[i].Mmax*1000.0;      
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/cmf-ps1-sv3.h
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/cmf-ps1-sv3.h	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/cmf-ps1-sv3.h	(revision 37403)
@@ -0,0 +1,66 @@
+
+/** STRUCT DEFINITION **/
+typedef struct {
+  unsigned int     detID;                // detection ID                     
+  float            X;                    // x coord (pixels)
+  float            Y;                    // y coord (pixels)
+  float            dX;                   // x coord error (pixels)
+  float            dY;                   // y coord error (pixels)
+  float            posangle;             // Posangle at source (degrees)
+  float            pltscale;             // Plate Scale at source (arcsec/pixel)
+  float            M;                    // inst mags (mags)
+  float            dM;                   // inst mag error (mags)
+  float            Flux;                 // psf flux (counts)
+  float            dFlux;                // psf flux error (counts      )
+  float            Map;                  // standard aperture mag (mags)
+  float            MapRaw;               // raw aperture mag (mags)
+  float            apRadius;             // radius used for fit (pixels)
+  float            apFlux;               // aperture flux (counts)
+  float            apFluxErr;            // error on ap flux (counts)
+  int              apNpix;               // pixels used for aper
+  float            Mcalib;               // calibrated psf mag (mags)
+  float            dMcal;                // zero point scatter (mags)
+  float            Mpeak;                // peak flux as a mag (mags)
+  double           RA;                   // PSF RA coord (degrees)
+  double           DEC;                  // PSF DEC coord (degrees)
+  float            sky;                  // sky flux (cnts/sec)
+  float            dSky;                 // sky flux error (cnts/sec)
+  float            psfChisq;             // psf fit chisq
+  float            crNsigma;             // Nsigma deviations from PSF to CF
+  float            extNsigma;            // Nsigma deviations from PSF to EXT
+  float            fx;                   // psf fit major axis (pixels)
+  float            fy;                   // psf fit minor axis (pixels)
+  float            df;                   // ellipse angle (degrees)
+  float            k;                    // extra PSF parameter (unitless)
+  float            fwhmMaj;              // true fwhm of psf (pixels)
+  float            fwhmMin;              // true fwhm (minor) (pixels)
+  float            psfQF;                // quality factor
+  float            psfQFperf;            // quality factor perfect
+  int              psfNdof;              // psf degrees of freedom
+  int              psfNpix;              // psf number of pixels
+  float            Mxx;                  // second moment X (pixels^2)
+  float            Mxy;                  // second moment Y (pixels^2)
+  float            Myy;                  // second moment XY (pixels^2)
+  float            M3c;                  // third moment cos(t) (pixels^3)
+  float            M3s;                  // third moment sin(t) (pixels^3)
+  float            M4c;                  // fourth moment cos(t) (pixels^4)
+  float            M4s;                  // fourth moment sin(t) (pixels^4)
+  float            Mr1;                  // first radial moment (pixels)
+  float            Mrh;                  // half radial moment (pixels^1/2)
+  float            kronFlux;             // kron flux (counts)
+  float            kronFluxErr;          // kron flux error (counts)
+  float            kronInner;            // kron flux 1<R<2.5 (counts)
+  float            kronOuter;            // kron flux 2.5<R<4 (counts)
+  int              flags;                // analysis flags
+  int              flags2;               // analysis flags (2)
+  short            nFrames;              // images overlapping peak
+  short            padding;              // padding for 8byte records
+  int              padding2;             // padding for 8byte records
+} CMF_PS1_SV3;
+
+CMF_PS1_SV3 *gfits_table_get_CMF_PS1_SV3 (FTable *table, off_t *Ndata, char *swapped);
+int      gfits_table_set_CMF_PS1_SV3 (FTable *ftable, CMF_PS1_SV3 *data, off_t Ndata);
+int      gfits_table_mkheader_CMF_PS1_SV3 (Header *header);
+unsigned char *gfits_convert_CMF_PS1_SV3 (unsigned char *data, off_t size, off_t nitems, char toStruct);
+int      Send_CMF_PS1_SV3 (int device, CMF_PS1_SV3 *data, int Ndata, int copy);
+int      Recv_CMF_PS1_SV3 (int device, CMF_PS1_SV3 **data, int *Ndata);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/cmf-ps1-v5-lensing.h
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/cmf-ps1-v5-lensing.h	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/cmf-ps1-v5-lensing.h	(revision 37403)
@@ -0,0 +1,93 @@
+
+/** STRUCT DEFINITION **/
+typedef struct {
+  unsigned int     detID;                // detection ID                     
+  float            X;                    // x coord (pixels)
+  float            Y;                    // y coord (pixels)
+  float            dX;                   // x coord error (pixels)
+  float            dY;                   // y coord error (pixels)
+  float            posangle;             // Posangle at source (degrees)
+  float            pltscale;             // Plate Scale at source (arcsec/pixel)
+  float            M;                    // inst mags (mags)
+  float            dM;                   // inst mag error (mags)
+  float            Flux;                 // psf flux (counts)
+  float            dFlux;                // psf flux error (counts      )
+  float            Map;                  // standard aperture mag (mags)
+  float            MapRaw;               // raw aperture mag (mags)
+  float            apRadius;             // radius used for aper (pixels)
+  float            apFlux;               // aperture flux (counts)
+  float            apFluxErr;            // error on ap flux (counts)
+  int              apNpix;               // pixels used by aper (pixels)
+  float            Mcalib;               // calibrated psf mag (mags)
+  float            dMcal;                // zero point scatter (mags)
+  float            Mpeak;                // peak flux as a mag (mags)
+  double           RA;                   // PSF RA coord (degrees)
+  double           DEC;                  // PSF DEC coord (degrees)
+  float            sky;                  // sky flux (cnts/sec)
+  float            dSky;                 // sky flux error (cnts/sec)
+  float            psfChisq;             // psf fit chisq
+  float            crNsigma;             // Nsigma deviations from PSF to CF
+  float            extNsigma;            // Nsigma deviations from PSF to EXT
+  float            fx;                   // psf fit major axis (pixels)
+  float            fy;                   // psf fit minor axis (pixels)
+  float            df;                   // ellipse angle (degrees)
+  float            k;                    // extra PSF parameter (unitless)
+  float            fwhmMaj;              // true fwhm of psf (pixels)
+  float            fwhmMin;              // true fwhm (minor) (pixels)
+  float            psfQF;                // quality factor
+  float            psfQFperf;            // quality factor perfect
+  int              psfNdof;              // psf degrees of freedom
+  int              psfNpix;              // psf number of pixels
+  float            Mxx;                  // second moment X (pixels^2)
+  float            Mxy;                  // second moment Y (pixels^2)
+  float            Myy;                  // second moment XY (pixels^2)
+  float            M3c;                  // third moment cos(t) (pixels^3)
+  float            M3s;                  // third moment sin(t) (pixels^3)
+  float            M4c;                  // fourth moment cos(t) (pixels^4)
+  float            M4s;                  // fourth moment sin(t) (pixels^4)
+
+  float            X11_sm_obj;           // lensing smear
+  float            X12_sm_obj;           // lensing smear
+  float            X22_sm_obj;           // lensing smear
+  float            E1_sm_obj;            // lensing smear
+  float            E2_sm_obj;            // lensing smear
+
+  float            X11_sh_obj;           // lensing shear
+  float            X12_sh_obj;           // lensing shear
+  float            X22_sh_obj;           // lensing shear
+  float            E1_sh_obj;            // lensing shear
+  float            E2_sh_obj;            // lensing shear
+
+  float            X11_sm_psf;           // lensing smear
+  float            X12_sm_psf;           // lensing smear
+  float            X22_sm_psf;           // lensing smear
+  float            E1_sm_psf;            // lensing smear
+  float            E2_sm_psf;            // lensing smear
+
+  float            X11_sh_psf;           // lensing shear
+  float            X12_sh_psf;           // lensing shear
+  float            X22_sh_psf;           // lensing shear
+  float            E1_sh_psf;            // lensing shear
+  float            E2_sh_psf;            // lensing shear
+
+  float            Mr1;                  // first radial moment (pixels)
+  float            Mrh;                  // half radial moment (pixels^1/2)
+  float            kronFlux;             // kron flux (counts)
+  float            kronFluxErr;          // kron flux error (counts)
+  float            kronInner;            // kron flux 1<R<2.5 (counts)
+  float            kronOuter;            // kron flux 2.5<R<4 (counts)
+  float            skyLimitRad;          // profile to sky limit (radius)
+  float            skyLimitFlux;         // profile to sky limit (flux)
+  float            skyLimitSlope;        // profile to sky limit (slope)
+  int              flags;                // analysis flags
+  int              flags2;               // analysis flags (2)
+  short            nFrames;              // images overlapping peak
+  short            padding;              // padding for 8byte records
+} CMF_PS1_V5_Lensing;
+
+CMF_PS1_V5_Lensing *gfits_table_get_CMF_PS1_V5_Lensing (FTable *table, off_t *Ndata, char *swapped);
+int      gfits_table_set_CMF_PS1_V5_Lensing (FTable *ftable, CMF_PS1_V5_Lensing *data, off_t Ndata);
+int      gfits_table_mkheader_CMF_PS1_V5_Lensing (Header *header);
+int      gfits_convert_CMF_PS1_V5_Lensing (unsigned char *data, off_t size, off_t nitems, char toStruct);
+int      Send_CMF_PS1_V5_Lensing (int device, CMF_PS1_V5_Lensing *data, int Ndata, int copy);
+int      Recv_CMF_PS1_V5_Lensing (int device, CMF_PS1_V5_Lensing **data, int *Ndata);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/cmf-ps1-v5.h
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/cmf-ps1-v5.h	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/cmf-ps1-v5.h	(revision 37403)
@@ -0,0 +1,68 @@
+
+/** STRUCT DEFINITION **/
+typedef struct {
+  unsigned int     detID;                // detection ID                     
+  float            X;                    // x coord (pixels)
+  float            Y;                    // y coord (pixels)
+  float            dX;                   // x coord error (pixels)
+  float            dY;                   // y coord error (pixels)
+  float            posangle;             // Posangle at source (degrees)
+  float            pltscale;             // Plate Scale at source (arcsec/pixel)
+  float            M;                    // inst mags (mags)
+  float            dM;                   // inst mag error (mags)
+  float            Flux;                 // psf flux (counts)
+  float            dFlux;                // psf flux error (counts      )
+  float            Map;                  // standard aperture mag (mags)
+  float            MapRaw;               // raw aperture mag (mags)
+  float            apRadius;             // radius used for aper (pixels)
+  float            apFlux;               // aperture flux (counts)
+  float            apFluxErr;            // error on ap flux (counts)
+  int              apNpix;               // pixels used by aper (pixels)
+  float            Mcalib;               // calibrated psf mag (mags)
+  float            dMcal;                // zero point scatter (mags)
+  float            Mpeak;                // peak flux as a mag (mags)
+  double           RA;                   // PSF RA coord (degrees)
+  double           DEC;                  // PSF DEC coord (degrees)
+  float            sky;                  // sky flux (cnts/sec)
+  float            dSky;                 // sky flux error (cnts/sec)
+  float            psfChisq;             // psf fit chisq
+  float            crNsigma;             // Nsigma deviations from PSF to CF
+  float            extNsigma;            // Nsigma deviations from PSF to EXT
+  float            fx;                   // psf fit major axis (pixels)
+  float            fy;                   // psf fit minor axis (pixels)
+  float            df;                   // ellipse angle (degrees)
+  float            k;                    // extra PSF parameter (unitless)
+  float            fwhmMaj;              // true fwhm of psf (pixels)
+  float            fwhmMin;              // true fwhm (minor) (pixels)
+  float            psfQF;                // quality factor
+  float            psfQFperf;            // quality factor perfect
+  int              psfNdof;              // psf degrees of freedom
+  int              psfNpix;              // psf number of pixels
+  float            Mxx;                  // second moment X (pixels^2)
+  float            Mxy;                  // second moment Y (pixels^2)
+  float            Myy;                  // second moment XY (pixels^2)
+  float            M3c;                  // third moment cos(t) (pixels^3)
+  float            M3s;                  // third moment sin(t) (pixels^3)
+  float            M4c;                  // fourth moment cos(t) (pixels^4)
+  float            M4s;                  // fourth moment sin(t) (pixels^4)
+  float            Mr1;                  // first radial moment (pixels)
+  float            Mrh;                  // half radial moment (pixels^1/2)
+  float            kronFlux;             // kron flux (counts)
+  float            kronFluxErr;          // kron flux error (counts)
+  float            kronInner;            // kron flux 1<R<2.5 (counts)
+  float            kronOuter;            // kron flux 2.5<R<4 (counts)
+  float            skyLimitRad;          // profile to sky limit (radius)
+  float            skyLimitFlux;         // profile to sky limit (flux)
+  float            skyLimitSlope;        // profile to sky limit (slope)
+  int              flags;                // analysis flags
+  int              flags2;               // analysis flags (2)
+  short            nFrames;              // images overlapping peak
+  short            padding;              // padding for 8byte records
+} CMF_PS1_V5;
+
+CMF_PS1_V5 *gfits_table_get_CMF_PS1_V5 (FTable *table, off_t *Ndata, char *swapped);
+int      gfits_table_set_CMF_PS1_V5 (FTable *ftable, CMF_PS1_V5 *data, off_t Ndata);
+int      gfits_table_mkheader_CMF_PS1_V5 (Header *header);
+int      gfits_convert_CMF_PS1_V5 (unsigned char *data, off_t size, off_t nitems, char toStruct);
+int      Send_CMF_PS1_V5 (int device, CMF_PS1_V5 *data, int Ndata, int copy);
+int      Recv_CMF_PS1_V5 (int device, CMF_PS1_V5 **data, int *Ndata);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/dvo.h
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/dvo.h	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/dvo.h	(revision 37403)
@@ -28,4 +28,5 @@
   DVO_FORMAT_PS1_V3,
   DVO_FORMAT_PS1_V4,
+  DVO_FORMAT_PS1_V5,
 } DVOTableFormat;
 
@@ -78,15 +79,17 @@
 
 /* catalog values to be loaded */
-# define LOAD_NONE 	0x00
-# define LOAD_AVES 	0x01
-# define LOAD_MEAS 	0x02
-# define LOAD_MISS 	0x04
-# define LOAD_SECF 	0x08 
-# define SKIP_AVES 	0x10
-# define SKIP_MEAS 	0x20
-# define SKIP_MISS 	0x40
-# define SKIP_SECF 	0x80
-
-// # define LOAD_MEAS_META 0x100 -- is this used??
+# define LOAD_NONE 	0x000
+# define LOAD_AVES 	0x001
+# define LOAD_MEAS 	0x002
+# define LOAD_MISS 	0x004
+# define LOAD_SECF 	0x008 
+# define SKIP_AVES 	0x010
+# define SKIP_MEAS 	0x020
+# define SKIP_MISS 	0x040
+# define SKIP_SECF 	0x080
+# define LOAD_LENSING 	0x100
+# define LOAD_LENSOBJ 	0x200
+# define SKIP_LENSING 	0x400
+# define SKIP_LENSOBJ 	0x800
 
 /* photometry code types */
@@ -125,5 +128,5 @@
   ID_MEAS_BLEND_MEAS     = 0x00000100,  // detection is within radius of multiple objects 
   ID_MEAS_BLEND_OBJ      = 0x00000200,  // multiple detections within radius of object 
-  ID_MEAS_UNDEF_3        = 0x00000400,  // unused 
+  ID_MEAS_WARP_USED      = 0x00000400,  // measurement used to find mean warp photometry
   ID_MEAS_UNDEF_4        = 0x00000800,  // unused 
   ID_MEAS_BLEND_MEAS_X   = 0x00001000,  // detection is within radius of multiple objects across catalogs		     
@@ -171,4 +174,5 @@
   ID_STAR_USE_PAR   = 0x00200000, // parallax used (not AVE or PM)
   ID_STAR_NO_ASTROM = 0x00400000, // mean astrometry could not be measured
+  ID_STAR_BAD_PM    = 0x00800000, // mean astrometry could not be measured
   ID_OBJ_EXT        = 0x01000000, // extended in our data (eg, PS)
   ID_OBJ_EXT_ALT    = 0x02000000, // extended in external data (eg, 2MASS)
@@ -333,4 +337,7 @@
 // another special case : does not match byte-boundaries
 # include "cmf-ps1-dv3.h"
+# include "cmf-ps1-sv3.h"
+# include "cmf-ps1-v5.h"
+# include "cmf-ps1-v5-lensing.h"
 
 typedef struct {
@@ -376,12 +383,12 @@
   char  ***name; // projection cell name
   
-  int NX_SUB;
-  int NY_SUB;
+  float NX_SUB;
+  float NY_SUB;
   double dPix;
 
   double **Xo;
   double **Yo;
-  int **dX;
-  int **dY;
+  float **dX;
+  float **dY;
 } BoundaryTree;
 
@@ -404,9 +411,9 @@
   double Do;
   double dPix;
-  int dX;
-  int dY;
-
-  int NX_SUB;
-  int NY_SUB;
+  float dX;
+  float dY;
+
+  float NX_SUB;
+  float NY_SUB;
 
   char *basename;
@@ -433,6 +440,6 @@
 // a reduced-subset structure for relphot & relastro
 typedef struct {
-  float          dR;
-  float          dD;
+  double         R;
+  double         D;
   float          M;
   float          Mcal;
@@ -457,5 +464,5 @@
 } MeasureTiny;
 
-/** STRUCT DEFINITION **/
+// alternate version of PS1_V4 (old dev version)
 typedef struct {
   double           R;                    // RA (decimal degrees )
@@ -481,5 +488,5 @@
   uint32_t         measureOffset;        // offset to first psf measurement
   uint32_t         missingOffset;        // offset to first missing obs
-  uint32_t         extendOffset;         // offset to first extended measurement
+  float            refColor;            // offset to first extended measurement
   uint32_t         flags;                // average object flags (star; ghost; etc)
   uint32_t         photFlagsUpper;       // upper bit of 2 bit summary of per-measure photflags
@@ -493,5 +500,5 @@
 Average *Average_PS1_V4alt_ToInternal (Average_PS1_V4alt *in, off_t Nvalues);
 
-/** STRUCT DEFINITION **/
+// alternate version of PS1_V4 (old dev version)
 typedef struct {
   float            dR;                   // RA offset (arcsec)
@@ -547,5 +554,111 @@
 
 Measure_PS1_V4alt *gfits_table_get_Measure_PS1_V4alt (FTable *table, off_t *Ndata, char *swapped);
-Measure *Measure_PS1_V4alt_ToInternal (Measure_PS1_V4alt *in, off_t Nvalues);
+Measure *Measure_PS1_V4alt_ToInternal (Average *ave, Measure_PS1_V4alt *in, off_t Nvalues);
+
+// alternate version of PS1_V5 (old dev version)
+typedef struct {
+  float            M;                    // average mag in this band (mags)
+  float            dM;                   // formal error on average mag (mags)
+  float            Map;                  // ave aperture mag in this band (mags)
+  float            dMap;                 // ave aperture mag in this band (mags)
+  float            sMap;                 // standard deviation of ap mags (mags)
+  float            Mkron;                // ave kron mag in this band (mags)
+  float            dMkron;               // formal error on average kron mag (mags)
+  float            sMkron;               // standard deviation of kron mags (mags)
+  float            Mstdev;               // standard deviation of measurements (mags)
+  float            Mmin;                 // min accepted mag (mags)
+  float            Mmax;                 // max accepted mag (mags)
+  float            Mchisq;               // chisq on average mag (value)
+  short            Ncode;                // number of detections in band
+  short            Nused;                // number of detections used in average
+  short            NusedKron;            // number of detections used in average
+  short            NusedAp;              // number of detections used in average
+  uint32_t         flags;                // photometry flags
+  float            MpsfStk;              // magnitude from stack (primary if available)
+  float            FpsfStk;              // flux from stack (primary if available)
+  float            dFpsfStk;             // mean flux psf error
+  float            MkronStk;             // magnitude from stack (primary if available)
+  float            FkronStk;             // flux from stack (primary if available)
+  float            dFkronStk;            // mean flux kron error
+  float            MapStk;               // magnitude from stack (primary if available)
+  float            FapStk;               // flux from stack (primary if available)
+  float            dFapStk;              // mean flux ap error
+  int              stackPrmryOff;        // measure entry which is primary stack detection
+  int              stackBestOff;         // measure entry which is best stack detection
+  float            MpsfWrp;              // psf magnitude from stack (primary if available)
+  float            FpsfWrp;              // psf flux from stack (primary if available)
+  float            dFpsfWrp;             // mean flux psf error
+  float            sFpsfWrp;             // mean flux psf stdev
+  float            MkronWrp;             // kron magnitude from stack (primary if available)
+  float            FkronWrp;             // kron flux from stack (primary if available)
+  float            dFkronWrp;            // mean flux kron error
+  float            sFkronWrp;            // mean flux kron stdev
+  float            MapWrp;               // aper magnitude from stack (primary if available)
+  float            FapWrp;               // aper flux from stack (primary if available)
+  float            dFapWrp;              // mean flux ap error
+  float            sFapWrp;              // mean flux ap stdev
+  short            NusedWrp;             // number of detections used in average
+  short            NusedKronWrp;         // number of detections used in average
+  short            NusedApWrp;           // number of detections used in average
+  short            ubercalDist;          // number of images from an ubercal-image
+} SecFilt_PS1_V5alt;
+
+SecFilt_PS1_V5alt *gfits_table_get_SecFilt_PS1_V5alt (FTable *table, off_t *Ndata, char *swapped);
+int      gfits_convert_SecFilt_PS1_V5alt (SecFilt_PS1_V5alt *data, off_t size, off_t nitems);
+SecFilt *SecFilt_PS1_V5alt_ToInternal (SecFilt_PS1_V5alt *in, off_t Nvalues);
+
+// alternate version of PS1_V5alt (old dev version)
+typedef struct {
+  double           R;                    // RA (decimal degrees )
+  double           D;                    // DEC (decimal degrees )
+  float            dR;                   // RA error (arcsec)
+  float            dD;                   // DEC error (arcsec)
+  float            uR;                   // RA*cos(D) proper-motion (arcsec/year)
+  float            uD;                   // DEC proper-motion (arcsec/year)
+  float            duR;                  // RA*cos(D) p-m error (arcsec/year)
+  float            duD;                  // DEC p-m error (arcsec/year)
+  float            P;                    // parallax (arcsec)
+  float            dP;                   // parallax error (arcsec)
+  double           Rstk;                 // RA on stack (decimal degrees )
+  double           Dstk;                 // DEC on stack (decimal degrees )
+  float            dRstk;                // RA error on stack (arcsec)
+  float            dDstk;                // DEC error on stack (arcsec)
+  float            ChiSqAve;             // astrometry analysis chisq
+  float            ChiSqPM;              // astrometry analysis chisq
+  float            ChiSqPar;             // astrometry analysis chisq
+  int              Tmean;                // mean epoch (PM,PAR ref) (unix time seconds)
+  int              Trange;               // mean epoch (PM,PAR ref) (unix time seconds)
+  float            psfQF;                // psf coverage (bad masks)
+  float            psfQFperf;            // psf coverage (all masks)
+  float            stargal;              // star / galaxy separator (1/100 arcsec)
+  unsigned short   Npos;                 // number of detections used for astrometry
+  unsigned short   Nmeasure;             // number of psf measurements
+  unsigned short   Nmissing;             // number of missings
+  unsigned short   Nlensing;             // number of lensing measurements
+  unsigned short   Nlensobj;             // number of lensing measurements
+  unsigned short   Nextend;              // number of extended measurements
+  int              measureOffset;        // offset to first psf measurement
+  int              missingOffset;        // offset to first missing obs
+  int              lensingOffset;        // offset to first lensing obs
+  int              lensobjOffset;        // offset to mean lensing data
+  int              extendOffset;         // offset to extended object entry
+  int              paramsOffset;         // offset to stellar parameter data
+  float            refColorBlue;         // color of astrometry ref stars
+  float            refColorRed;          // color of astrometry ref stars
+  uint32_t         flags;                // average object flags (star; ghost; etc)
+  uint32_t         photFlagsUpper;       // upper bit of 2 bit summary of per-measure photflags
+  uint32_t         photFlagsLower;       // lower bit of 2 bit summary of per-measure photflags
+  unsigned int     objID;                // unique ID for object in table
+  unsigned int     catID;                // unique ID for table in which object was first realized
+  uint64_t         extID;                // external ID for object (eg PSPS objID)
+  uint64_t         extIDgc;              // external ID for object in galactic coords
+} Average_PS1_V5alt;
+
+Average_PS1_V5alt *gfits_table_get_Average_PS1_V5alt (FTable *table, off_t *Ndata, char *swapped);
+int      gfits_convert_Average_PS1_V5alt (Average_PS1_V5alt *data, off_t size, off_t nitems);
+Average *Average_PS1_V5alt_ToInternal (Average_PS1_V5alt *in, off_t Nvalues);
+
+/* for some reason I have merged the set of tables and the file description,
+   so I need to have an internal structure to point to the separate files */
 
 /* a catalog contains this data */
@@ -561,8 +674,12 @@
   SecFilt *secfilt;
 
+  // lensing data (optional?)
+  Lensing *lensing;
+  Lensobj *lensobj;
+
   int Nsecfilt;  /* number of secfilt entries for each average entry */
-  off_t Naverage,   Nmeasure,   Nmissing,   Nsecf_mem;  /* current number of each component in memory */
-  off_t Naves_disk, Nmeas_disk, Nmiss_disk, Nsecf_disk; /* current number of each component on disk */
-  off_t Naves_off,  Nmeas_off,  Nmiss_off,  Nsecf_off;  /* index of first loaded data value */
+  off_t Naverage,   Nmeasure,   Nmissing,   Nlensing,      Nlensobj,      Nsecf_mem;  /* current number of each component in memory */
+  off_t Naves_disk, Nmeas_disk, Nmiss_disk, Nlensing_disk, Nlensobj_disk, Nsecf_disk; /* current number of each component on disk */
+  off_t Naves_off,  Nmeas_off,  Nmiss_off,  Nlensing_off,  Nlensobj_off,  Nsecf_off;  /* index of first loaded data value */
 
   // note that we use these for the full-sky relphot analysis
@@ -583,4 +700,6 @@
   struct Catalog *missing_catalog;		/* missing catalog data (split) */
   struct Catalog *secfilt_catalog;		/* secfilt catalog data (split) */
+  struct Catalog *lensing_catalog;		/* lensing catalog data (split) */
+  struct Catalog *lensobj_catalog;		/* lensobj catalog data (split) */
 
   unsigned int objID;
@@ -591,14 +710,16 @@
   char catmode;				/* storage mode (raw, mef, split, mysql) */
   char catformat;			/* storage format (elixir, panstarrs, etc) */
-  char catflags;				/* choices to be loaded */
-  char sorted;				/* is measure table average-sorted? */
+  int sorted;				/* is measure table average-sorted? (NOTE this is an int only because gfits_scan %t requires it) */
   
+  short catflags; /* choices to be loaded */
+
   /* pointers for data manipulation */
-  off_t *found;
-  off_t *image;
-  off_t *mosaic;
-  float *X;
-  float *Y;
-  int   *nOwn; // relastro uses this to count owned detections per object
+  off_t *found_t;
+  off_t *foundWarp_t;
+//  off_t *image_t;
+//  off_t *mosaic_t;
+//  float *X_t;
+//  float *Y_t;
+  int   *nOwn_t; // relastro uses this to count owned detections per object
 
 } Catalog;
@@ -660,41 +781,45 @@
 char     *GetPhotcodeNamebyCode (int code);
 
-float PhotInst (Measure *measure);
-float PhotCat (Measure *measure);
-float PhotSys (Measure *measure, Average *average, SecFilt *secfilt);
-float PhotRel (Measure *measure, Average *average, SecFilt *secfilt);
-float PhotCal (Measure *thisone, Average *average, SecFilt *secfilt, Measure *measure, PhotCode *code);
-float PhotAve (PhotCode *code, Average *average, SecFilt *secfilt);
-float PhotRef (PhotCode *code, Average *average, SecFilt *secfilt, Measure *measure);
-float PhotAveErr (PhotCode *code, Average *average, SecFilt *secfilt);
-
-float PhotAperInst (Measure *measure);
-float PhotAperCat (Measure *measure);
-float PhotAperSys (Measure *measure, Average *average, SecFilt *secfilt);
-float PhotAperRel (Measure *measure, Average *average, SecFilt *secfilt);
-float PhotAperCal (Measure *thisone, Average *average, SecFilt *secfilt, Measure *measure, PhotCode *code);
-float PhotAperAve (PhotCode *code, Average *average, SecFilt *secfilt);
-float PhotAperRef (PhotCode *code, Average *average, SecFilt *secfilt, Measure *measure);
-
-float PhotKronInst (Measure *measure);
-float PhotKronCat (Measure *measure);
-float PhotKronSys (Measure *measure, Average *average, SecFilt *secfilt);
-float PhotKronRel (Measure *measure, Average *average, SecFilt *secfilt);
-float PhotKronCal (Measure *thisone, Average *average, SecFilt *secfilt, Measure *measure, PhotCode *code);
-float PhotKronAve (PhotCode *code, Average *average, SecFilt *secfilt);
-float PhotKronRef (PhotCode *code, Average *average, SecFilt *secfilt, Measure *measure);
-float PhotKronAveErr (PhotCode *code, Average *average, SecFilt *secfilt);
+float PhotInst (Measure *measure, dvoMagClassType class);
+float PhotCat (Measure *measure, dvoMagClassType class);
+float PhotSys (Measure *measure, Average *average, SecFilt *secfilt, dvoMagClassType class);
+float PhotRel (Measure *measure, Average *average, SecFilt *secfilt, dvoMagClassType class);
+float PhotCal (Measure *thisone, Average *average, SecFilt *secfilt, Measure *measure, PhotCode *code, dvoMagClassType class);
+float PhotErr (Measure *measure, dvoMagClassType class);
+float PhotCalErr (Measure *measure, dvoMagClassType class);
+
+float PhotAve (PhotCode *code, Average *average, SecFilt *secfilt, dvoMagClassType class, dvoMagSourceType source);
+float PhotRef (PhotCode *code, Average *average, SecFilt *secfilt, Measure *measure, dvoMagClassType class, dvoMagSourceType source);
+float PhotAveErr (PhotCode *code, Average *average, SecFilt *secfilt, dvoMagClassType class, dvoMagSourceType source);
+
+float PhotInstTiny (MeasureTiny *measure, dvoMagClassType class);
+float PhotCatTiny (MeasureTiny *measure, dvoMagClassType class);
+float PhotSysTiny (MeasureTiny *measure, AverageTiny *average, SecFilt *secfilt, dvoMagClassType class);
+float PhotRelTiny (MeasureTiny *measure, AverageTiny *average, SecFilt *secfilt, dvoMagClassType class);
+float PhotCalTiny (MeasureTiny *thisone, AverageTiny *average, SecFilt *secfilt, MeasureTiny *measure, PhotCode *code, dvoMagClassType class);
+
+float PhotAveTiny (PhotCode *code, AverageTiny *average, SecFilt *secfilt, dvoMagClassType class, dvoMagSourceType source);
+float PhotRefTiny (PhotCode *code, AverageTiny *average, SecFilt *secfilt, MeasureTiny *measure, dvoMagClassType class, dvoMagSourceType source);
+
+float PhotFluxInst (Measure *measure, dvoMagClassType class);
+float PhotFluxCat (Measure *measure, dvoMagClassType class);
+float PhotFluxSys (Measure *measure, Average *average, SecFilt *secfilt, dvoMagClassType class);
+float PhotFluxRel (Measure *measure, Average *average, SecFilt *secfilt, dvoMagClassType class);
+float PhotFluxCal (Measure *thisone, Average *average, SecFilt *secfilt, Measure *measure, PhotCode *code, dvoMagClassType class);
+
+float PhotFluxAve (PhotCode *code, Average *average, SecFilt *secfilt, dvoMagClassType class, dvoMagSourceType source);
+float PhotFluxRef (PhotCode *code, Average *average, SecFilt *secfilt, Measure *measure, dvoMagClassType class, dvoMagSourceType source);
+
+float PhotFluxInstErr (Measure *measure, dvoMagClassType class);
+float PhotFluxCatErr (Measure *measure, dvoMagClassType class);
+float PhotFluxAveErr (PhotCode *code, Average *average, SecFilt *secfilt, dvoMagClassType class, dvoMagSourceType source);
 
 float PhotXm (PhotCode *code, Average *average, SecFilt *secfilt);
-
 float PhotZeroPoint (Measure *measure, Average *average, SecFilt *secfilt);
-float PhotAveFluxPSF (PhotCode *code, Average *average, SecFilt *secfilt);
-float PhotAvedFluxPSF (PhotCode *code, Average *average, SecFilt *secfilt);
-float PhotAveFluxKron (PhotCode *code, Average *average, SecFilt *secfilt);
-float PhotAvedFluxKron (PhotCode *code, Average *average, SecFilt *secfilt);
-
-float PhotMstdev (PhotCode *code, Average *average, SecFilt *secfilt);
-float PhotM20 (PhotCode *code, Average *average, SecFilt *secfilt);
-float PhotM80 (PhotCode *code, Average *average, SecFilt *secfilt);
+
+int   PhotNphot (PhotCode *code, Average *average, SecFilt *secfilt, dvoMagClassType class, dvoMagSourceType source);
+float PhotMstdev (PhotCode *code, Average *average, SecFilt *secfilt, dvoMagClassType class, dvoMagSourceType source);
+float PhotMmin (PhotCode *code, Average *average, SecFilt *secfilt);
+float PhotMmax (PhotCode *code, Average *average, SecFilt *secfilt);
 float PhotUCdist (PhotCode *code, Average *average, SecFilt *secfilt);
 unsigned int PhotStackID (PhotCode *code, Average *average, SecFilt *secfilt);
@@ -703,12 +828,4 @@
 int PhotColor (Average *average, SecFilt *secfilt, Measure *measure, int c1, int c2, double *color);
 
-float PhotInstTiny (MeasureTiny *measure);
-float PhotCatTiny (MeasureTiny *measure);
-float PhotAperTiny (MeasureTiny *measure);
-float PhotSysTiny (MeasureTiny *measure, AverageTiny *average, SecFilt *secfilt);
-float PhotRelTiny (MeasureTiny *measure, AverageTiny *average, SecFilt *secfilt);
-float PhotCalTiny (MeasureTiny *thisone, AverageTiny *average, SecFilt *secfilt, MeasureTiny *measure, PhotCode *code);
-float PhotAveTiny (PhotCode *code, AverageTiny *average, SecFilt *secfilt);
-float PhotRefTiny (PhotCode *code, AverageTiny *average, SecFilt *secfilt, MeasureTiny *measure);
 float PhotXmTiny (PhotCode *code, AverageTiny *average, SecFilt *secfilt);
 float PhotdMTiny (PhotCode *code, AverageTiny *average, SecFilt *secfilt);
@@ -781,8 +898,8 @@
 /*** conversion functions / I/O conversions ***/
 Average *ReadRawAverage (FILE *f, off_t Naverage, char format, SecFilt **primary);
-Measure *ReadRawMeasure (FILE *f, off_t Nmeasure, char format);
+Measure *ReadRawMeasure (FILE *f, Average *average, off_t Nmeasure, char format);
 SecFilt *ReadRawSecFilt (FILE *f, off_t Nsecfilt, char format);
 int WriteRawAverage (FILE *f, Average *average, off_t Naverage, char format, SecFilt *primary);
-int WriteRawMeasure (FILE *f, Measure *measure, off_t Nmeasure, char format);
+int WriteRawMeasure (FILE *f, Average *average, Measure *measure, off_t Nmeasure, char format);
 int WriteRawSecFilt (FILE *f, SecFilt *secfilt, off_t Nsecfilt, char format);
 
@@ -790,11 +907,15 @@
 
 Average *FtableToAverage (FTable *ftable, off_t *Naverage, char *format, SecFilt **primary);
-Measure *FtableToMeasure (FTable *ftable, off_t *Nmeasure, char *format);
+Measure *FtableToMeasure (FTable *ftable, Average *average, off_t *Nmeasure, char *format);
 SecFilt *FtableToSecFilt (FTable *ftable, off_t *Nsecfilt, char *format);
+Lensing *FtableToLensing (FTable *ftable, off_t *Nlensing, char *format);
+Lensobj *FtableToLensobj (FTable *ftable, off_t *Nlensobj, char *format);
 int      FtableToImage   (FTable *ftable, Header *theader, char *format);
 
 int AverageToFtable (FTable *ftable, Average *average, off_t Naverage, char format, SecFilt *primary);
-int MeasureToFtable (FTable *ftable, Measure *measure, off_t Nmeasure, char format);
+int MeasureToFtable (FTable *ftable, Average *average, Measure *measure, off_t Nmeasure, char format);
 int SecFiltToFtable (FTable *ftable, SecFilt *secfilt, off_t Nsecfilt, char format);
+int LensingToFtable (FTable *ftable, Lensing *lensing, off_t Nlensing, char format);
+int LensobjToFtable (FTable *ftable, Lensobj *lensobj, off_t Nlensobj, char format);
 int ImageToFtable (FTable *ftable, Header *theader, char format);
 int ImageToVtable (VTable *vtable, Header *theader, char format);
@@ -811,4 +932,5 @@
 # include "ps1_v3_defs.h"
 # include "ps1_v4_defs.h"
+# include "ps1_v5_defs.h"
 # include "ps1_ref_defs.h"
 
@@ -905,4 +1027,9 @@
 void TessellationTableInit (TessellationTable *tess, int Ntess);
 
+float dvoOffsetR (Measure *measure, Average *average);
+float dvoOffsetD (Measure *measure, Average *average);
+double dvoMeanR (float dR, Average *average);
+double dvoMeanD (float dD, Average *average);
+
 void dvo_average_init (Average *average);
 void dvo_averageT_init (AverageTiny *average);
@@ -910,4 +1037,7 @@
 void dvo_measure_init (Measure *measure);
 void dvo_measureT_init (MeasureTiny *measure);
+
+void dvo_lensing_init (Lensing *lensing);
+void dvo_lensobj_init (Lensobj *lensobj, int toZero);
 
 void InitRegionHosts (RegionHostInfo *hosts, int Nhosts, int NHOSTS);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/dvodb.h
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/dvodb.h	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/dvodb.h	(revision 37403)
@@ -22,62 +22,48 @@
 
 /* magnitude types */
-enum {MAG_NONE, 
-
-      // these magnitude types are from the measurement table (or derived therein)
-      // the following imply PSF magnitudes:
-      MAG_INST, // -2.5*log(DN) [ie, not DN/sec]
-      MAG_CAT,  // MAG_INST + 2.5*log(exptime) + C_lambda + K_lambda*(airmass - 1)
-      MAG_SYS,  // MAG_CAT + \sum_i A_i * (color_i - color_o) [color correction for measure photcode]
-      MAG_REL,  // MAG_SYS - Mcal [specific zero point for image]
-      MAG_CAL,  // MAG_REL + \sum_i A_i * (color_i - color_o) [color correction for average photcode]
-      MAG_ERR,  // error on PSF MAG
-
-      // the following imply APERTURE magnitudes:
-      MAG_APER_INST, // -2.5*log(DN) [ie, not DN/sec]
-      MAG_APER_CAT,  // MAG_APER_INST + 2.5*log(exptime) + C_lambda + K_lambda*(airmass - 1)
-      MAG_APER_SYS,  // MAG_APER_CAT + \sum_i A_i * (color_i - color_o) [color correction for measure photcode]
-      MAG_APER_REL,  // MAG_APER_SYS - Mcal [specific zero point for image]
-      MAG_APER_CAL,  // MAG_APER_REL + \sum_i A_i * (color_i - color_o) [color correction for average photcode]
-      MAG_APER_ERR,  // error on APER MAG (if known, else psf error)
-      MAG_APER,      // in mextract -> MAG_APER_REL, in avextract -> MAG_APER_AVE
-
-      // the following imply KRON magnitudes:
-      MAG_KRON_INST, // -2.5*log(DN) [ie, not DN/sec]
-      MAG_KRON_CAT,  // MAG_KRON_INST + 2.5*log(exptime) + C_lambda + K_lambda*(airmass - 1)
-      MAG_KRON_SYS,  // MAG_KRON_CAT + \sum_i A_i * (color_i - color_o) [color correction for measure photcode]
-      MAG_KRON_REL,  // MAG_KRON_SYS - Mcal [specific zero point for image]
-      MAG_KRON_CAL,  // MAG_KRON_REL + \sum_i A_i * (color_i - color_o) [color correction for average photcode]
-      MAG_KRON_ERR,  // error on KRON MAG
-      MAG_KRON,      // in mextract -> MAG_KRON_REL, in avextract -> MAG_KRON_AVE
-
-      // these magnitude types are from the average (secfilt) table:
-      // the following imply PSF magnitudes (or fluxes)
-      MAG_AVE, 
-      MAG_REF, 
-      MAG_STDEV, 
-      MAG_AVE_ERR, 
-      MAG_CHISQ,
-      MAG_20, 
-      MAG_80, 
-      MAG_FLUX_PSF,
-      MAG_FLUX_PSF_ERR,
-
-      // the following imply APERTURE magnitudes:
-      MAG_APER_AVE,
-      MAG_APER_REF,
-
-      // the following imply KRON magnitudes or fluxes:
-      MAG_KRON_AVE,
-      MAG_KRON_REF,
-      MAG_FLUX_KRON,
-      MAG_FLUX_KRON_ERR,
-
-      // other secfilt fields of interest
-      MAG_PHOT_FLAGS, 
-      MAG_NCODE,
-      MAG_NPHOT,
-      MAG_UC_DIST, 
-      MAG_STACK_DET_ID, 
-};
+
+typedef enum {
+  MAG_SRC_NONE,
+  MAG_SRC_CHP,
+  MAG_SRC_WRP,
+  MAG_SRC_STK,
+} dvoMagSourceType;
+
+typedef enum {
+  MAG_LEVEL_NONE,	// -2.5*log(DN) [ie, not DN/sec]
+  MAG_LEVEL_INST,		// -2.5*log(DN) [ie, not DN/sec]
+  MAG_LEVEL_CAT,		// MAG_INST + 2.5*log(exptime) + C_lambda + K_lambda*(airmass - 1)
+  MAG_LEVEL_SYS, // MAG_CAT + \sum_i A_i * (color_i - color_o) [color correction for measure photcode]
+  MAG_LEVEL_REL, // MAG_SYS - Mcal [specific zero point for image]
+  MAG_LEVEL_CAL, // MAG_REL + \sum_i A_i * (color_i - color_o) [color correction for average photcode]
+  MAG_LEVEL_AVE, 
+  MAG_LEVEL_REF, 
+} dvoMagLevelType;
+
+typedef enum {
+  MAG_OPTION_NONE,
+  MAG_OPTION_MAG,
+  MAG_OPTION_ERR,
+  MAG_OPTION_FLUX,
+  MAG_OPTION_FLUX_ERR,
+  MAG_OPTION_STDEV,
+  MAG_OPTION_CHISQ,
+  MAG_OPTION_MIN,
+  MAG_OPTION_MAX,
+  MAG_OPTION_NCODE,
+  MAG_OPTION_NPHOT, // Nused
+  MAG_OPTION_UC_DIST, 
+  MAG_OPTION_FLAGS, 
+} dvoMagOptionType;
+
+//  MAG_OPTION_STACK_PRIMARY_OFF, 
+//  MAG_OPTION_STACK_BEST_OFF, 
+
+typedef enum {
+  MAG_CLASS_NONE,
+  MAG_CLASS_PSF,
+  MAG_CLASS_KRON,
+  MAG_CLASS_APER,
+} dvoMagClassType;
 
 /* measure fields */
@@ -119,5 +105,5 @@
       MEAS_OBJ_FLAGS, 
       MEAS_SECFILT_FLAGS, 
-      MEAS_MAG, 
+      MEAS_PHOT, // photometry class of measurements
       MEAS_MINST, 
       MEAS_MCAT, 
@@ -173,11 +159,8 @@
       MEAS_EXTERN_ID,
       MEAS_EXPNAME_AS_INT,
-      MEAS_MCAL_OFFSET,
+      MEAS_MCAL_OFFSET, // make this a dvoMagOption?
       MEAS_FLAT,
       MEAS_CENTER_OFFSET,
-      MEAS_FLUX_PSF,
-      MEAS_FLUX_PSF_ERR,
-      MEAS_FLUX_KRON,
-      MEAS_FLUX_KRON_ERR,
+      MEAS_REF_COLOR,
 };
 
@@ -210,9 +193,4 @@
       AVE_NMISS, 
       AVE_NPOS, 
-      AVE_NPHOT, 
-      AVE_NCODE, 
-      AVE_MAG, 
-      AVE_dMAG, 
-      AVE_Xm, 
       AVE_OBJ_FLAGS, 
       AVE_TYPE, 
@@ -222,5 +200,13 @@
       AVE_EXTID_HI,
       AVE_EXTID_LO,
+      AVE_REF_COLOR,
+      AVE_PHOT, // photometry class of values
 };
+
+//       AVE_NPHOT, 
+//       AVE_NCODE, 
+//       AVE_MAG, 
+//       AVE_dMAG, 
+//       AVE_Xm, 
 
 enum {IMAGE_ZERO, 
@@ -289,5 +275,6 @@
       IMAGE_NFIT_ASTROM,
       IMAGE_NLINK_PHOTOM,
-      IMAGE_NLINK_ASTROM
+      IMAGE_NLINK_ASTROM,
+      IMAGE_REF_COLOR
 };
 
@@ -309,5 +296,10 @@
   int table;
   int ID;
-  int magMode;
+
+  dvoMagSourceType magSource; // chip, (forced) warp, stack [only relevant for averages]
+  dvoMagLevelType magLevel;  // inst, cat, sys, rel, ave, ref, err, min, max, stdev, nphot, chisq, 
+  dvoMagOptionType magOption;  // psf, kron, aper
+  dvoMagClassType magClass;
+
   char type;
   PhotCode *photcode;
@@ -371,5 +363,5 @@
 
 int          GetMagMode             PROTO((char *string));
-PhotCode    *ParsePhotcodeField     PROTO((char *field, int *mode, int def));
+int          ParsePhotcodeField     PROTO((dbField *field, char *fieldName, int fieldID));
 int          ParseMeasureField      PROTO((dbField *field, char *fieldName));
 int          ParseAverageField      PROTO((dbField *field, char *fieldName));
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/elixir_defs.h
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/elixir_defs.h	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/elixir_defs.h	(revision 37403)
@@ -3,6 +3,6 @@
 Average 	       	*Average_Elixir_ToInternal (Average_Elixir *in, off_t Nvalues, SecFilt **primary);
 Average_Elixir 	        *AverageInternalTo_Elixir (Average *in, off_t Nvalues, SecFilt *primary);
-Measure 	       	*Measure_Elixir_ToInternal (Measure_Elixir *in, off_t Nvalues);
-Measure_Elixir 	        *MeasureInternalTo_Elixir (Measure *in, off_t Nvalues);
+Measure 	       	*Measure_Elixir_ToInternal (Average *ave, Measure_Elixir *in, off_t Nvalues);
+Measure_Elixir 	        *MeasureInternalTo_Elixir (Average *ave, Measure *in, off_t Nvalues);
 SecFilt 	       	*SecFilt_Elixir_ToInternal (SecFilt_Elixir *in, off_t Nvalues);
 SecFilt_Elixir 	       	*SecFiltInternalTo_Elixir (SecFilt *in, off_t Nvalues);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/loneos_defs.h
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/loneos_defs.h	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/loneos_defs.h	(revision 37403)
@@ -3,6 +3,6 @@
 Average                	*Average_Loneos_ToInternal (Average_Loneos *in, off_t Nvalues, SecFilt **primary);
 Average_Loneos 	        *AverageInternalTo_Loneos (Average *in, off_t Nvalues, SecFilt *primary);
-Measure                	*Measure_Loneos_ToInternal (Measure_Loneos *in, off_t Nvalues);
-Measure_Loneos 	        *MeasureInternalTo_Loneos (Measure *in, off_t Nvalues);
+Measure                	*Measure_Loneos_ToInternal (Average *ave, Measure_Loneos *in, off_t Nvalues);
+Measure_Loneos 	        *MeasureInternalTo_Loneos (Average *ave, Measure *in, off_t Nvalues);
 SecFilt 	       	*SecFilt_Loneos_ToInternal (SecFilt_Loneos *in, off_t Nvalues);
 SecFilt_Loneos 	       	*SecFiltInternalTo_Loneos (SecFilt *in, off_t Nvalues);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/panstarrs_dev_0_defs.h
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/panstarrs_dev_0_defs.h	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/panstarrs_dev_0_defs.h	(revision 37403)
@@ -3,6 +3,6 @@
 Average 	       	*Average_Panstarrs_DEV_0_ToInternal (Average_Panstarrs_DEV_0 *in, off_t Nvalues, SecFilt **primary);
 Average_Panstarrs_DEV_0 *AverageInternalTo_Panstarrs_DEV_0 (Average *in, off_t Nvalues, SecFilt *primary);
-Measure 	       	*Measure_Panstarrs_DEV_0_ToInternal (Measure_Panstarrs_DEV_0 *in, off_t Nvalues);
-Measure_Panstarrs_DEV_0 *MeasureInternalTo_Panstarrs_DEV_0 (Measure *in, off_t Nvalues);
+Measure 	       	*Measure_Panstarrs_DEV_0_ToInternal (Average *ave, Measure_Panstarrs_DEV_0 *in, off_t Nvalues);
+Measure_Panstarrs_DEV_0 *MeasureInternalTo_Panstarrs_DEV_0 (Average *ave, Measure *in, off_t Nvalues);
 SecFilt 	       	*SecFilt_Panstarrs_DEV_0_ToInternal (SecFilt_Panstarrs_DEV_0 *in, off_t Nvalues);
 SecFilt_Panstarrs_DEV_0 *SecFiltInternalTo_Panstarrs_DEV_0 (SecFilt *in, off_t Nvalues);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/panstarrs_dev_1_defs.h
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/panstarrs_dev_1_defs.h	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/panstarrs_dev_1_defs.h	(revision 37403)
@@ -3,6 +3,6 @@
 Average 	       	*Average_Panstarrs_DEV_1_ToInternal (Average_Panstarrs_DEV_1 *in, off_t Nvalues, SecFilt **primary);
 Average_Panstarrs_DEV_1 *AverageInternalTo_Panstarrs_DEV_1 (Average *in, off_t Nvalues, SecFilt *primary);
-Measure 	       	*Measure_Panstarrs_DEV_1_ToInternal (Measure_Panstarrs_DEV_1 *in, off_t Nvalues);
-Measure_Panstarrs_DEV_1 *MeasureInternalTo_Panstarrs_DEV_1 (Measure *in, off_t Nvalues);
+Measure 	       	*Measure_Panstarrs_DEV_1_ToInternal (Average *ave, Measure_Panstarrs_DEV_1 *in, off_t Nvalues);
+Measure_Panstarrs_DEV_1 *MeasureInternalTo_Panstarrs_DEV_1 (Average *ave, Measure *in, off_t Nvalues);
 SecFilt 	       	*SecFilt_Panstarrs_DEV_1_ToInternal (SecFilt_Panstarrs_DEV_1 *in, off_t Nvalues);
 SecFilt_Panstarrs_DEV_1 *SecFiltInternalTo_Panstarrs_DEV_1 (SecFilt *in, off_t Nvalues);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/ps1_dev_1_defs.h
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/ps1_dev_1_defs.h	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/ps1_dev_1_defs.h	(revision 37403)
@@ -3,6 +3,6 @@
 Average 	       	*Average_PS1_DEV_1_ToInternal (Average_PS1_DEV_1 *in, off_t Nvalues, SecFilt **primary);
 Average_PS1_DEV_1       *AverageInternalTo_PS1_DEV_1 (Average *in, off_t Nvalues, SecFilt *primary);
-Measure 	       	*Measure_PS1_DEV_1_ToInternal (Measure_PS1_DEV_1 *in, off_t Nvalues);
-Measure_PS1_DEV_1       *MeasureInternalTo_PS1_DEV_1 (Measure *in, off_t Nvalues);
+Measure 	       	*Measure_PS1_DEV_1_ToInternal (Average *ave, Measure_PS1_DEV_1 *in, off_t Nvalues);
+Measure_PS1_DEV_1       *MeasureInternalTo_PS1_DEV_1 (Average *ave, Measure *in, off_t Nvalues);
 SecFilt 	       	*SecFilt_PS1_DEV_1_ToInternal (SecFilt_PS1_DEV_1 *in, off_t Nvalues);
 SecFilt_PS1_DEV_1       *SecFiltInternalTo_PS1_DEV_1 (SecFilt *in, off_t Nvalues);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/ps1_dev_2_defs.h
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/ps1_dev_2_defs.h	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/ps1_dev_2_defs.h	(revision 37403)
@@ -3,6 +3,6 @@
 Average 	       	*Average_PS1_DEV_2_ToInternal (Average_PS1_DEV_2 *in, off_t Nvalues, SecFilt **primary);
 Average_PS1_DEV_2       *AverageInternalTo_PS1_DEV_2 (Average *in, off_t Nvalues, SecFilt *primary);
-Measure 	       	*Measure_PS1_DEV_2_ToInternal (Measure_PS1_DEV_2 *in, off_t Nvalues);
-Measure_PS1_DEV_2       *MeasureInternalTo_PS1_DEV_2 (Measure *in, off_t Nvalues);
+Measure 	       	*Measure_PS1_DEV_2_ToInternal (Average *ave, Measure_PS1_DEV_2 *in, off_t Nvalues);
+Measure_PS1_DEV_2       *MeasureInternalTo_PS1_DEV_2 (Average *ave, Measure *in, off_t Nvalues);
 SecFilt 	       	*SecFilt_PS1_DEV_2_ToInternal (SecFilt_PS1_DEV_2 *in, off_t Nvalues);
 SecFilt_PS1_DEV_2       *SecFiltInternalTo_PS1_DEV_2 (SecFilt *in, off_t Nvalues);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/ps1_ref_defs.h
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/ps1_ref_defs.h	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/ps1_ref_defs.h	(revision 37403)
@@ -3,6 +3,6 @@
 Average 	       	*Average_PS1_REF_ToInternal (Average_PS1_REF *in, off_t Nvalues, SecFilt **primary);
 Average_PS1_REF          *AverageInternalTo_PS1_REF (Average *in, off_t Nvalues, SecFilt *primary);
-Measure 	       	*Measure_PS1_REF_ToInternal (Measure_PS1_REF *in, off_t Nvalues);
-Measure_PS1_REF          *MeasureInternalTo_PS1_REF (Measure *in, off_t Nvalues);
+Measure 	       	*Measure_PS1_REF_ToInternal (Average *ave, Measure_PS1_REF *in, off_t Nvalues);
+Measure_PS1_REF          *MeasureInternalTo_PS1_REF (Average *ave, Measure *in, off_t Nvalues);
 SecFilt 	       	*SecFilt_PS1_REF_ToInternal (SecFilt_PS1_REF *in, off_t Nvalues);
 SecFilt_PS1_REF          *SecFiltInternalTo_PS1_REF (SecFilt *in, off_t Nvalues);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/ps1_v1_defs.h
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/ps1_v1_defs.h	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/ps1_v1_defs.h	(revision 37403)
@@ -3,6 +3,6 @@
 Average 	       	*Average_PS1_V1_ToInternal (Average_PS1_V1 *in, off_t Nvalues, SecFilt **primary);
 Average_PS1_V1          *AverageInternalTo_PS1_V1 (Average *in, off_t Nvalues, SecFilt *primary);
-Measure 	       	*Measure_PS1_V1_ToInternal (Measure_PS1_V1 *in, off_t Nvalues);
-Measure_PS1_V1          *MeasureInternalTo_PS1_V1 (Measure *in, off_t Nvalues);
+Measure 	       	*Measure_PS1_V1_ToInternal (Average *ave, Measure_PS1_V1 *in, off_t Nvalues);
+Measure_PS1_V1          *MeasureInternalTo_PS1_V1 (Average *ave, Measure *in, off_t Nvalues);
 SecFilt 	       	*SecFilt_PS1_V1_ToInternal (SecFilt_PS1_V1 *in, off_t Nvalues);
 SecFilt_PS1_V1          *SecFiltInternalTo_PS1_V1 (SecFilt *in, off_t Nvalues);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/ps1_v2_defs.h
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/ps1_v2_defs.h	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/ps1_v2_defs.h	(revision 37403)
@@ -3,6 +3,6 @@
 Average 	       	*Average_PS1_V2_ToInternal (Average_PS1_V2 *in, off_t Nvalues, SecFilt **primary);
 Average_PS1_V2          *AverageInternalTo_PS1_V2 (Average *in, off_t Nvalues, SecFilt *primary);
-Measure 	       	*Measure_PS1_V2_ToInternal (Measure_PS1_V2 *in, off_t Nvalues);
-Measure_PS1_V2          *MeasureInternalTo_PS1_V2 (Measure *in, off_t Nvalues);
+Measure 	       	*Measure_PS1_V2_ToInternal (Average *ave, Measure_PS1_V2 *in, off_t Nvalues);
+Measure_PS1_V2          *MeasureInternalTo_PS1_V2 (Average *ave, Measure *in, off_t Nvalues);
 SecFilt 	       	*SecFilt_PS1_V2_ToInternal (SecFilt_PS1_V2 *in, off_t Nvalues);
 SecFilt_PS1_V2          *SecFiltInternalTo_PS1_V2 (SecFilt *in, off_t Nvalues);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/ps1_v3_defs.h
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/ps1_v3_defs.h	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/ps1_v3_defs.h	(revision 37403)
@@ -3,6 +3,6 @@
 Average 	       	*Average_PS1_V3_ToInternal (Average_PS1_V3 *in, off_t Nvalues, SecFilt **primary);
 Average_PS1_V3          *AverageInternalTo_PS1_V3 (Average *in, off_t Nvalues, SecFilt *primary);
-Measure 	       	*Measure_PS1_V3_ToInternal (Measure_PS1_V3 *in, off_t Nvalues);
-Measure_PS1_V3          *MeasureInternalTo_PS1_V3 (Measure *in, off_t Nvalues);
+Measure 	       	*Measure_PS1_V3_ToInternal (Average *ave, Measure_PS1_V3 *in, off_t Nvalues);
+Measure_PS1_V3          *MeasureInternalTo_PS1_V3 (Average *ave, Measure *in, off_t Nvalues);
 SecFilt 	       	*SecFilt_PS1_V3_ToInternal (SecFilt_PS1_V3 *in, off_t Nvalues);
 SecFilt_PS1_V3          *SecFiltInternalTo_PS1_V3 (SecFilt *in, off_t Nvalues);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/ps1_v4_defs.h
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/ps1_v4_defs.h	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/ps1_v4_defs.h	(revision 37403)
@@ -3,6 +3,6 @@
 Average 	       	*Average_PS1_V4_ToInternal (Average_PS1_V4 *in, off_t Nvalues, SecFilt **primary);
 Average_PS1_V4          *AverageInternalTo_PS1_V4 (Average *in, off_t Nvalues, SecFilt *primary);
-Measure 	       	*Measure_PS1_V4_ToInternal (Measure_PS1_V4 *in, off_t Nvalues);
-Measure_PS1_V4          *MeasureInternalTo_PS1_V4 (Measure *in, off_t Nvalues);
+Measure 	       	*Measure_PS1_V4_ToInternal (Average *ave, Measure_PS1_V4 *in, off_t Nvalues);
+Measure_PS1_V4          *MeasureInternalTo_PS1_V4 (Average *ave, Measure *in, off_t Nvalues);
 SecFilt 	       	*SecFilt_PS1_V4_ToInternal (SecFilt_PS1_V4 *in, off_t Nvalues);
 SecFilt_PS1_V4          *SecFiltInternalTo_PS1_V4 (SecFilt *in, off_t Nvalues);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/ps1_v5_defs.h
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/ps1_v5_defs.h	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/include/ps1_v5_defs.h	(revision 37403)
@@ -0,0 +1,16 @@
+Image 		       	*Image_PS1_V5_ToInternal (Image_PS1_V5 *in, off_t Nvalues, off_t Nalloc);
+Image_PS1_V5    	*ImageInternalTo_PS1_V5 (Image *in, off_t Nvalues);
+Average 	       	*Average_PS1_V5_ToInternal (Average_PS1_V5 *in, off_t Nvalues, SecFilt **primary);
+Average_PS1_V5          *AverageInternalTo_PS1_V5 (Average *in, off_t Nvalues, SecFilt *primary);
+Measure 	       	*Measure_PS1_V5_ToInternal (Average *ave, Measure_PS1_V5 *in, off_t Nvalues);
+Measure_PS1_V5          *MeasureInternalTo_PS1_V5 (Average *ave, Measure *in, off_t Nvalues);
+SecFilt 	       	*SecFilt_PS1_V5_ToInternal (SecFilt_PS1_V5 *in, off_t Nvalues);
+SecFilt_PS1_V5          *SecFiltInternalTo_PS1_V5 (SecFilt *in, off_t Nvalues);
+
+Lensing 	       	*Lensing_PS1_V5_ToInternal (Lensing_PS1_V5 *in, off_t Nvalues);
+Lensing_PS1_V5          *LensingInternalTo_PS1_V5 (Lensing *in, off_t Nvalues);
+Lensobj 	       	*Lensobj_PS1_V5_ToInternal (Lensobj_PS1_V5 *in, off_t Nvalues);
+Lensobj_PS1_V5          *LensobjInternalTo_PS1_V5 (Lensobj *in, off_t Nvalues);
+
+PhotCode                *PhotCode_PS1_V5_To_Internal (PhotCode_PS1_V5 *in, off_t Nvalues);
+PhotCode_PS1_V5         *PhotCode_Internal_To_PS1_V5 (PhotCode *in, off_t Nvalues);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/BoundaryTree.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/BoundaryTree.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/BoundaryTree.c	(revision 37403)
@@ -84,6 +84,6 @@
   gfits_scan (headerPHU, "DEC_ORI",  "%lf", 1, &tree->DEC_origin);
   gfits_scan (headerPHU, "DEC_OFF",  "%lf", 1, &tree->DEC_offset);
-  gfits_scan (headerPHU, "NX_SUB",   "%d",  1, &tree->NX_SUB);
-  gfits_scan (headerPHU, "NY_SUB",   "%d",  1, &tree->NY_SUB);
+  gfits_scan (headerPHU, "NX_SUB",   "%f",  1, &tree->NX_SUB);
+  gfits_scan (headerPHU, "NY_SUB",   "%f",  1, &tree->NY_SUB);
   gfits_scan (headerPHU, "PIXSCALE", "%lf", 1, &tree->dPix);
 
@@ -111,6 +111,6 @@
   ALLOCATE (tree->Xo,   double *, tree->Nzone);
   ALLOCATE (tree->Yo,   double *, tree->Nzone);
-  ALLOCATE (tree->dX,      int *, tree->Nzone);
-  ALLOCATE (tree->dY,      int *, tree->Nzone);
+  ALLOCATE (tree->dX,    float *, tree->Nzone);
+  ALLOCATE (tree->dY,    float *, tree->Nzone);
   ALLOCATE (tree->cell,    int *, tree->Nzone);
   ALLOCATE (tree->projID,  int *, tree->Nzone);
@@ -121,6 +121,6 @@
     ALLOCATE (tree->Xo[i],   double, tree->Nband[i]);
     ALLOCATE (tree->Yo[i],   double, tree->Nband[i]);
-    ALLOCATE (tree->dX[i],      int, tree->Nband[i]);
-    ALLOCATE (tree->dY[i],      int, tree->Nband[i]);
+    ALLOCATE (tree->dX[i],    float, tree->Nband[i]);
+    ALLOCATE (tree->dY[i],    float, tree->Nband[i]);
     ALLOCATE (tree->cell[i],    int, tree->Nband[i]);
     ALLOCATE (tree->projID[i],  int, tree->Nband[i]);
@@ -147,6 +147,6 @@
   GET_COLUMN_NEW(&headerCell, &ftableCell, Xo,    "X_CENT",      double);
   GET_COLUMN_NEW(&headerCell, &ftableCell, Yo,    "Y_CENT",      double);
-  GET_COLUMN_NEW(&headerCell, &ftableCell, dX,    "X_GRID",      int);
-  GET_COLUMN_NEW(&headerCell, &ftableCell, dY,    "Y_GRID",      int);
+  GET_COLUMN_NEW(&headerCell, &ftableCell, dX,    "X_GRID",      float);
+  GET_COLUMN_NEW(&headerCell, &ftableCell, dY,    "Y_GRID",      float);
   GET_COLUMN_NEW(&headerCell, &ftableCell, name,  "NAME",        char); // XXX how is this done?
   gfits_free_header (&headerCell);
@@ -214,6 +214,6 @@
   gfits_modify (&header, "DEC_OFF", "%lf", 1, tree->DEC_offset);
 
-  gfits_modify (&header, "NX_SUB", "%d", 1, tree->NX_SUB);
-  gfits_modify (&header, "NY_SUB", "%d", 1, tree->NY_SUB);
+  gfits_modify (&header, "NX_SUB", "%f", 1, tree->NX_SUB);
+  gfits_modify (&header, "NY_SUB", "%f", 1, tree->NY_SUB);
   gfits_modify (&header, "PIXSCALE", "%lf", 1, tree->dPix);
 
@@ -289,6 +289,6 @@
     gfits_define_bintable_column (&theader, "D", "X_CENT", "projection cell center pixel", "none", 1.0, 0.0);
     gfits_define_bintable_column (&theader, "D", "Y_CENT", "projection cell center pixel", "none", 1.0, 0.0);
-    gfits_define_bintable_column (&theader, "J", "X_GRID", "skycell grid spacing", "none", 1.0, 0.0);
-    gfits_define_bintable_column (&theader, "J", "Y_GRID", "skycell grid spacing", "none", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "X_GRID", "skycell grid spacing", "none", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "Y_GRID", "skycell grid spacing", "none", 1.0, 0.0);
     gfits_define_bintable_column (&theader, fmt, "NAME", "cell name", "none", 1.0, 0.0);
 
@@ -310,6 +310,6 @@
     double *Xo            ; ALLOCATE (Xo,    double, Ncell);
     double *Yo            ; ALLOCATE (Yo,    double, Ncell);
-    int    *dX            ; ALLOCATE (dX,    int,    Ncell);
-    int    *dY            ; ALLOCATE (dY,    int,    Ncell);
+    float  *dX            ; ALLOCATE (dX,    float,  Ncell);
+    float  *dY            ; ALLOCATE (dY,    float,  Ncell);
     char   *name          ; ALLOCATE (name,  char,   Ncell*BOUNDARY_TREE_NAME_LENGTH);
 
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/ImageMetadata.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/ImageMetadata.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/ImageMetadata.c	(revision 37403)
@@ -124,14 +124,14 @@
   gfits_create_table_header (&theader, "BINTABLE", "IMAGE_SUBSET");
 
-  gfits_define_bintable_column (&theader, "J", "IMAGE_ID", "image ID", NULL, 1.0, 1.0*0x8000);
-  gfits_define_bintable_column (&theader, "J", "EXTERN_ID", "extern ID", NULL, 1.0, 1.0*0x8000);
-  gfits_define_bintable_column (&theader, "J", "EXPNAME_AS_INT", "expname as integer", NULL, 1.0, 1.0*0x8000);
-  gfits_define_bintable_column (&theader, "D", "CRVAL1", "ra at center", "degrees", 1.0, 0.0);
-  gfits_define_bintable_column (&theader, "D", "CRVAL2", "dec at center", "degrees", 1.0, 0.0);
-  gfits_define_bintable_column (&theader, "E", "THETA", "camera rot angle", "degrees", 1.0, 0.0);
-  gfits_define_bintable_column (&theader, "E", "MCAL", "zero point offset", "magnitudes", 1.0, 0.0);
-  gfits_define_bintable_column (&theader, "E", "SECZ", "airmass", "none", 1.0, 0.0);
-  gfits_define_bintable_column (&theader, "E", "X_CENTER", "chip center", "none", 1.0, 0.0);
-  gfits_define_bintable_column (&theader, "E", "Y_CENTER", "chip center", "none", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "J", "IMAGE_ID", 	 "image ID",  	       NULL, 	     1.0, FT_BZERO_INT32);
+  gfits_define_bintable_column (&theader, "J", "EXTERN_ID",      "extern ID", 	       NULL, 	     1.0, FT_BZERO_INT32);
+  gfits_define_bintable_column (&theader, "J", "EXPNAME_AS_INT", "expname as integer", NULL, 	     1.0, FT_BZERO_INT32);
+  gfits_define_bintable_column (&theader, "D", "CRVAL1", 	 "ra at center",       "degrees",    1.0, 0.0);
+  gfits_define_bintable_column (&theader, "D", "CRVAL2", 	 "dec at center",      "degrees",    1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E", "THETA", 	 "camera rot angle",   "degrees",    1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E", "MCAL",  	 "zero point offset",  "magnitudes", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E", "SECZ",  	 "airmass",            "none", 	     1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E", "X_CENTER", 	 "chip center",        "none", 	     1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E", "Y_CENTER", 	 "chip center",        "none", 	     1.0, 0.0);
 
   // generate the output array that carries the data
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/LoadPhotcodesFITS.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/LoadPhotcodesFITS.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/LoadPhotcodesFITS.c	(revision 37403)
@@ -64,4 +64,5 @@
   CONVERT_FORMAT("DVO_PHOTCODE_PS1_V3",    PS1_V3);
   CONVERT_FORMAT("DVO_PHOTCODE_PS1_V4",    PS1_V4);
+  CONVERT_FORMAT("DVO_PHOTCODE_PS1_V5",    PS1_V5);
 
   table = GetPhotcodeTable ();
@@ -100,4 +101,15 @@
   // photcode.equiv of 0 means "undefined"
   for (i = 0; i < Ncode; i++) {
+    if (!strcasecmp(photcode[i].name, "MAG")) {
+      fprintf (stderr, "MAG is not an allowed photcode name (reserved to DVO internals)\n");
+      free (photcode);
+      return FALSE;
+    }
+    if (!strcasecmp(photcode[i].name, "FLUX")) {
+      fprintf (stderr, "FLUX is not an allowed photcode name (reserved to DVO internals)\n");
+      free (photcode);
+      return FALSE;
+    }
+
     if (photcode[i].type == PHOT_DEP) {
       if (photcode[i].equiv == 0) continue;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/LoadPhotcodesText.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/LoadPhotcodesText.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/LoadPhotcodesText.c	(revision 37403)
@@ -108,4 +108,9 @@
     }
 
+    if (!strcasecmp(name, "MAG")) {
+      fprintf (stderr, "MAG is not an allowed photcode name (reserved to DVO internals)\n");
+      return FALSE;
+    }
+
     photcode[Ncode].type = 0;
     memset(photcode[Ncode].dummy, 0, sizeof(photcode[Ncode].dummy));
@@ -137,8 +142,8 @@
     photcode[Ncode].photomErrSys      = atof (photomErrSys);
 
-    photcode[Ncode].astromPoorMask    = strtol (astromPoorMask, NULL, 0);
-    photcode[Ncode].astromBadMask     = strtol (astromBadMask, NULL, 0);
-    photcode[Ncode].photomPoorMask    = strtol (photomPoorMask, NULL, 0);
-    photcode[Ncode].photomBadMask     = strtol (photomBadMask, NULL, 0);
+    photcode[Ncode].astromPoorMask    = strtoll (astromPoorMask, NULL, 0);
+    photcode[Ncode].astromBadMask     = strtoll (astromBadMask, NULL, 0);
+    photcode[Ncode].photomPoorMask    = strtoll (photomPoorMask, NULL, 0);
+    photcode[Ncode].photomBadMask     = strtoll (photomBadMask, NULL, 0);
 
     switch (photcode[Ncode].type) {
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/SavePhotcodesFITS.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/SavePhotcodesFITS.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/SavePhotcodesFITS.c	(revision 37403)
@@ -30,9 +30,9 @@
   // for the moment, we simply support the latest photcode format for output
   // XXX update this as needed as new formats are defined
-  PhotCode_PS1_V4 *photcode_output = PhotCode_Internal_To_PS1_V4 (table[0].code, table[0].Ncode);
+  PhotCode_PS1_V5 *photcode_output = PhotCode_Internal_To_PS1_V5 (table[0].code, table[0].Ncode);
 
   /* convert FITS format data to internal format (byteswaps & EXTNAME) */
   if (!gfits_db_create (&db)) return (FALSE);
-  if (!gfits_table_set_PhotCode_PS1_V4 (&db.ftable, photcode_output, table[0].Ncode)) return (FALSE);
+  if (!gfits_table_set_PhotCode_PS1_V5 (&db.ftable, photcode_output, table[0].Ncode)) return (FALSE);
   if (!gfits_db_save (&db)) return (FALSE);
   if (!gfits_db_close (&db)) return (FALSE);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/TessellationTable.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/TessellationTable.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/TessellationTable.c	(revision 37403)
@@ -28,9 +28,9 @@
     tess[i].dPix = NAN;
 
-    tess[i].dX = 0;
-    tess[i].dY = 0;
-
-    tess[i].NX_SUB = 0;
-    tess[i].NY_SUB = 0;
+    tess[i].dX = NAN;
+    tess[i].dY = NAN;
+
+    tess[i].NX_SUB = NAN;
+    tess[i].NY_SUB = NAN;
 
     tess[i].basename = NULL;
@@ -123,6 +123,6 @@
   GET_COLUMN_NEW(Xo,     "X_CENT", double);
   GET_COLUMN_NEW(Yo,     "Y_CENT", double);
-  GET_COLUMN_NEW(dX,     "X_GRID", int);
-  GET_COLUMN_NEW(dY,     "Y_GRID", int);
+  GET_COLUMN_NEW(dX,     "X_GRID", float);
+  GET_COLUMN_NEW(dY,     "Y_GRID", float);
   GET_COLUMN_NEW(Rmin,   "R_MIN",  double);
   GET_COLUMN_NEW(Rmax,   "R_MAX",  double);
@@ -130,6 +130,6 @@
   GET_COLUMN_NEW(Dmax,   "D_MAX",  double);
   GET_COLUMN_NEW(dPix,   "SCALE",  double);
-  GET_COLUMN_NEW(NX_SUB, "NX_SUB", int);
-  GET_COLUMN_NEW(NY_SUB, "NY_SUB", int);
+  GET_COLUMN_NEW(NX_SUB, "NX_SUB", float);
+  GET_COLUMN_NEW(NY_SUB, "NY_SUB", float);
   GET_COLUMN_NEW(TYPE,   "TYPE",   int);
 
@@ -280,6 +280,6 @@
     gfits_modify (&header, "DEC_OFF", "%lf", 1, rings->DEC_offset);
 
-    gfits_modify (&header, "NX_SUB", "%d", 1, rings->NX_SUB);
-    gfits_modify (&header, "NY_SUB", "%d", 1, rings->NY_SUB);
+    gfits_modify (&header, "NX_SUB", "%f", 1, rings->NX_SUB);
+    gfits_modify (&header, "NY_SUB", "%f", 1, rings->NY_SUB);
     gfits_modify (&header, "PIXSCALE", "%lf", 1, rings->dPix);
   }
@@ -300,6 +300,6 @@
   gfits_define_bintable_column (&theader, "D", "X_CENT", "projection cell center pixel", "none", 1.0, 0.0);
   gfits_define_bintable_column (&theader, "D", "Y_CENT", "projection cell center pixel", "none", 1.0, 0.0);
-  gfits_define_bintable_column (&theader, "J", "X_GRID", "skycell grid spacing", "none", 1.0, 0.0);
-  gfits_define_bintable_column (&theader, "J", "Y_GRID", "skycell grid spacing", "none", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E", "X_GRID", "skycell grid spacing", "none", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E", "Y_GRID", "skycell grid spacing", "none", 1.0, 0.0);
   gfits_define_bintable_column (&theader, "D", "R_MIN",  "RA limit (lower)", "none", 1.0, 0.0);
   gfits_define_bintable_column (&theader, "D", "R_MAX",  "RA limit (upper)", "none", 1.0, 0.0);
@@ -307,6 +307,6 @@
   gfits_define_bintable_column (&theader, "D", "D_MAX",  "DEC limit (upper)", "none", 1.0, 0.0);
   gfits_define_bintable_column (&theader, "D", "SCALE",  "pixel scale for projection cell", "none", 1.0, 0.0);
-  gfits_define_bintable_column (&theader, "J", "NX_SUB", "skycell subdivision in x", "none", 1.0, 0.0);
-  gfits_define_bintable_column (&theader, "J", "NY_SUB", "skycell subdivision in y", "none", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E", "NX_SUB", "skycell subdivision in x", "none", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E", "NY_SUB", "skycell subdivision in y", "none", 1.0, 0.0);
   gfits_define_bintable_column (&theader, "J", "TYPE",   "type of tessellation", "none", 1.0, 0.0);
 
@@ -330,6 +330,6 @@
   double *Xo            ; ALLOCATE (Xo    ,    double, Nout);
   double *Yo            ; ALLOCATE (Yo    ,    double, Nout);
-  int    *dX            ; ALLOCATE (dX    ,    int,    Nout);
-  int    *dY            ; ALLOCATE (dY    ,    int,    Nout);
+  float  *dX            ; ALLOCATE (dX    ,    float,  Nout);
+  float  *dY            ; ALLOCATE (dY    ,    float,  Nout);
   double *Rmin          ; ALLOCATE (Rmin  ,    double, Nout);
   double *Rmax          ; ALLOCATE (Rmax  ,    double, Nout);
@@ -337,6 +337,6 @@
   double *Dmax          ; ALLOCATE (Dmax  ,    double, Nout);
   double *dPix          ; ALLOCATE (dPix  ,    double, Nout);
-  int    *NX_SUB        ; ALLOCATE (NX_SUB,    int,    Nout);
-  int    *NY_SUB        ; ALLOCATE (NY_SUB,    int,    Nout);
+  float  *NX_SUB        ; ALLOCATE (NX_SUB,    float,  Nout);
+  float  *NY_SUB        ; ALLOCATE (NY_SUB,    float,  Nout);
   int    *TYPE          ; ALLOCATE (TYPE,      int,    Nout);
 
@@ -559,4 +559,8 @@
     int xi = x / tess[myTess].tree->dX[zone][band];
     int yi = y / tess[myTess].tree->dY[zone][band];
+
+    xi = MAX(MIN(xi, tess[myTess].tree->NX_SUB - 1.0), 0);
+    yi = MAX(MIN(yi, tess[myTess].tree->NY_SUB - 1.0), 0);
+
     int N = xi + tess[myTess].tree->NX_SUB * yi;
   
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/cmf-ps1-dv3.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/cmf-ps1-dv3.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/cmf-ps1-dv3.c	(revision 37403)
@@ -2,5 +2,5 @@
 
 /*** note : this file is derived from the autocode version, but is modified because
-     the forma does not match with structure byte boundaries ***/
+     the format does not match with structure byte boundaries ***/
 
 /* if we are not correctly including the ohana headers, this will fail */
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/cmf-ps1-sv3.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/cmf-ps1-sv3.c	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/cmf-ps1-sv3.c	(revision 37403)
@@ -0,0 +1,375 @@
+# include "dvo.h"
+
+// ST_SIZE is the size of the structure (must be modulo 8 bytes)
+// FT_SIZE is the size of a row in the FITS table (inpt or output)
+# define ST_SIZE 224
+# define FT_SIZE 220
+
+// this function is based on the one generated by the autocode of cmf-ps1-v5.d
+unsigned char *gfits_convert_CMF_PS1_SV3 (unsigned char *input, off_t size, off_t nitems, char toStruct) {
+
+  off_t i;
+  unsigned char *byte = NULL;
+  unsigned char *output = NULL;
+
+  if (size != ST_SIZE) { 
+    fprintf (stderr, "WARNING: mismatch in data types CMF_PS1_SV3: "OFF_T_FMT" vs %d\n",  size,  ST_SIZE);
+    return (NULL);
+  }
+
+  /* provide initial values to avoid compiler warnings for non-BYTE_SWAP arch */
+  i = 0;
+
+  // BYTE & WORD swap below is valid for the structure, not the FITS buffer
+  if (toStruct) {
+    // allocate a new output data buffer
+    ALLOCATE (output, unsigned char, nitems*sizeof(CMF_PS1_SV3));
+    unsigned char *inbyte = input;
+    unsigned char *otbyte = output;
+
+    // the data in the input table does not line up with the output structure: copy carefully.
+    for (i = 0; i < nitems; i++, inbyte += FT_SIZE, otbyte += ST_SIZE) {
+      memcpy (&otbyte[  0], &inbyte[  0],  76); // IPP_IDET to CAL_PSF_MAG_SIG
+      memcpy (&otbyte[ 80], &inbyte[ 76],  16); // RA_PSF, DEC_PSF
+      memcpy (&otbyte[ 76], &inbyte[ 92],   8); // PEAK_FLUX_AS_MAG
+      memcpy (&otbyte[ 96], &inbyte[ 96], 124); // SKY to PADDING
+      memset (&otbyte[220], 0, 4); // PADDING2
+    }
+
+    // after we have moved around PEAK_FLUX_AS_MAG, RA_PSF, DEC_PSF, we can swap as needed for this platform
+    byte = output;
+  } else {
+    byte = input;
+  }
+
+# ifdef BYTE_SWAP
+  char tmp = 0;
+  for (i = 0; i < nitems; i++, byte += ST_SIZE) {
+    /** BYTE SWAP **/
+    SWAP_WORD (0);   // IPP_IDET
+    SWAP_WORD (4);   // X_PSF
+    SWAP_WORD (8);   // Y_PSF
+    SWAP_WORD (12);  // X_PSF_SIG
+    SWAP_WORD (16);  // Y_PSF_SIG
+    SWAP_WORD (20);  // POSANGLE
+    SWAP_WORD (24);  // PLTSCALE
+    SWAP_WORD (28);  // PSF_INST_MAG
+    SWAP_WORD (32);  // PSF_INST_MAG_SIG
+    SWAP_WORD (36);  // PSF_INST_FLUX
+    SWAP_WORD (40);  // PSF_INST_FLUX_SIG
+    SWAP_WORD (44);  // AP_MAG
+    SWAP_WORD (48);  // AP_MAG_RAW
+    SWAP_WORD (52);  // AP_MAG_RADIUS
+    SWAP_WORD (56);  // AP_FLUX
+    SWAP_WORD (60);  // AP_FLUX_SIG
+    SWAP_WORD (64);  // AP_NPIX
+    SWAP_WORD (68);  // CAL_PSF_MAG
+    SWAP_WORD (72);  // CAL_PSF_MAG_SIG
+
+    // order in structure
+    SWAP_WORD (76);  // PEAK_FLUX_AS_MAG
+    SWAP_DBLE (80);  // RA_PSF
+    SWAP_DBLE (88);  // DEC_PSF
+
+    // order in FITS table
+    // SWAP_WORD (76);  // RA_PSF
+    // SWAP_DBLE (84);  // DEC_PSF
+    // SWAP_DBLE (92);  // PEAK_FLUX_AS_MAG
+
+    SWAP_WORD (96);  // SKY
+    SWAP_WORD (100); // SKY_SIG
+    SWAP_WORD (104); // PSF_CHISQ
+    SWAP_WORD (108); // CR_NSIGMA
+    SWAP_WORD (112); // EXT_NSIGMA
+    SWAP_WORD (116); // PSF_MAJOR
+    SWAP_WORD (120); // PSF_MINOR
+    SWAP_WORD (124); // PSF_THETA
+    SWAP_WORD (128); // PSF_CORE
+    SWAP_WORD (132); // PSF_FWHM_MAJ
+    SWAP_WORD (136); // PSF_FWHM_MIN
+    SWAP_WORD (140); // PSF_QF
+    SWAP_WORD (144); // PSF_QF_PERFECT
+    SWAP_WORD (148); // PSF_NDOF
+    SWAP_WORD (152); // PSF_NPIX
+    SWAP_WORD (156); // MOMENTS_XX
+    SWAP_WORD (160); // MOMENTS_XY
+    SWAP_WORD (164); // MOMENTS_YY
+    SWAP_WORD (168); // MOMENTS_M3C
+    SWAP_WORD (172); // MOMENTS_M3S
+    SWAP_WORD (176); // MOMENTS_M4C
+    SWAP_WORD (180); // MOMENTS_M4S
+    SWAP_WORD (184); // MOMENTS_R1
+    SWAP_WORD (188); // MOMENTS_RH
+    SWAP_WORD (192); // KRON_FLUX
+    SWAP_WORD (196); // KRON_FLUX_ERR
+    SWAP_WORD (200); // KRON_FLUX_INNER
+    SWAP_WORD (204); // KRON_FLUX_OUTER
+    SWAP_WORD (208); // FLAGS
+    SWAP_WORD (212); // FLAGS2
+    SWAP_BYTE (216); // N_FRAMES
+    SWAP_BYTE (218); // PADDING
+    SWAP_WORD (220); // PADDING2
+  }
+# endif  
+
+  // BYTE & WORD swap below is valid for the structure, not the FITS buffer
+  if (!toStruct) {
+    // allocate a new output data buffer
+    ALLOCATE (output, unsigned char, nitems*FT_SIZE);
+    unsigned char *inbyte = input;
+    unsigned char *otbyte = output;
+
+    // the data in the input table does not line up with the output structure: copy carefully.
+    for (i = 0; i < nitems; i++, inbyte += ST_SIZE, otbyte += FT_SIZE) {
+      memcpy (&otbyte[  0], &inbyte[  0],  76); // IPP_IDET to CAL_PSF_MAG_SIG
+      memcpy (&otbyte[ 76], &inbyte[ 80],  16); // RA_PSF, DEC_PSF
+      memcpy (&otbyte[ 92], &inbyte[ 76],   4); // PEAK_FLUX_AS_MAG
+      memcpy (&otbyte[ 96], &inbyte[ 96], 124); // SKY to PADDING
+    }
+  }
+
+  return (output);
+} 
+
+int gfits_table_scale_storage_CMF_PS1_SV3 (CMF_PS1_SV3 *data, off_t Ndata) {
+
+  off_t i;
+  for (i = 0; i < Ndata; i++) {
+    data[i].detID   -= 0x80000000;
+    data[i].flags   -= 0x80000000;
+    data[i].flags2  -= 0x80000000;
+    data[i].nFrames -= 0x8000;
+  }
+  return TRUE;
+}
+
+/*** add test of EXTNAME and header-defined columns? ***/
+/* return internal structure representation */
+CMF_PS1_SV3 *gfits_table_get_CMF_PS1_SV3 (FTable *ftable, off_t *Ndata, char *swapped) {
+
+  int Ncols;
+  CMF_PS1_SV3 *data;
+
+  Ncols = ftable[0].header[0].Naxis[0];
+  if (Ncols != FT_SIZE) {
+    fprintf (stderr, "ERROR: mis-match in table size: width is %d but should be %d bytes\n", Ncols, FT_SIZE);
+    return NULL;
+  }
+
+  *Ndata = ftable[0].header[0].Naxis[1];
+  data = (CMF_PS1_SV3 *) ftable[0].buffer;
+  if ((swapped == NULL) || (*swapped == FALSE)) {
+    unsigned char *newdata = gfits_convert_CMF_PS1_SV3 ((unsigned char *) data, sizeof (CMF_PS1_SV3), *Ndata, TRUE);
+    if (!newdata) return NULL;
+    free (ftable[0].buffer);
+    ftable[0].buffer = (char *) newdata;
+    data = (CMF_PS1_SV3 *) ftable[0].buffer;
+    gfits_table_scale_storage_CMF_PS1_SV3 (data, *Ndata);
+    if (swapped != NULL) *swapped = TRUE;
+  }
+  return (data);
+}
+
+int gfits_table_set_CMF_PS1_SV3 (FTable *ftable, CMF_PS1_SV3 *data, off_t Ndata) {
+
+  Header *header;
+
+  header = ftable[0].header;
+
+  /* create table header */
+  if (!gfits_create_table_header (header, "BINTABLE", "CMF_PS1_SV3")) return (FALSE);
+
+  /* define table layout */
+  /** TABLE DEFINITION **/
+  gfits_define_bintable_column (header, "J",    "IPP_IDET",         "detection ID                     ", "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "X_PSF",            "x coord",                         "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "Y_PSF",            "y coord",                         "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "X_PSF_SIG",        "x coord error",                   "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "Y_PSF_SIG",        "y coord error",                   "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "POSANGLE",         "Posangle at source",              "degrees",           1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PLTSCALE",         "Plate Scale at source",           "arcsec/pixel",      1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_INST_MAG",     "inst mags",                       "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_INST_MAG_SIG", "inst mag error",                  "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_INST_FLUX",    "psf flux",                        "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_INST_FLUX_SIG", "psf flux error",                  "counts      ",      1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "AP_MAG",           "standard aperture mag",           "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "AP_MAG_RAW",       "raw aperture mag",                "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "AP_MAG_RADIUS",    "radius used for fit",             "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "AP_FLUX",          "aperture flux",                   "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "AP_FLUX_SIG",      "error on ap flux",                "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "J",    "AP_NPIX",          "pixels used for aper",            "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "CAL_PSF_MAG",      "calibrated psf mag",              "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "CAL_PSF_MAG_SIG",  "zero point scatter",              "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PEAK_FLUX_AS_MAG", "peak flux as a mag",              "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "D",    "RA_PSF",           "PSF RA coord",                    "degrees",           1.0, 0.0);
+  gfits_define_bintable_column (header, "D",    "DEC_PSF",          "PSF DEC coord",                   "degrees",           1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "SKY",              "sky flux",                        "cnts/sec",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "SKY_SIG",          "sky flux error",                  "cnts/sec",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_CHISQ",        "psf fit chisq",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "CR_NSIGMA",        "Nsigma deviations from PSF to CF", "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "EXT_NSIGMA",       "Nsigma deviations from PSF to EXT", "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_MAJOR",        "psf fit major axis",              "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_MINOR",        "psf fit minor axis",              "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_THETA",        "ellipse angle",                   "degrees",           1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_CORE",         "extra PSF parameter",             "unitless",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_FWHM_MAJ",     "true fwhm of psf",                "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_FWHM_MIN",     "true fwhm (minor)",               "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_QF",           "quality factor",                  "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_QF_PERFECT",   "quality factor perfect",          "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "J",    "PSF_NDOF",         "psf degrees of freedom",          "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "J",    "PSF_NPIX",         "psf number of pixels",            "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_XX",       "second moment X",                 "pixels^2",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_XY",       "second moment Y",                 "pixels^2",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_YY",       "second moment XY",                "pixels^2",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_M3C",      "third moment cos(t)",             "pixels^3",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_M3S",      "third moment sin(t)",             "pixels^3",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_M4C",      "fourth moment cos(t)",            "pixels^4",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_M4S",      "fourth moment sin(t)",            "pixels^4",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_R1",       "first radial moment",             "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_RH",       "half radial moment",              "pixels^1/2",        1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "KRON_FLUX",        "kron flux",                       "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "KRON_FLUX_ERR",    "kron flux error",                 "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "KRON_FLUX_INNER",  "kron flux 1<R<2.5",               "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "KRON_FLUX_OUTER",  "kron flux 2.5<R<4",               "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "J",    "FLAGS",            "analysis flags",                  "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "J",    "FLAGS2",           "analysis flags (2)",              "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "I",    "N_FRAMES",         "images overlapping peak",         "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "I",    "PADDING",          "padding for 8byte records",       "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "J",    "PADDING2",         "padding for 8byte records",       "",                  1.0, 0.0);
+
+  /* create table */
+  if (!gfits_create_table (header, ftable)) return (FALSE);
+
+  /* add data values */
+  if (!gfits_table_scale_data (ftable)) return (FALSE);
+  unsigned char *newdata = gfits_convert_CMF_PS1_SV3 ((unsigned char *) data, sizeof (CMF_PS1_SV3), Ndata, FALSE);
+  if (!newdata) return (FALSE);
+  free (ftable[0].buffer);
+  ftable[0].buffer = (char *) newdata;
+  if (!gfits_add_rows (ftable, (char *) newdata, Ndata, sizeof (CMF_PS1_SV3))) return (FALSE);
+
+  return (TRUE);
+}
+
+int gfits_table_mkheader_CMF_PS1_SV3 (Header *header) {
+
+  /* create table header */
+  if (!gfits_create_table_header (header, "BINTABLE", "CMF_PS1_SV3")) return (FALSE);
+
+  /* define table layout */
+  /** TABLE DEFINITION **/
+  gfits_define_bintable_column (header, "J",    "IPP_IDET",         "detection ID                     ", "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "X_PSF",            "x coord",                         "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "Y_PSF",            "y coord",                         "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "X_PSF_SIG",        "x coord error",                   "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "Y_PSF_SIG",        "y coord error",                   "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "POSANGLE",         "Posangle at source",              "degrees",           1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PLTSCALE",         "Plate Scale at source",           "arcsec/pixel",      1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_INST_MAG",     "inst mags",                       "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_INST_MAG_SIG", "inst mag error",                  "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_INST_FLUX",    "psf flux",                        "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_INST_FLUX_SIG", "psf flux error",                  "counts      ",      1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "AP_MAG",           "standard aperture mag",           "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "AP_MAG_RAW",       "raw aperture mag",                "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "AP_MAG_RADIUS",    "radius used for fit",             "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "AP_FLUX",          "aperture flux",                   "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "AP_FLUX_SIG",      "error on ap flux",                "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "J",    "AP_NPIX",          "pixels used for aper",            "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "CAL_PSF_MAG",      "calibrated psf mag",              "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "CAL_PSF_MAG_SIG",  "zero point scatter",              "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PEAK_FLUX_AS_MAG", "peak flux as a mag",              "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "D",    "RA_PSF",           "PSF RA coord",                    "degrees",           1.0, 0.0);
+  gfits_define_bintable_column (header, "D",    "DEC_PSF",          "PSF DEC coord",                   "degrees",           1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "SKY",              "sky flux",                        "cnts/sec",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "SKY_SIG",          "sky flux error",                  "cnts/sec",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_CHISQ",        "psf fit chisq",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "CR_NSIGMA",        "Nsigma deviations from PSF to CF", "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "EXT_NSIGMA",       "Nsigma deviations from PSF to EXT", "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_MAJOR",        "psf fit major axis",              "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_MINOR",        "psf fit minor axis",              "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_THETA",        "ellipse angle",                   "degrees",           1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_CORE",         "extra PSF parameter",             "unitless",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_FWHM_MAJ",     "true fwhm of psf",                "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_FWHM_MIN",     "true fwhm (minor)",               "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_QF",           "quality factor",                  "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_QF_PERFECT",   "quality factor perfect",          "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "J",    "PSF_NDOF",         "psf degrees of freedom",          "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "J",    "PSF_NPIX",         "psf number of pixels",            "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_XX",       "second moment X",                 "pixels^2",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_XY",       "second moment Y",                 "pixels^2",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_YY",       "second moment XY",                "pixels^2",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_M3C",      "third moment cos(t)",             "pixels^3",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_M3S",      "third moment sin(t)",             "pixels^3",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_M4C",      "fourth moment cos(t)",            "pixels^4",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_M4S",      "fourth moment sin(t)",            "pixels^4",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_R1",       "first radial moment",             "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_RH",       "half radial moment",              "pixels^1/2",        1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "KRON_FLUX",        "kron flux",                       "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "KRON_FLUX_ERR",    "kron flux error",                 "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "KRON_FLUX_INNER",  "kron flux 1<R<2.5",               "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "KRON_FLUX_OUTER",  "kron flux 2.5<R<4",               "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "J",    "FLAGS",            "analysis flags",                  "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "J",    "FLAGS2",           "analysis flags (2)",              "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "I",    "N_FRAMES",         "images overlapping peak",         "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "I",    "PADDING",          "padding for 8byte records",       "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "J",    "PADDING2",         "padding for 8byte records",       "",                  1.0, 0.0);
+
+  return (TRUE);
+}
+
+int Send_CMF_PS1_SV3 (int device, CMF_PS1_SV3 *data, int Ndata, int copy) {
+
+  int Nwrite, Nbytes;
+  CMF_PS1_SV3 *tmpdata;
+
+  Nbytes = Ndata * sizeof (CMF_PS1_SV3);
+
+  if (copy) {
+    ALLOCATE (tmpdata, CMF_PS1_SV3, Ndata);
+    memcpy (tmpdata, data, Nbytes);
+  } else {
+    tmpdata = data;
+  }
+
+  unsigned char *newdata = gfits_convert_CMF_PS1_SV3 ((unsigned char *) tmpdata, sizeof (CMF_PS1_SV3), Ndata, FALSE);
+  if (!newdata) return FALSE;
+
+  SendCommand (device, 16, "NVALUE: %6d", Ndata);
+  SendCommand (device, 16, "NBYTES: %6d", Nbytes);
+  Nwrite = write (device, newdata, Nbytes);
+  if (Nwrite != Nbytes) {
+    return (FALSE);
+  }
+  
+  /* perform handshaking? */
+
+  return (TRUE);
+}
+
+int Recv_CMF_PS1_SV3 (int device, CMF_PS1_SV3 **data, int *Ndata) {
+
+  int ndata;
+  IOBuffer message;
+  CMF_PS1_SV3 *tmpdata;
+
+  ExpectCommand (device, 16, 1.0, &message);
+  sscanf (message.buffer, "%*s %d", &ndata);
+  FreeIOBuffer (&message);
+  
+  /* what is reasonable for timeout? */
+  ExpectMessage (device, 1.0, &message);
+  
+  tmpdata = (CMF_PS1_SV3 *) message.buffer;
+  unsigned char *newdata = gfits_convert_CMF_PS1_SV3 ((unsigned char *) tmpdata, sizeof (CMF_PS1_SV3), ndata, TRUE);
+  if (!newdata) return FALSE;
+  free (message.buffer);
+
+  /* double-check data length? */
+  /* perform handshaking? */
+
+  *Ndata = ndata;
+  *data = (CMF_PS1_SV3 *) newdata;
+
+  return (TRUE);
+}
+
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/cmf-ps1-v5-lensing.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/cmf-ps1-v5-lensing.c	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/cmf-ps1-v5-lensing.c	(revision 37403)
@@ -0,0 +1,456 @@
+# include "dvo.h"
+# define ST_SIZE 312
+
+// this function is based on the one generated by the autocode of cmf-ps1-v5.d
+int gfits_convert_CMF_PS1_V5_Lensing (unsigned char *data, off_t size, off_t nitems, char toStruct) {
+
+  off_t i;
+  unsigned char tmp;
+
+  if (size != ST_SIZE) { 
+    fprintf (stderr, "WARNING: mismatch in data types CMF_PS1_V5_Lensing: "OFF_T_FMT" vs %d\n",  size,  ST_SIZE);
+    return (FALSE);
+  }
+
+  /* provide initial values to avoid compiler warnings for non-BYTE_SWAP arch */
+  i = tmp = 0;
+
+  // allocate a temporary output 
+  unsigned char tmpdata[64];
+
+  // move the bytes corresponding to PEAK_FLUX_AS_MAG, RA_PSF, DEC_PSF
+  if (toStruct) {
+    unsigned char *row = data;
+    for (i = 0; i < nitems; i++, row += size) {
+      memcpy  (tmpdata, &row[92], 4); // save PEAK_FLUX_AS_MAG (92-95)
+      memmove (&row[80], &row[76], 16); // move RA_PSF & DEC_PSF
+      memcpy  (&row[76], tmpdata, 4); // replace PEAK_FLUX_AS_MAG
+    }
+  }
+
+  // after we have moved around PEAK_FLUX_AS_MAG, RA_PSF, DEC_PSF, we can swap as needed for this platform
+  unsigned char *byte = data;
+
+# ifdef BYTE_SWAP
+  byte = (unsigned char *) data;
+  for (i = 0; i < nitems; i++, byte += ST_SIZE) {
+    /** BYTE SWAP **/
+    SWAP_WORD (0);   // IPP_IDET                     
+    SWAP_WORD (4);   // X_PSF
+    SWAP_WORD (8);   // Y_PSF
+    SWAP_WORD (12);  // X_PSF_SIG
+    SWAP_WORD (16);  // Y_PSF_SIG
+    SWAP_WORD (20);  // POSANGLE
+    SWAP_WORD (24);  // PLTSCALE
+    SWAP_WORD (28);  // PSF_INST_MAG
+    SWAP_WORD (32);  // PSF_INST_MAG_SIG
+    SWAP_WORD (36);  // PSF_INST_FLUX
+    SWAP_WORD (40);  // PSF_INST_FLUX_SIG
+    SWAP_WORD (44);  // AP_MAG
+    SWAP_WORD (48);  // AP_MAG_RAW
+    SWAP_WORD (52);  // AP_MAG_RADIUS
+    SWAP_WORD (56);  // AP_FLUX
+    SWAP_WORD (60);  // AP_FLUX_SIG
+    SWAP_WORD (64);  // AP_NPIX
+    SWAP_WORD (68);  // CAL_PSF_MAG
+    SWAP_WORD (72);  // CAL_PSF_MAG_SIG
+    SWAP_WORD (76);  // PEAK_FLUX_AS_MAG
+    SWAP_DBLE (80);  // RA_PSF
+    SWAP_DBLE (88);  // DEC_PSF
+    SWAP_WORD (96);  // SKY
+    SWAP_WORD (100); // SKY_SIGMA
+    SWAP_WORD (104); // PSF_CHISQ
+    SWAP_WORD (108); // CR_NSIGMA
+    SWAP_WORD (112); // EXT_NSIGMA
+    SWAP_WORD (116); // PSF_MAJOR
+    SWAP_WORD (120); // PSF_MINOR
+    SWAP_WORD (124); // PSF_THETA
+    SWAP_WORD (128); // PSF_CORE
+    SWAP_WORD (132); // PSF_FWHM_MAJ
+    SWAP_WORD (136); // PSF_FWHM_MIN
+    SWAP_WORD (140); // PSF_QF
+    SWAP_WORD (144); // PSF_QF_PERFECT
+    SWAP_WORD (148); // PSF_NDOF
+    SWAP_WORD (152); // PSF_NPIX
+    SWAP_WORD (156); // MOMENTS_XX
+    SWAP_WORD (160); // MOMENTS_XY
+    SWAP_WORD (164); // MOMENTS_YY
+    SWAP_WORD (168); // MOMENTS_M3C
+    SWAP_WORD (172); // MOMENTS_M3S
+    SWAP_WORD (176); // MOMENTS_M4C
+    SWAP_WORD (180); // MOMENTS_M4S
+    SWAP_WORD (184); // X11_SM_OBJ
+    SWAP_WORD (188); // X12_SM_OBJ
+    SWAP_WORD (192); // X22_SM_OBJ
+    SWAP_WORD (196); // E1_SM_OBJ
+    SWAP_WORD (200); // E2_SM_OBJ
+    SWAP_WORD (204); // X11_SH_OBJ
+    SWAP_WORD (208); // X12_SH_OBJ
+    SWAP_WORD (212); // X22_SH_OBJ
+    SWAP_WORD (216); // E1_SH_OBJ
+    SWAP_WORD (220); // E2_SH_OBJ
+    SWAP_WORD (224); // X11_SM_PSF
+    SWAP_WORD (228); // X12_SM_PSF
+    SWAP_WORD (232); // X22_SM_PSF
+    SWAP_WORD (236); // E1_SM_PSF
+    SWAP_WORD (240); // E2_SM_PSF
+    SWAP_WORD (244); // X11_SH_PSF
+    SWAP_WORD (248); // X12_SH_PSF
+    SWAP_WORD (252); // X22_SH_PSF
+    SWAP_WORD (256); // E1_SH_PSF
+    SWAP_WORD (260); // E2_SH_PSF
+    SWAP_WORD (264); // MOMENTS_R1
+    SWAP_WORD (268); // MOMENTS_RH
+    SWAP_WORD (272); // KRON_FLUX
+    SWAP_WORD (276); // KRON_FLUX_ERR
+    SWAP_WORD (280); // KRON_FLUX_INNER
+    SWAP_WORD (284); // KRON_FLUX_OUTER
+    SWAP_WORD (288); // SKY_LIMIT_RAD
+    SWAP_WORD (292); // SKY_LIMIT_FLUX
+    SWAP_WORD (296); // SKY_LIMIT_SLOPE
+    SWAP_WORD (300); // FLAGS
+    SWAP_WORD (304); // FLAGS2
+    SWAP_BYTE (308); // N_FRAMES
+    SWAP_BYTE (310); // PADDING                       
+  }
+# endif  
+
+  // move the bytes corresponding to PEAK_FLUX_AS_MAG, RA_PSF, DEC_PSF
+  if (!toStruct) {
+    unsigned char *row = data;
+    for (i = 0; i < nitems; i++, row += size) {
+      memcpy  (tmpdata, &row[76], 4); // save PEAK_FLUX_AS_MAG (92-95)
+      memmove (&row[76], &row[80], 16); // move RA_PSF & DEC_PSF
+      memcpy  (&row[92], tmpdata, 4); // replace PEAK_FLUX_AS_MAG
+    }
+  }
+
+  return (TRUE);
+} 
+
+// data organization (input vs output)
+//                FITS               struct
+// WORD   (0); // IPP_IDET           IPP_IDET           / 1J                  
+// WORD   (4); // X_PSF              X_PSF              / 1E                  
+// WORD   (8); // Y_PSF              Y_PSF              / 1E                  
+// WORD  (12); // X_PSF_SIG          X_PSF_SIG          / 1E                  
+// WORD  (16); // Y_PSF_SIG          Y_PSF_SIG          / 1E                  
+// WORD  (20); // POSANGLE           POSANGLE           / 1E                  
+// WORD  (24); // PLTSCALE           PLTSCALE           / 1E                  
+// WORD  (28); // PSF_INST_MAG       PSF_INST_MAG       / 1E                  
+// WORD  (32); // PSF_INST_MAG_SIG   PSF_INST_MAG_SIG   / 1E                  
+// WORD  (36); // PSF_INST_FLUX      PSF_INST_FLUX      / 1E                  
+// WORD  (40); // PSF_INST_FLUX_SIG  PSF_INST_FLUX_SIG  / 1E                  
+// WORD  (44); // AP_MAG             AP_MAG             / 1E                  
+// WORD  (48); // AP_MAG_RAW         AP_MAG_RAW         / 1E                  
+// WORD  (52); // AP_MAG_RADIUS      AP_MAG_RADIUS      / 1E                  
+// WORD  (56); // AP_FLUX            AP_FLUX            / 1E                  
+// WORD  (60); // AP_FLUX_SIG        AP_FLUX_SIG        / 1E                  
+// WORD  (64); // AP_NPIX            AP_NPIX            / 1J                  
+// WORD  (68); // CAL_PSF_MAG        CAL_PSF_MAG        / 1E                  
+// WORD  (72); // CAL_PSF_MAG_SIG    CAL_PSF_MAG_SIG    / 1E                  
+// WORD  (76); // PEAK_FLUX_AS_MAG   RA_PSF             / 1D                  
+// DBLE  (80); // RA_PSF             DEC_PSF            / 1D                  
+// DBLE  (88); // DEC_PSF            PEAK_FLUX_AS_MAG   / 1E                  
+// WORD  (96); // SKY                SKY                / 1E                  
+// WORD (100); // SKY_SIGMA          SKY_SIGMA          / 1E                  
+// WORD (104); // PSF_CHISQ          PSF_CHISQ          / 1E                  
+// WORD (108); // CR_NSIGMA          CR_NSIGMA          / 1E                  
+// WORD (112); // EXT_NSIGMA         EXT_NSIGMA         / 1E                  
+// WORD (116); // PSF_MAJOR          PSF_MAJOR          / 1E                  
+// WORD (120); // PSF_MINOR          PSF_MINOR          / 1E                  
+// WORD (124); // PSF_THETA          PSF_THETA          / 1E                  
+// WORD (128); // PSF_CORE           PSF_CORE           / 1E                  
+// WORD (132); // PSF_FWHM_MAJ       PSF_FWHM_MAJ       / 1E                  
+// WORD (136); // PSF_FWHM_MIN       PSF_FWHM_MIN       / 1E                  
+// WORD (140); // PSF_QF             PSF_QF             / 1E                  
+// WORD (144); // PSF_QF_PERFECT     PSF_QF_PERFECT     / 1E                  
+// WORD (148); // PSF_NDOF           PSF_NDOF           / 1J                  
+// WORD (152); // PSF_NPIX           PSF_NPIX           / 1J                  
+// WORD (156); // MOMENTS_XX         MOMENTS_XX         / 1E                  
+// WORD (160); // MOMENTS_XY         MOMENTS_XY         / 1E                  
+// WORD (164); // MOMENTS_YY         MOMENTS_YY         / 1E                  
+// WORD (168); // MOMENTS_M3C        MOMENTS_M3C        / 1E                  
+// WORD (172); // MOMENTS_M3S        MOMENTS_M3S        / 1E                  
+// WORD (176); // MOMENTS_M4C        MOMENTS_M4C        / 1E                  
+// WORD (180); // MOMENTS_M4S        MOMENTS_M4S        / 1E                  
+// WORD (184); // MOMENTS_R1         MOMENTS_R1         / 1E                  
+// WORD (188); // MOMENTS_RH         MOMENTS_RH         / 1E                  
+// WORD (192); // KRON_FLUX          KRON_FLUX          / 1E                  
+// WORD (196); // KRON_FLUX_ERR      KRON_FLUX_ERR      / 1E                  
+// WORD (200); // KRON_FLUX_INNER    KRON_FLUX_INNER    / 1E                  
+// WORD (204); // KRON_FLUX_OUTER    KRON_FLUX_OUTER    / 1E                  
+// WORD (208); // SKY_LIMIT_RAD      SKY_LIMIT_RAD      / 1E                  
+// WORD (212); // SKY_LIMIT_FLUX     SKY_LIMIT_FLUX     / 1E                  
+// WORD (216); // SKY_LIMIT_SLOPE    SKY_LIMIT_SLOPE    / 1E                  
+// WORD (220); // FLAGS              FLAGS              / 1J                  
+// WORD (224); // FLAGS2             FLAGS2             / 1J                  
+// BYTE (228); // N_FRAMES           N_FRAMES           / 1I                  
+// BYTE (230); // PADDING            PADDING            / 1I                  
+
+/*** add test of EXTNAME and header-defined columns? ***/
+/* return internal structure representation */
+CMF_PS1_V5_Lensing *gfits_table_get_CMF_PS1_V5_Lensing (FTable *ftable, off_t *Ndata, char *swapped) {
+
+  int Ncols;
+  CMF_PS1_V5_Lensing *data;
+
+  Ncols = ftable[0].header[0].Naxis[0];
+  if (Ncols != ST_SIZE) {
+    fprintf (stderr, "ERROR: mis-match in table size: width is %d but should be %d bytes\n", Ncols, ST_SIZE);
+    return NULL;
+  }
+
+  *Ndata = ftable[0].header[0].Naxis[1];
+  data = (CMF_PS1_V5_Lensing *) ftable[0].buffer;
+  if ((swapped == NULL) || (*swapped == FALSE)) {
+    if (!gfits_convert_CMF_PS1_V5_Lensing ((unsigned char *) data, sizeof (CMF_PS1_V5_Lensing), *Ndata, TRUE)) {
+      return NULL;
+    }
+    gfits_table_scale_data (ftable);
+    if (swapped != NULL) *swapped = TRUE;
+  }
+  return (data);
+}
+
+int gfits_table_set_CMF_PS1_V5_Lensing (FTable *ftable, CMF_PS1_V5_Lensing *data, off_t Ndata) {
+
+  Header *header;
+
+  header = ftable[0].header;
+
+  /* create table header */
+  if (!gfits_create_table_header (header, "BINTABLE", "CMF_PS1_V5_Lensing")) return (FALSE);
+
+  /* define table layout */
+  /** TABLE DEFINITION **/
+  gfits_define_bintable_column (header, "J",    "IPP_IDET",         "detection ID                     ", "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "X_PSF",            "x coord",                         "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "Y_PSF",            "y coord",                         "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "X_PSF_SIG",        "x coord error",                   "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "Y_PSF_SIG",        "y coord error",                   "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "POSANGLE",         "Posangle at source",              "degrees",           1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PLTSCALE",         "Plate Scale at source",           "arcsec/pixel",      1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_INST_MAG",     "inst mags",                       "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_INST_MAG_SIG", "inst mag error",                  "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_INST_FLUX",    "psf flux",                        "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_INST_FLUX_SIG", "psf flux error",                  "counts      ",      1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "AP_MAG",           "standard aperture mag",           "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "AP_MAG_RAW",       "raw aperture mag",                "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "AP_MAG_RADIUS",    "radius used for aper",            "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "AP_FLUX",          "aperture flux",                   "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "AP_FLUX_SIG",      "error on ap flux",                "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "J",    "AP_NPIX",          "pixels used by aper",             "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "CAL_PSF_MAG",      "calibrated psf mag",              "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "CAL_PSF_MAG_SIG",  "zero point scatter",              "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "D",    "RA_PSF",           "PSF RA coord",                    "degrees",           1.0, 0.0);
+  gfits_define_bintable_column (header, "D",    "DEC_PSF",          "PSF DEC coord",                   "degrees",           1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PEAK_FLUX_AS_MAG", "peak flux as a mag",              "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "SKY",              "sky flux",                        "cnts/sec",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "SKY_SIGMA",        "sky flux error",                  "cnts/sec",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_CHISQ",        "psf fit chisq",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "CR_NSIGMA",        "Nsigma deviations from PSF to CF", "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "EXT_NSIGMA",       "Nsigma deviations from PSF to EXT", "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_MAJOR",        "psf fit major axis",              "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_MINOR",        "psf fit minor axis",              "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_THETA",        "ellipse angle",                   "degrees",           1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_CORE",         "extra PSF parameter",             "unitless",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_FWHM_MAJ",     "true fwhm of psf",                "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_FWHM_MIN",     "true fwhm (minor)",               "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_QF",           "quality factor",                  "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_QF_PERFECT",   "quality factor perfect",          "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "J",    "PSF_NDOF",         "psf degrees of freedom",          "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "J",    "PSF_NPIX",         "psf number of pixels",            "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_XX",       "second moment X",                 "pixels^2",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_XY",       "second moment Y",                 "pixels^2",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_YY",       "second moment XY",                "pixels^2",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_M3C",      "third moment cos(t)",             "pixels^3",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_M3S",      "third moment sin(t)",             "pixels^3",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_M4C",      "fourth moment cos(t)",            "pixels^4",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_M4S",      "fourth moment sin(t)",            "pixels^4",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "X11_SM_OBJ",       "lensing smear",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "X12_SM_OBJ",       "lensing smear",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "X22_SM_OBJ",       "lensing smear",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "E1_SM_OBJ",        "lensing smear",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "E2_SM_OBJ",        "lensing smear",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "X11_SH_OBJ",       "lensing shear",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "X12_SH_OBJ",       "lensing shear",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "X22_SH_OBJ",       "lensing shear",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "E1_SH_OBJ",        "lensing shear",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "E2_SH_OBJ",        "lensing shear",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "X11_SM_PSF",       "lensing smear",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "X12_SM_PSF",       "lensing smear",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "X22_SM_PSF",       "lensing smear",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "E1_SM_PSF",        "lensing smear",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "E2_SM_PSF",        "lensing smear",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "X11_SH_PSF",       "lensing shear",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "X12_SH_PSF",       "lensing shear",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "X22_SH_PSF",       "lensing shear",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "E1_SH_PSF",        "lensing shear",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "E2_SH_PSF",        "lensing shear",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_R1",       "first radial moment",             "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_RH",       "half radial moment",              "pixels^1/2",        1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "KRON_FLUX",        "kron flux",                       "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "KRON_FLUX_ERR",    "kron flux error",                 "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "KRON_FLUX_INNER",  "kron flux 1<R<2.5",               "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "KRON_FLUX_OUTER",  "kron flux 2.5<R<4",               "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "SKY_LIMIT_RAD",    "profile to sky limit (radius)",   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "SKY_LIMIT_FLUX",   "profile to sky limit (flux)",     "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "SKY_LIMIT_SLOPE",  "profile to sky limit (slope)",    "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "J",    "FLAGS",            "analysis flags",                  "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "J",    "FLAGS2",           "analysis flags (2)",              "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "I",    "N_FRAMES",         "images overlapping peak",         "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "I",    "PADDING",          "padding for 8byte records",       "",                  1.0, 0.0);
+
+  /* create table */
+  if (!gfits_create_table (header, ftable)) return (FALSE);
+
+  /* add data values */
+  if (!gfits_table_scale_data (ftable)) return (FALSE);
+  if (!gfits_convert_CMF_PS1_V5_Lensing ((unsigned char *) data, sizeof (CMF_PS1_V5_Lensing), Ndata, FALSE)) return (FALSE);
+  if (!gfits_add_rows (ftable, (char *) data, Ndata, sizeof (CMF_PS1_V5_Lensing))) return (FALSE);
+
+  return (TRUE);
+}
+
+int gfits_table_mkheader_CMF_PS1_V5_Lensing (Header *header) {
+
+  /* create table header */
+  if (!gfits_create_table_header (header, "BINTABLE", "CMF_PS1_V5_Lensing")) return (FALSE);
+
+  /* define table layout */
+  /** TABLE DEFINITION **/
+  gfits_define_bintable_column (header, "J",    "IPP_IDET",         "detection ID                     ", "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "X_PSF",            "x coord",                         "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "Y_PSF",            "y coord",                         "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "X_PSF_SIG",        "x coord error",                   "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "Y_PSF_SIG",        "y coord error",                   "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "POSANGLE",         "Posangle at source",              "degrees",           1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PLTSCALE",         "Plate Scale at source",           "arcsec/pixel",      1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_INST_MAG",     "inst mags",                       "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_INST_MAG_SIG", "inst mag error",                  "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_INST_FLUX",    "psf flux",                        "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_INST_FLUX_SIG", "psf flux error",                  "counts      ",      1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "AP_MAG",           "standard aperture mag",           "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "AP_MAG_RAW",       "raw aperture mag",                "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "AP_MAG_RADIUS",    "radius used for aper",            "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "AP_FLUX",          "aperture flux",                   "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "AP_FLUX_SIG",      "error on ap flux",                "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "J",    "AP_NPIX",          "pixels used by aper",             "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "CAL_PSF_MAG",      "calibrated psf mag",              "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "CAL_PSF_MAG_SIG",  "zero point scatter",              "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PEAK_FLUX_AS_MAG", "peak flux as a mag",              "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "D",    "RA_PSF",           "PSF RA coord",                    "degrees",           1.0, 0.0);
+  gfits_define_bintable_column (header, "D",    "DEC_PSF",          "PSF DEC coord",                   "degrees",           1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "SKY",              "sky flux",                        "cnts/sec",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "SKY_SIGMA",        "sky flux error",                  "cnts/sec",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_CHISQ",        "psf fit chisq",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "CR_NSIGMA",        "Nsigma deviations from PSF to CF", "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "EXT_NSIGMA",       "Nsigma deviations from PSF to EXT", "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_MAJOR",        "psf fit major axis",              "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_MINOR",        "psf fit minor axis",              "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_THETA",        "ellipse angle",                   "degrees",           1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_CORE",         "extra PSF parameter",             "unitless",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_FWHM_MAJ",     "true fwhm of psf",                "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_FWHM_MIN",     "true fwhm (minor)",               "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_QF",           "quality factor",                  "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_QF_PERFECT",   "quality factor perfect",          "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "J",    "PSF_NDOF",         "psf degrees of freedom",          "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "J",    "PSF_NPIX",         "psf number of pixels",            "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_XX",       "second moment X",                 "pixels^2",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_XY",       "second moment Y",                 "pixels^2",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_YY",       "second moment XY",                "pixels^2",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_M3C",      "third moment cos(t)",             "pixels^3",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_M3S",      "third moment sin(t)",             "pixels^3",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_M4C",      "fourth moment cos(t)",            "pixels^4",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_M4S",      "fourth moment sin(t)",            "pixels^4",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "X11_SM_OBJ",       "lensing smear",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "X12_SM_OBJ",       "lensing smear",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "X22_SM_OBJ",       "lensing smear",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "E1_SM_OBJ",        "lensing smear",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "E2_SM_OBJ",        "lensing smear",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "X11_SH_OBJ",       "lensing shear",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "X12_SH_OBJ",       "lensing shear",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "X22_SH_OBJ",       "lensing shear",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "E1_SH_OBJ",        "lensing shear",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "E2_SH_OBJ",        "lensing shear",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "X11_SM_PSF",       "lensing smear",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "X12_SM_PSF",       "lensing smear",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "X22_SM_PSF",       "lensing smear",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "E1_SM_PSF",        "lensing smear",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "E2_SM_PSF",        "lensing smear",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "X11_SH_PSF",       "lensing shear",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "X12_SH_PSF",       "lensing shear",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "X22_SH_PSF",       "lensing shear",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "E1_SH_PSF",        "lensing shear",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "E2_SH_PSF",        "lensing shear",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_R1",       "first radial moment",             "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_RH",       "half radial moment",              "pixels^1/2",        1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "KRON_FLUX",        "kron flux",                       "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "KRON_FLUX_ERR",    "kron flux error",                 "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "KRON_FLUX_INNER",  "kron flux 1<R<2.5",               "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "KRON_FLUX_OUTER",  "kron flux 2.5<R<4",               "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "SKY_LIMIT_RAD",    "profile to sky limit (radius)",   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "SKY_LIMIT_FLUX",   "profile to sky limit (flux)",     "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "SKY_LIMIT_SLOPE",  "profile to sky limit (slope)",    "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "J",    "FLAGS",            "analysis flags",                  "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "J",    "FLAGS2",           "analysis flags (2)",              "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "I",    "N_FRAMES",         "images overlapping peak",         "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "I",    "PADDING",          "padding for 8byte records",       "",                  1.0, 0.0);
+
+  return (TRUE);
+}
+
+int Send_CMF_PS1_V5_Lensing (int device, CMF_PS1_V5_Lensing *data, int Ndata, int copy) {
+
+  int Nwrite, Nbytes;
+  CMF_PS1_V5_Lensing *tmpdata;
+
+  Nbytes = Ndata * sizeof (CMF_PS1_V5_Lensing);
+
+  if (copy) {
+    ALLOCATE (tmpdata, CMF_PS1_V5_Lensing, Ndata);
+    memcpy (tmpdata, data, Nbytes);
+  } else {
+    tmpdata = data;
+  }
+
+  if (!gfits_convert_CMF_PS1_V5_Lensing ((unsigned char *) tmpdata, sizeof (CMF_PS1_V5_Lensing), Ndata, FALSE)) return (FALSE);
+
+  SendCommand (device, 16, "NVALUE: %6d", Ndata);
+  SendCommand (device, 16, "NBYTES: %6d", Nbytes);
+  Nwrite = write (device, tmpdata, Nbytes);
+  if (Nwrite != Nbytes) {
+    return (FALSE);
+  }
+  
+  /* perform handshaking? */
+
+  return (TRUE);
+}
+
+int Recv_CMF_PS1_V5_Lensing (int device, CMF_PS1_V5_Lensing **data, int *Ndata) {
+
+  int ndata;
+  IOBuffer message;
+  CMF_PS1_V5_Lensing *tmpdata;
+
+  ExpectCommand (device, 16, 1.0, &message);
+  sscanf (message.buffer, "%*s %d", &ndata);
+  FreeIOBuffer (&message);
+  
+  /* what is reasonable for timeout? */
+  ExpectMessage (device, 1.0, &message);
+  
+  tmpdata = (CMF_PS1_V5_Lensing *) message.buffer;
+  if (!gfits_convert_CMF_PS1_V5_Lensing ((unsigned char *) tmpdata, sizeof (CMF_PS1_V5_Lensing), ndata, TRUE)) return (FALSE);
+
+  /* double-check data length? */
+  /* perform handshaking? */
+
+  *Ndata = ndata;
+  *data = tmpdata;
+
+  return (TRUE);
+}
+
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/cmf-ps1-v5.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/cmf-ps1-v5.c	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/cmf-ps1-v5.c	(revision 37403)
@@ -0,0 +1,395 @@
+# include "dvo.h"
+
+// this function is based on the one generated by the autocode of cmf-ps1-v5.d
+int gfits_convert_CMF_PS1_V5 (unsigned char *data, off_t size, off_t nitems, char toStruct) {
+
+  off_t i;
+  unsigned char tmp;
+
+  if (size != 232) { 
+    fprintf (stderr, "WARNING: mismatch in data types CMF_PS1_V5: "OFF_T_FMT" vs %d\n",  size,  232);
+    return (FALSE);
+  }
+
+  /* provide initial values to avoid compiler warnings for non-BYTE_SWAP arch */
+  i = tmp = 0;
+
+  // allocate a temporary output 
+  unsigned char tmpdata[64];
+
+  // move the bytes corresponding to PEAK_FLUX_AS_MAG, RA_PSF, DEC_PSF
+  if (toStruct) {
+    unsigned char *row = data;
+    for (i = 0; i < nitems; i++, row += size) {
+      memcpy  (tmpdata, &row[92], 4); // save PEAK_FLUX_AS_MAG (92-95)
+      memmove (&row[80], &row[76], 16); // move RA_PSF & DEC_PSF
+      memcpy  (&row[76], tmpdata, 4); // replace PEAK_FLUX_AS_MAG
+    }
+  }
+
+  // after we have moved around PEAK_FLUX_AS_MAG, RA_PSF, DEC_PSF, we can swap as needed for this platform
+  unsigned char *byte = data;
+
+# ifdef BYTE_SWAP
+  byte = (unsigned char *) data;
+  for (i = 0; i < nitems; i++, byte += 232) {
+    /** BYTE SWAP **/
+    SWAP_WORD (0); // IPP_IDET                     
+    SWAP_WORD (4); // X_PSF
+    SWAP_WORD (8); // Y_PSF
+    SWAP_WORD (12); // X_PSF_SIG
+    SWAP_WORD (16); // Y_PSF_SIG
+    SWAP_WORD (20); // POSANGLE
+    SWAP_WORD (24); // PLTSCALE
+    SWAP_WORD (28); // PSF_INST_MAG
+    SWAP_WORD (32); // PSF_INST_MAG_SIG
+    SWAP_WORD (36); // PSF_INST_FLUX
+    SWAP_WORD (40); // PSF_INST_FLUX_SIG
+    SWAP_WORD (44); // AP_MAG
+    SWAP_WORD (48); // AP_MAG_RAW
+    SWAP_WORD (52); // AP_MAG_RADIUS
+    SWAP_WORD (56); // AP_FLUX
+    SWAP_WORD (60); // AP_FLUX_SIG
+    SWAP_WORD (64); // AP_NPIX
+    SWAP_WORD (68); // CAL_PSF_MAG
+    SWAP_WORD (72); // CAL_PSF_MAG_SIG
+    SWAP_WORD (76); // PEAK_FLUX_AS_MAG
+    SWAP_DBLE (80); // RA_PSF
+    SWAP_DBLE (88); // DEC_PSF
+    SWAP_WORD (96); // SKY
+    SWAP_WORD (100); // SKY_SIGMA
+    SWAP_WORD (104); // PSF_CHISQ
+    SWAP_WORD (108); // CR_NSIGMA
+    SWAP_WORD (112); // EXT_NSIGMA
+    SWAP_WORD (116); // PSF_MAJOR
+    SWAP_WORD (120); // PSF_MINOR
+    SWAP_WORD (124); // PSF_THETA
+    SWAP_WORD (128); // PSF_CORE
+    SWAP_WORD (132); // PSF_FWHM_MAJ
+    SWAP_WORD (136); // PSF_FWHM_MIN
+    SWAP_WORD (140); // PSF_QF
+    SWAP_WORD (144); // PSF_QF_PERFECT
+    SWAP_WORD (148); // PSF_NDOF
+    SWAP_WORD (152); // PSF_NPIX
+    SWAP_WORD (156); // MOMENTS_XX
+    SWAP_WORD (160); // MOMENTS_XY
+    SWAP_WORD (164); // MOMENTS_YY
+    SWAP_WORD (168); // MOMENTS_M3C
+    SWAP_WORD (172); // MOMENTS_M3S
+    SWAP_WORD (176); // MOMENTS_M4C
+    SWAP_WORD (180); // MOMENTS_M4S
+    SWAP_WORD (184); // MOMENTS_R1
+    SWAP_WORD (188); // MOMENTS_RH
+    SWAP_WORD (192); // KRON_FLUX
+    SWAP_WORD (196); // KRON_FLUX_ERR
+    SWAP_WORD (200); // KRON_FLUX_INNER
+    SWAP_WORD (204); // KRON_FLUX_OUTER
+    SWAP_WORD (208); // SKY_LIMIT_RAD
+    SWAP_WORD (212); // SKY_LIMIT_FLUX
+    SWAP_WORD (216); // SKY_LIMIT_SLOPE
+    SWAP_WORD (220); // FLAGS
+    SWAP_WORD (224); // FLAGS2
+    SWAP_BYTE (228); // N_FRAMES
+    SWAP_BYTE (230); // PADDING
+  }
+# endif  
+
+  // move the bytes corresponding to PEAK_FLUX_AS_MAG, RA_PSF, DEC_PSF
+  if (!toStruct) {
+    unsigned char *row = data;
+    for (i = 0; i < nitems; i++, row += size) {
+      memcpy  (tmpdata, &row[76], 4); // save PEAK_FLUX_AS_MAG (92-95)
+      memmove (&row[76], &row[80], 16); // move RA_PSF & DEC_PSF
+      memcpy  (&row[92], tmpdata, 4); // replace PEAK_FLUX_AS_MAG
+    }
+  }
+
+  return (TRUE);
+} 
+
+// data organization (input vs output)
+//                FITS               struct
+// WORD   (0); // IPP_IDET           IPP_IDET           / 1J                  
+// WORD   (4); // X_PSF              X_PSF              / 1E                  
+// WORD   (8); // Y_PSF              Y_PSF              / 1E                  
+// WORD  (12); // X_PSF_SIG          X_PSF_SIG          / 1E                  
+// WORD  (16); // Y_PSF_SIG          Y_PSF_SIG          / 1E                  
+// WORD  (20); // POSANGLE           POSANGLE           / 1E                  
+// WORD  (24); // PLTSCALE           PLTSCALE           / 1E                  
+// WORD  (28); // PSF_INST_MAG       PSF_INST_MAG       / 1E                  
+// WORD  (32); // PSF_INST_MAG_SIG   PSF_INST_MAG_SIG   / 1E                  
+// WORD  (36); // PSF_INST_FLUX      PSF_INST_FLUX      / 1E                  
+// WORD  (40); // PSF_INST_FLUX_SIG  PSF_INST_FLUX_SIG  / 1E                  
+// WORD  (44); // AP_MAG             AP_MAG             / 1E                  
+// WORD  (48); // AP_MAG_RAW         AP_MAG_RAW         / 1E                  
+// WORD  (52); // AP_MAG_RADIUS      AP_MAG_RADIUS      / 1E                  
+// WORD  (56); // AP_FLUX            AP_FLUX            / 1E                  
+// WORD  (60); // AP_FLUX_SIG        AP_FLUX_SIG        / 1E                  
+// WORD  (64); // AP_NPIX            AP_NPIX            / 1J                  
+// WORD  (68); // CAL_PSF_MAG        CAL_PSF_MAG        / 1E                  
+// WORD  (72); // CAL_PSF_MAG_SIG    CAL_PSF_MAG_SIG    / 1E                  
+// WORD  (76); // PEAK_FLUX_AS_MAG   RA_PSF             / 1D                  
+// DBLE  (80); // RA_PSF             DEC_PSF            / 1D                  
+// DBLE  (88); // DEC_PSF            PEAK_FLUX_AS_MAG   / 1E                  
+// WORD  (96); // SKY                SKY                / 1E                  
+// WORD (100); // SKY_SIGMA          SKY_SIGMA          / 1E                  
+// WORD (104); // PSF_CHISQ          PSF_CHISQ          / 1E                  
+// WORD (108); // CR_NSIGMA          CR_NSIGMA          / 1E                  
+// WORD (112); // EXT_NSIGMA         EXT_NSIGMA         / 1E                  
+// WORD (116); // PSF_MAJOR          PSF_MAJOR          / 1E                  
+// WORD (120); // PSF_MINOR          PSF_MINOR          / 1E                  
+// WORD (124); // PSF_THETA          PSF_THETA          / 1E                  
+// WORD (128); // PSF_CORE           PSF_CORE           / 1E                  
+// WORD (132); // PSF_FWHM_MAJ       PSF_FWHM_MAJ       / 1E                  
+// WORD (136); // PSF_FWHM_MIN       PSF_FWHM_MIN       / 1E                  
+// WORD (140); // PSF_QF             PSF_QF             / 1E                  
+// WORD (144); // PSF_QF_PERFECT     PSF_QF_PERFECT     / 1E                  
+// WORD (148); // PSF_NDOF           PSF_NDOF           / 1J                  
+// WORD (152); // PSF_NPIX           PSF_NPIX           / 1J                  
+// WORD (156); // MOMENTS_XX         MOMENTS_XX         / 1E                  
+// WORD (160); // MOMENTS_XY         MOMENTS_XY         / 1E                  
+// WORD (164); // MOMENTS_YY         MOMENTS_YY         / 1E                  
+// WORD (168); // MOMENTS_M3C        MOMENTS_M3C        / 1E                  
+// WORD (172); // MOMENTS_M3S        MOMENTS_M3S        / 1E                  
+// WORD (176); // MOMENTS_M4C        MOMENTS_M4C        / 1E                  
+// WORD (180); // MOMENTS_M4S        MOMENTS_M4S        / 1E                  
+// WORD (184); // MOMENTS_R1         MOMENTS_R1         / 1E                  
+// WORD (188); // MOMENTS_RH         MOMENTS_RH         / 1E                  
+// WORD (192); // KRON_FLUX          KRON_FLUX          / 1E                  
+// WORD (196); // KRON_FLUX_ERR      KRON_FLUX_ERR      / 1E                  
+// WORD (200); // KRON_FLUX_INNER    KRON_FLUX_INNER    / 1E                  
+// WORD (204); // KRON_FLUX_OUTER    KRON_FLUX_OUTER    / 1E                  
+// WORD (208); // SKY_LIMIT_RAD      SKY_LIMIT_RAD      / 1E                  
+// WORD (212); // SKY_LIMIT_FLUX     SKY_LIMIT_FLUX     / 1E                  
+// WORD (216); // SKY_LIMIT_SLOPE    SKY_LIMIT_SLOPE    / 1E                  
+// WORD (220); // FLAGS              FLAGS              / 1J                  
+// WORD (224); // FLAGS2             FLAGS2             / 1J                  
+// BYTE (228); // N_FRAMES           N_FRAMES           / 1I                  
+// BYTE (230); // PADDING            PADDING            / 1I                  
+
+/*** add test of EXTNAME and header-defined columns? ***/
+/* return internal structure representation */
+CMF_PS1_V5 *gfits_table_get_CMF_PS1_V5 (FTable *ftable, off_t *Ndata, char *swapped) {
+
+  int Ncols;
+  CMF_PS1_V5 *data;
+
+  Ncols = ftable[0].header[0].Naxis[0];
+  if (Ncols != 232) {
+    fprintf (stderr, "ERROR: mis-match in table size: width is %d but should be %d bytes\n", Ncols, 232);
+    return NULL;
+  }
+
+  *Ndata = ftable[0].header[0].Naxis[1];
+  data = (CMF_PS1_V5 *) ftable[0].buffer;
+  if ((swapped == NULL) || (*swapped == FALSE)) {
+    if (!gfits_convert_CMF_PS1_V5 ((unsigned char *) data, sizeof (CMF_PS1_V5), *Ndata, TRUE)) {
+      return NULL;
+    }
+    gfits_table_scale_data (ftable);
+    if (swapped != NULL) *swapped = TRUE;
+  }
+  return (data);
+}
+
+int gfits_table_set_CMF_PS1_V5 (FTable *ftable, CMF_PS1_V5 *data, off_t Ndata) {
+
+  Header *header;
+
+  header = ftable[0].header;
+
+  /* create table header */
+  if (!gfits_create_table_header (header, "BINTABLE", "CMF_PS1_V5")) return (FALSE);
+
+  /* define table layout */
+  /** TABLE DEFINITION **/
+  gfits_define_bintable_column (header, "J",    "IPP_IDET",         "detection ID                     ", "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "X_PSF",            "x coord",                         "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "Y_PSF",            "y coord",                         "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "X_PSF_SIG",        "x coord error",                   "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "Y_PSF_SIG",        "y coord error",                   "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "POSANGLE",         "Posangle at source",              "degrees",           1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PLTSCALE",         "Plate Scale at source",           "arcsec/pixel",      1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_INST_MAG",     "inst mags",                       "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_INST_MAG_SIG", "inst mag error",                  "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_INST_FLUX",    "psf flux",                        "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_INST_FLUX_SIG", "psf flux error",                  "counts      ",      1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "AP_MAG",           "standard aperture mag",           "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "AP_MAG_RAW",       "raw aperture mag",                "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "AP_MAG_RADIUS",    "radius used for aper",            "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "AP_FLUX",          "aperture flux",                   "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "AP_FLUX_SIG",      "error on ap flux",                "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "J",    "AP_NPIX",          "pixels used by aper",             "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "CAL_PSF_MAG",      "calibrated psf mag",              "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "CAL_PSF_MAG_SIG",  "zero point scatter",              "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "D",    "RA_PSF",           "PSF RA coord",                    "degrees",           1.0, 0.0);
+  gfits_define_bintable_column (header, "D",    "DEC_PSF",          "PSF DEC coord",                   "degrees",           1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PEAK_FLUX_AS_MAG", "peak flux as a mag",              "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "SKY",              "sky flux",                        "cnts/sec",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "SKY_SIGMA",        "sky flux error",                  "cnts/sec",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_CHISQ",        "psf fit chisq",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "CR_NSIGMA",        "Nsigma deviations from PSF to CF", "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "EXT_NSIGMA",       "Nsigma deviations from PSF to EXT", "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_MAJOR",        "psf fit major axis",              "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_MINOR",        "psf fit minor axis",              "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_THETA",        "ellipse angle",                   "degrees",           1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_CORE",         "extra PSF parameter",             "unitless",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_FWHM_MAJ",     "true fwhm of psf",                "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_FWHM_MIN",     "true fwhm (minor)",               "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_QF",           "quality factor",                  "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_QF_PERFECT",   "quality factor perfect",          "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "J",    "PSF_NDOF",         "psf degrees of freedom",          "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "J",    "PSF_NPIX",         "psf number of pixels",            "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_XX",       "second moment X",                 "pixels^2",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_XY",       "second moment Y",                 "pixels^2",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_YY",       "second moment XY",                "pixels^2",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_M3C",      "third moment cos(t)",             "pixels^3",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_M3S",      "third moment sin(t)",             "pixels^3",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_M4C",      "fourth moment cos(t)",            "pixels^4",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_M4S",      "fourth moment sin(t)",            "pixels^4",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_R1",       "first radial moment",             "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_RH",       "half radial moment",              "pixels^1/2",        1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "KRON_FLUX",        "kron flux",                       "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "KRON_FLUX_ERR",    "kron flux error",                 "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "KRON_FLUX_INNER",  "kron flux 1<R<2.5",               "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "KRON_FLUX_OUTER",  "kron flux 2.5<R<4",               "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "SKY_LIMIT_RAD",    "profile to sky limit (radius)",   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "SKY_LIMIT_FLUX",   "profile to sky limit (flux)",     "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "SKY_LIMIT_SLOPE",  "profile to sky limit (slope)",    "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "J",    "FLAGS",            "analysis flags",                  "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "J",    "FLAGS2",           "analysis flags (2)",              "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "I",    "N_FRAMES",         "images overlapping peak",         "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "I",    "PADDING",          "padding for 8byte records",       "",                  1.0, 0.0);
+
+  /* create table */
+  if (!gfits_create_table (header, ftable)) return (FALSE);
+
+  /* add data values */
+  if (!gfits_table_scale_data (ftable)) return (FALSE);
+  if (!gfits_convert_CMF_PS1_V5 ((unsigned char *) data, sizeof (CMF_PS1_V5), Ndata, FALSE)) return (FALSE);
+  if (!gfits_add_rows (ftable, (char *) data, Ndata, sizeof (CMF_PS1_V5))) return (FALSE);
+
+  return (TRUE);
+}
+
+int gfits_table_mkheader_CMF_PS1_V5 (Header *header) {
+
+  /* create table header */
+  if (!gfits_create_table_header (header, "BINTABLE", "CMF_PS1_V5")) return (FALSE);
+
+  /* define table layout */
+  /** TABLE DEFINITION **/
+  gfits_define_bintable_column (header, "J",    "IPP_IDET",         "detection ID                     ", "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "X_PSF",            "x coord",                         "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "Y_PSF",            "y coord",                         "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "X_PSF_SIG",        "x coord error",                   "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "Y_PSF_SIG",        "y coord error",                   "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "POSANGLE",         "Posangle at source",              "degrees",           1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PLTSCALE",         "Plate Scale at source",           "arcsec/pixel",      1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_INST_MAG",     "inst mags",                       "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_INST_MAG_SIG", "inst mag error",                  "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_INST_FLUX",    "psf flux",                        "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_INST_FLUX_SIG", "psf flux error",                  "counts      ",      1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "AP_MAG",           "standard aperture mag",           "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "AP_MAG_RAW",       "raw aperture mag",                "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "AP_MAG_RADIUS",    "radius used for aper",            "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "AP_FLUX",          "aperture flux",                   "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "AP_FLUX_SIG",      "error on ap flux",                "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "J",    "AP_NPIX",          "pixels used by aper",             "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "CAL_PSF_MAG",      "calibrated psf mag",              "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "CAL_PSF_MAG_SIG",  "zero point scatter",              "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PEAK_FLUX_AS_MAG", "peak flux as a mag",              "mags",              1.0, 0.0);
+  gfits_define_bintable_column (header, "D",    "RA_PSF",           "PSF RA coord",                    "degrees",           1.0, 0.0);
+  gfits_define_bintable_column (header, "D",    "DEC_PSF",          "PSF DEC coord",                   "degrees",           1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "SKY",              "sky flux",                        "cnts/sec",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "SKY_SIGMA",        "sky flux error",                  "cnts/sec",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_CHISQ",        "psf fit chisq",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "CR_NSIGMA",        "Nsigma deviations from PSF to CF", "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "EXT_NSIGMA",       "Nsigma deviations from PSF to EXT", "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_MAJOR",        "psf fit major axis",              "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_MINOR",        "psf fit minor axis",              "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_THETA",        "ellipse angle",                   "degrees",           1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_CORE",         "extra PSF parameter",             "unitless",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_FWHM_MAJ",     "true fwhm of psf",                "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_FWHM_MIN",     "true fwhm (minor)",               "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_QF",           "quality factor",                  "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PSF_QF_PERFECT",   "quality factor perfect",          "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "J",    "PSF_NDOF",         "psf degrees of freedom",          "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "J",    "PSF_NPIX",         "psf number of pixels",            "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_XX",       "second moment X",                 "pixels^2",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_XY",       "second moment Y",                 "pixels^2",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_YY",       "second moment XY",                "pixels^2",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_M3C",      "third moment cos(t)",             "pixels^3",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_M3S",      "third moment sin(t)",             "pixels^3",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_M4C",      "fourth moment cos(t)",            "pixels^4",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_M4S",      "fourth moment sin(t)",            "pixels^4",          1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_R1",       "first radial moment",             "pixels",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MOMENTS_RH",       "half radial moment",              "pixels^1/2",        1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "KRON_FLUX",        "kron flux",                       "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "KRON_FLUX_ERR",    "kron flux error",                 "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "KRON_FLUX_INNER",  "kron flux 1<R<2.5",               "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "KRON_FLUX_OUTER",  "kron flux 2.5<R<4",               "counts",            1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "SKY_LIMIT_RAD",    "profile to sky limit (radius)",   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "SKY_LIMIT_FLUX",   "profile to sky limit (flux)",     "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "SKY_LIMIT_SLOPE",  "profile to sky limit (slope)",    "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "J",    "FLAGS",            "analysis flags",                  "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "J",    "FLAGS2",           "analysis flags (2)",              "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "I",    "N_FRAMES",         "images overlapping peak",         "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "I",    "PADDING",          "padding for 8byte records",       "",                  1.0, 0.0);
+
+  return (TRUE);
+}
+
+int Send_CMF_PS1_V5 (int device, CMF_PS1_V5 *data, int Ndata, int copy) {
+
+  int Nwrite, Nbytes;
+  CMF_PS1_V5 *tmpdata;
+
+  Nbytes = Ndata * sizeof (CMF_PS1_V5);
+
+  if (copy) {
+    ALLOCATE (tmpdata, CMF_PS1_V5, Ndata);
+    memcpy (tmpdata, data, Nbytes);
+  } else {
+    tmpdata = data;
+  }
+
+  if (!gfits_convert_CMF_PS1_V5 ((unsigned char *) tmpdata, sizeof (CMF_PS1_V5), Ndata, FALSE)) return (FALSE);
+
+  SendCommand (device, 16, "NVALUE: %6d", Ndata);
+  SendCommand (device, 16, "NBYTES: %6d", Nbytes);
+  Nwrite = write (device, tmpdata, Nbytes);
+  if (Nwrite != Nbytes) {
+    return (FALSE);
+  }
+  
+  /* perform handshaking? */
+
+  return (TRUE);
+}
+
+int Recv_CMF_PS1_V5 (int device, CMF_PS1_V5 **data, int *Ndata) {
+
+  int ndata;
+  IOBuffer message;
+  CMF_PS1_V5 *tmpdata;
+
+  ExpectCommand (device, 16, 1.0, &message);
+  sscanf (message.buffer, "%*s %d", &ndata);
+  FreeIOBuffer (&message);
+  
+  /* what is reasonable for timeout? */
+  ExpectMessage (device, 1.0, &message);
+  
+  tmpdata = (CMF_PS1_V5 *) message.buffer;
+  if (!gfits_convert_CMF_PS1_V5 ((unsigned char *) tmpdata, sizeof (CMF_PS1_V5), ndata, TRUE)) return (FALSE);
+
+  /* double-check data length? */
+  /* perform handshaking? */
+
+  *Ndata = ndata;
+  *data = tmpdata;
+
+  return (TRUE);
+}
+
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dbExtractAverages.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dbExtractAverages.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dbExtractAverages.c	(revision 37403)
@@ -52,6 +52,5 @@
 dbValue dbExtractAverages (Average *average, SecFilt *secfilt, Measure *measure, dbField *field) {
 
-  off_t i;
-  int Nsec;
+  // off_t i;
   dbValue value;
 
@@ -162,4 +161,7 @@
       value.Flt = average[0].stargal;
       break;
+    case AVE_REF_COLOR:
+      value.Flt = average[0].refColorBlue;
+      break;
 
     case AVE_OBJ_FLAGS:
@@ -179,19 +181,26 @@
       break;
 
-    case AVE_MAG:
-      switch (field->magMode) {
-	case MAG_AVE:
-	  value.Flt = PhotAve  (field->photcode, average, secfilt);
-	  break;
-	case MAG_REF:
-	  value.Flt = PhotRef  (field->photcode, average, secfilt, measure);
-	  break;
-	case MAG_INST:
-	case MAG_CAT:
-	case MAG_SYS:
-	case MAG_REL:
-	case MAG_CAL:
-	  // XXX need to code this correctly: this returns just the first matching value
-	  value.Flt = NAN;
+    case AVE_PHOT:
+      // if we request mag:ave, use equiv for photcode (ie a given measure, say GPC1.g.XY01, will return g for mag:ave)
+      if  (field->photcode->type == PHOT_MAG) {
+	// this is an error
+	break;
+      }
+
+      // if we ask for 2MASS_K, etc (REF values), return NAN unless measure->code matches
+      if (field->photcode->type == PHOT_REF) {
+	// need to ensure measure exists.
+	break;
+      }
+
+      // if we ask for GPC1.g.XY03:rel, etc (DEP values), return NAN unless measure->code matches
+      if (field->photcode->type == PHOT_DEP) {
+	// again.
+	break;
+      }
+
+      /* in some cases below we need a measurement which matches the requested photcode.
+	 here is some sample code to find this.
+
 	  for (i = 0; i < average[0].Nmeasure; i++) {
 	    if (field->photcode->code != measure[i].photcode) continue;
@@ -199,103 +208,116 @@
 	    break;
 	  }
-	  break;
-	case MAG_CHISQ:
+      */
+
+      switch (field->magOption) {
+	case MAG_OPTION_MAG:
+	  switch (field->magLevel) {
+	    case MAG_LEVEL_AVE:
+	      value.Flt = PhotAve  (field->photcode, average, secfilt, field->magClass, field->magSource); 
+	      break;
+	    case MAG_LEVEL_REF:
+	      // which measure is needed here?
+	      // PhotRef  (field->photcode, average, secfilt, measure, field->magClass, field->magSource); 
+	      break;
+	    case MAG_LEVEL_INST:
+	    case MAG_LEVEL_CAT:
+	    case MAG_LEVEL_SYS:
+	    case MAG_LEVEL_REL:
+	    case MAG_LEVEL_CAL:
+	    case MAG_LEVEL_NONE:
+	      break;
+	  }
+	  break;
+
+	case MAG_OPTION_ERR:
+	  switch (field->magLevel) {
+	    case MAG_LEVEL_AVE:
+	    case MAG_LEVEL_REF:
+	      value.Flt = PhotAveErr (field->photcode, average, secfilt, field->magClass, field->magSource);  
+	      break;
+	    case MAG_LEVEL_INST:
+	    case MAG_LEVEL_CAT:
+	    case MAG_LEVEL_SYS:
+	    case MAG_LEVEL_REL:
+	    case MAG_LEVEL_CAL:
+	    case MAG_LEVEL_NONE:
+	      break;
+	  }
+	  break;
+
+	case MAG_OPTION_FLUX:
+	  switch (field->magLevel) {
+	    case MAG_LEVEL_AVE:
+	      value.Flt = PhotFluxAve  (field->photcode, average, secfilt, field->magClass, field->magSource); 
+	      break;
+	    case MAG_LEVEL_REF:
+	      // XXX which measure is needed here?
+	      // value.Flt = PhotFluxRef  (field->photcode, average, secfilt, measure, field->magClass, field->magSource); 
+	      break;
+	    case MAG_LEVEL_INST:
+	    case MAG_LEVEL_CAT:
+	    case MAG_LEVEL_SYS:
+	    case MAG_LEVEL_REL:
+	    case MAG_LEVEL_CAL:
+	    case MAG_LEVEL_NONE:
+	      break;
+	  }
+	  break;
+
+	case MAG_OPTION_FLUX_ERR:
+	  switch (field->magLevel) {
+	    case MAG_LEVEL_AVE:
+	    case MAG_LEVEL_REF:
+	      value.Flt = PhotFluxAveErr (field->photcode, average, secfilt, field->magClass, field->magSource);  
+	      break;
+	    case MAG_LEVEL_INST:
+	    case MAG_LEVEL_CAT:
+	    case MAG_LEVEL_SYS:
+	    case MAG_LEVEL_REL:
+	    case MAG_LEVEL_CAL:
+	    case MAG_LEVEL_NONE:
+	      break;
+	  }
+	  break;
+
+	case MAG_OPTION_STDEV:
+	  value.Flt = PhotMstdev (field->photcode, average, secfilt, field->magClass, field->magSource);
+	  break;
+	case MAG_OPTION_CHISQ:
 	  value.Flt = PhotXm (field->photcode, average, secfilt);
 	  break;
-	case MAG_ERR:
-	  if ((field->photcode->type == PHOT_REF) || (field->photcode->type == PHOT_DEP)) {
-	    for (i = 0; i < average[0].Nmeasure; i++) {
-	      if (field->photcode->code != measure[i].photcode) continue;
-	      value.Flt = measure[i].dM;
-	      break;
-	    }
-	  } else {
-	    value.Flt = PhotAveErr (field->photcode, average, secfilt);
-	  }
-	  break;
-	case MAG_STDEV:
-	  value.Flt = PhotMstdev (field->photcode, average, secfilt);
-	  break;
-	case MAG_PHOT_FLAGS:
-	  if ((field->photcode->type == PHOT_REF) || (field->photcode->type == PHOT_DEP)) {
-	    for (i = 0; i < average[0].Nmeasure; i++) {
-	      if (field->photcode->code != measure[i].photcode) continue;
-	      value.Int = measure[i].photFlags;
-	      break;
-	    }
-	  } else {
-	    Nsec = GetPhotcodeNsec (field->photcode->code);
-	    if (Nsec == -1) break;
-	    value.Int = secfilt[Nsec].flags;
-	  }
-	  break;
-	case MAG_NCODE:
-	  // XXX push these into dvo_photcode_ops APIs
-	  // XXX do I need to allow for conversion to equiv?
-	  Nsec = GetPhotcodeNsec (field->photcode->code);
+	case MAG_OPTION_MIN:
+	  value.Flt = PhotMmin (field->photcode, average, secfilt);
+	  break;
+	case MAG_OPTION_MAX:
+	  value.Flt = PhotMmax (field->photcode, average, secfilt);
+	  break;
+	case MAG_OPTION_NCODE: {
+	  int Nsec = GetPhotcodeNsec (field->photcode->code);
 	  if (Nsec == -1) break;
 	  value.Int = secfilt[Nsec].Ncode;
 	  break;
-	case MAG_NPHOT:
-	  Nsec = GetPhotcodeNsec (field->photcode->code);
+	}
+	case MAG_OPTION_NPHOT: {
+	  value.Int = PhotNphot (field->photcode, average, secfilt, field->magClass, field->magSource);
+	  break;
+	}
+	case MAG_OPTION_UC_DIST:
+	  value.Flt = PhotUCdist (field->photcode, average, secfilt);
+	  break;
+	// XX case MAG_OPTION_STACK_DET_ID:
+	// XX   value.Int = PhotStackID (field->photcode, average, secfilt);
+	// XX   break;
+	case MAG_OPTION_FLAGS: {
+	  int Nsec = GetPhotcodeNsec (field->photcode->code);
 	  if (Nsec == -1) break;
-	  value.Int = secfilt[Nsec].Nused;
-	  break;
-
-	case MAG_APER:
-	case MAG_APER_AVE:
-	  value.Flt = PhotAperAve (field->photcode, average, secfilt);
-	  break;
-
-	case MAG_APER_REF:
-	  value.Flt = PhotAperRef (field->photcode, average, secfilt, measure);
-	  break;
-
-	case MAG_KRON:
-	case MAG_KRON_AVE:
-	  value.Flt = PhotKronAve (field->photcode, average, secfilt);
-	  break;
-
-	case MAG_KRON_REF:
-	  value.Flt = PhotKronRef (field->photcode, average, secfilt, measure);
-	  break;
-
-	case MAG_KRON_ERR:
-	  value.Flt = PhotKronAveErr (field->photcode, average, secfilt);
-	  break;
-
-	case MAG_20:
-	  value.Flt = PhotM20 (field->photcode, average, secfilt);
-	  break;
-	case MAG_80:
-	  value.Flt = PhotM80 (field->photcode, average, secfilt);
-	  break;
-	case MAG_UC_DIST:
-	  value.Flt = PhotUCdist (field->photcode, average, secfilt);
-	  break;
-	case MAG_STACK_DET_ID:
-	  value.Int = PhotStackID (field->photcode, average, secfilt);
-	  break;
-
-	case MAG_FLUX_PSF:
-	  value.Flt = PhotAveFluxPSF (field->photcode, average, secfilt);
-	  break;
-	case MAG_FLUX_PSF_ERR:
-	  value.Flt = PhotAvedFluxPSF (field->photcode, average, secfilt);
-	  break;
-	case MAG_FLUX_KRON:
-	  value.Flt = PhotAveFluxKron (field->photcode, average, secfilt);
-	  break;
-	case MAG_FLUX_KRON_ERR:
-	  value.Flt = PhotAvedFluxKron (field->photcode, average, secfilt);
-	  break;
-      }
-      break;
-    case AVE_dMAG:
-      value.Flt = PhotAveErr (field->photcode, average, secfilt);
-      break;
-    case AVE_Xm:
-      value.Flt = PhotXm (field->photcode, average, secfilt);
-      break;
+	  value.Int = secfilt[Nsec].flags;
+	  break;
+	}
+	case MAG_OPTION_NONE:
+	  break;
+      }
+      break;
+
     case AVE_TYPE:
       break;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dbExtractImages.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dbExtractImages.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dbExtractImages.c	(revision 37403)
@@ -69,6 +69,11 @@
       if (!haveCelestial) {
 	if (!FindMosaicForImage (image, Nimage, N)) return value;
-	x = 0.5*image[N].NX;
-	y = 0.5*image[N].NY;
+	if (!strcmp(&image[N].coords.ctype[4], "-DIS")) {
+	  x = 0.0;
+	  y = 0.0;
+	} else {
+	  x = 0.5*image[N].NX;
+	  y = 0.5*image[N].NY;
+	}
 	XY_to_RD (&RAo, &DECo, x, y, &image[N].coords);
 	haveCelestial = TRUE;
@@ -79,6 +84,11 @@
       if (!haveCelestial) {
 	if (!FindMosaicForImage (image, Nimage, N)) return value;
-	x = 0.5*image[N].NX;
-	y = 0.5*image[N].NY;
+	if (!strcmp(&image[N].coords.ctype[4], "-DIS")) {
+	  x = 0.0;
+	  y = 0.0;
+	} else {
+	  x = 0.5*image[N].NX;
+	  y = 0.5*image[N].NY;
+	}
 	XY_to_RD (&RAo, &DECo, x, y, &image[N].coords);
 	haveCelestial = TRUE;
@@ -90,6 +100,11 @@
 	if (!haveCelestial) {
 	  if (!FindMosaicForImage (image, Nimage, N)) return value;
-	  x = 0.5*image[N].NX;
-	  y = 0.5*image[N].NY;
+	  if (!strcmp(&image[N].coords.ctype[4], "-DIS")) {
+	    x = 0.0;
+	    y = 0.0;
+	  } else {
+	    x = 0.5*image[N].NX;
+	    y = 0.5*image[N].NY;
+	  }
 	  XY_to_RD (&RAo, &DECo, x, y, &image[N].coords);
 	  haveCelestial = TRUE;
@@ -104,6 +119,11 @@
 	if (!haveCelestial) {
 	  if (!FindMosaicForImage (image, Nimage, N)) return value;
-	  x = 0.5*image[N].NX;
-	  y = 0.5*image[N].NY;
+	  if (!strcmp(&image[N].coords.ctype[4], "-DIS")) {
+	    x = 0.0;
+	    y = 0.0;
+	  } else {
+	    x = 0.5*image[N].NX;
+	    y = 0.5*image[N].NY;
+	  }
 	  XY_to_RD (&RAo, &DECo, x, y, &image[N].coords);
 	  haveCelestial = TRUE;
@@ -118,6 +138,11 @@
 	if (!haveCelestial) {
 	  if (!FindMosaicForImage (image, Nimage, N)) return value;
-	  x = 0.5*image[N].NX;
-	  y = 0.5*image[N].NY;
+	  if (!strcmp(&image[N].coords.ctype[4], "-DIS")) {
+	    x = 0.0;
+	    y = 0.0;
+	  } else {
+	    x = 0.5*image[N].NX;
+	    y = 0.5*image[N].NY;
+	  }
 	  XY_to_RD (&RAo, &DECo, x, y, &image[N].coords);
 	  haveCelestial = TRUE;
@@ -132,6 +157,11 @@
 	if (!haveCelestial) {
 	  if (!FindMosaicForImage (image, Nimage, N)) return value;
-	  x = 0.5*image[N].NX;
-	  y = 0.5*image[N].NY;
+	  if (!strcmp(&image[N].coords.ctype[4], "-DIS")) {
+	    x = 0.0;
+	    y = 0.0;
+	  } else {
+	    x = 0.5*image[N].NX;
+	    y = 0.5*image[N].NY;
+	  }
 	  XY_to_RD (&RAo, &DECo, x, y, &image[N].coords);
 	  haveCelestial = TRUE;
@@ -344,4 +374,8 @@
       value.Int = image[N].nLinkAstrom;
       break;
+
+    case IMAGE_REF_COLOR:
+      value.Flt = image[N].refColorBlue;
+      break;
   }
   return (value);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dbExtractMeasures.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dbExtractMeasures.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dbExtractMeasures.c	(revision 37403)
@@ -90,4 +90,5 @@
   dbValue value;
   double dT;
+  float dR, dD;
 
   Coords *mosaic, *fieldc;
@@ -99,8 +100,8 @@
 
   switch (field->ID) {
-    case MEAS_MAG: { /* magnitudes are already determined above */
+    case MEAS_PHOT: { /* magnitudes are already determined above */
       PhotCode *myEquiv = GetPhotcodeEquivbyCode (measure[0].photcode);
 
-      // if we request mag:ave, use equiv for photcode
+      // if we request mag:ave, use equiv for photcode (ie a given measure, say GPC1.g.XY01, will return g for mag:ave)
       if  (field->photcode->type == PHOT_MAG) {
 	equiv = myEquiv;
@@ -116,28 +117,11 @@
       // if we ask for g:ave, or other SEC-level values, return the corresponding field 
       if (field->photcode->type == PHOT_SEC) {
-	switch (field->magMode) {
+	switch (field->magLevel) {
 	  // measure-like : return non-NAN if measure.equiv.photcode matches field.photcode
-	  case MAG_INST:
-	  case MAG_CAT:
-	  case MAG_SYS:
-	  case MAG_REL:
-	  case MAG_CAL:
-	  case MAG_ERR:
-
-	  case MAG_APER_INST:
-	  case MAG_APER_CAT:
-	  case MAG_APER_SYS:
-	  case MAG_APER_REL:
-	  case MAG_APER_CAL:
-	  case MAG_APER_ERR:
-
-	  case MAG_KRON_INST:
-	  case MAG_KRON_CAT:
-	  case MAG_KRON_SYS:
-	  case MAG_KRON_REL:
-	  case MAG_KRON_CAL:
-	  case MAG_KRON_ERR:
-
-	  case MAG_PHOT_FLAGS:
+	  case MAG_LEVEL_INST:
+	  case MAG_LEVEL_CAT:
+	  case MAG_LEVEL_SYS:
+	  case MAG_LEVEL_REL:
+	  case MAG_LEVEL_CAL:
 	    equiv = myEquiv;
 	    if (equiv && (equiv->code == field->photcode->code)) goto valid_photcode;
@@ -145,25 +129,6 @@
 
 	    // mean-like : return value for the given photcode
-	  case MAG_AVE:
-	  case MAG_REF:
-	  case MAG_STDEV:
-	  case MAG_AVE_ERR:
-	  case MAG_CHISQ:
-	  case MAG_FLUX_PSF:
-	  case MAG_FLUX_PSF_ERR:
-
-	  case MAG_APER_AVE:
-
-	  case MAG_KRON_AVE:
-	  case MAG_FLUX_KRON:
-	  case MAG_FLUX_KRON_ERR:
-
-	  case MAG_20:
-	  case MAG_80:
-	  case MAG_UC_DIST:
-	  case MAG_STACK_DET_ID:
-
-	  case MAG_NCODE:
-	  case MAG_NPHOT:
+	  case MAG_LEVEL_AVE:
+	  case MAG_LEVEL_REF:
 	    equiv = field->photcode;
 	    goto valid_photcode;
@@ -177,131 +142,112 @@
 
   valid_photcode:
-      switch (field->magMode) {
-	case MAG_INST:
-	  value.Flt = PhotInst (measure);  
-	  break;
-	case MAG_CAT:
-	  value.Flt = PhotCat  (measure); 
-	  break;
-	case MAG_SYS:
-	  value.Flt = PhotSys  (measure, average, secfilt); 
-	  break;
-	case MAG_REL:
-	  value.Flt = PhotRel  (measure, average, secfilt); 
-	  break;
-	case MAG_CAL:
-	  value.Flt = PhotCal  (measure, average, secfilt, measure, equiv); 
-	  break;
-	case MAG_AVE:
-	  value.Flt = PhotAve  (equiv, average, secfilt); 
-	  break;
-	case MAG_REF:
-	  value.Flt = PhotRef  (equiv, average, secfilt, measure); 
-	  break;
-	case MAG_ERR:
-	  value.Flt = measure[0].dM;
-	  break;
-	case MAG_AVE_ERR:
-	  value.Flt = PhotAveErr  (equiv, average, secfilt); 
-	  break;
-
-	case MAG_APER_INST:
-	  value.Flt = PhotAperInst (measure); 
-	  break;
-	case MAG_APER_CAT:
-	  value.Flt = PhotAperCat (measure); 
-	  break;
-	case MAG_APER_SYS:
-	  value.Flt = PhotAperSys (measure, average, secfilt); 
-	  break;
-	case MAG_APER:
-	case MAG_APER_REL:
-	  value.Flt = PhotAperRel (measure, average, secfilt); 
-	  break;
-	case MAG_APER_CAL:
-	  value.Flt = PhotAperCal (measure, average, secfilt, measure, equiv); 
-	  break;
-	case MAG_APER_AVE:
-	  value.Flt = PhotAperAve (equiv, average, secfilt);
-	  break;
-	case MAG_APER_REF:
-	  value.Flt = PhotAperRef (equiv, average, secfilt, measure); 
-	  break;
-	case MAG_APER_ERR:
-	  value.Flt = measure[0].dM;
-	  break;
-
-	case MAG_KRON_INST:
-	  value.Flt = PhotKronInst (measure); 
-	  break;
-	case MAG_KRON_CAT:
-	  value.Flt = PhotKronCat (measure); 
-	  break;
-	case MAG_KRON_SYS:
-	  value.Flt = PhotKronSys (measure, average, secfilt); 
-	  break;
-	case MAG_KRON:
-	case MAG_KRON_REL:
-	  value.Flt = PhotKronRel (measure, average, secfilt); 
-	  break;
-	case MAG_KRON_CAL:
-	  value.Flt = PhotKronCal (measure, average, secfilt, measure, equiv); 
-	  break;
-	case MAG_KRON_AVE:
-	  value.Flt = PhotKronAve (equiv, average, secfilt);
-	  break;
-	case MAG_KRON_REF:
-	  value.Flt = PhotKronRef (equiv, average, secfilt, measure); 
-	  break;
-	case MAG_KRON_ERR:
-	  value.Flt = measure[0].dMkron;
-	  break;
-
-	case MAG_PHOT_FLAGS:
-	  if ((field->photcode->type == PHOT_REF) || (field->photcode->type == PHOT_DEP)) {
-	    value.Int = measure[0].photFlags;
+      switch (field->magOption) {
+	case MAG_OPTION_MAG:
+	  switch (field->magLevel) {
+	    case MAG_LEVEL_INST:
+	      value.Flt = PhotInst (measure, field->magClass);  
+	      break;
+	    case MAG_LEVEL_CAT:
+	      value.Flt = PhotCat  (measure, field->magClass); 
+	      break;
+	    case MAG_LEVEL_SYS:
+	      value.Flt = PhotSys  (measure, average, secfilt, field->magClass); 
+	      break;
+	    case MAG_LEVEL_REL:
+	      value.Flt = PhotRel  (measure, average, secfilt, field->magClass); 
+	      break;
+	    case MAG_LEVEL_CAL:
+	      value.Flt = PhotCal  (measure, average, secfilt, measure, equiv, field->magClass); 
+	      break;
+	    case MAG_LEVEL_AVE:
+	      value.Flt = PhotAve  (equiv, average, secfilt, field->magClass, field->magSource); 
+	      break;
+	    case MAG_LEVEL_REF:
+	      value.Flt = PhotRef  (equiv, average, secfilt, measure, field->magClass, field->magSource); 
+	      break;
+	    case MAG_LEVEL_NONE:
+	      break;
 	  }
 	  break;
 
-	case MAG_NCODE:
-	  if (equiv == NULL) break;
-	  Nsec = GetPhotcodeNsec (equiv->code);
-	  if (Nsec == -1) break;
-	  value.Int = secfilt[Nsec].Ncode;
+	case MAG_OPTION_ERR:
+	  switch (field->magLevel) {
+	    case MAG_LEVEL_INST:
+	    case MAG_LEVEL_CAT:
+	    case MAG_LEVEL_SYS:
+	    case MAG_LEVEL_REL:
+	      value.Flt = PhotErr (measure, field->magClass);  
+	      break;
+	    case MAG_LEVEL_CAL:
+	      value.Flt = PhotCalErr (measure, field->magClass);  
+	      break;
+	    case MAG_LEVEL_AVE:
+	    case MAG_LEVEL_REF:
+	      value.Flt = PhotAveErr (equiv, average, secfilt, field->magClass, field->magSource);  
+	      break;
+	    case MAG_LEVEL_NONE:
+	      break;
+	  }
 	  break;
-	case MAG_NPHOT:
-	  if (equiv == NULL) break;
-	  Nsec = GetPhotcodeNsec (equiv->code);
-	  if (Nsec == -1) break;
-	  value.Int = secfilt[Nsec].Nused;
+
+	case MAG_OPTION_FLUX:
+	  switch (field->magLevel) {
+	    case MAG_LEVEL_INST:
+	      value.Flt = PhotFluxInst (measure, field->magClass);  
+	      break;
+	    case MAG_LEVEL_CAT:
+	      value.Flt = PhotFluxCat  (measure, field->magClass); 
+	      break;
+	    case MAG_LEVEL_SYS:
+	      value.Flt = PhotFluxSys  (measure, average, secfilt, field->magClass); 
+	      break;
+	    case MAG_LEVEL_REL:
+	      value.Flt = PhotFluxRel  (measure, average, secfilt, field->magClass); 
+	      break;
+	    case MAG_LEVEL_CAL:
+	      value.Flt = PhotFluxCal  (measure, average, secfilt, measure, equiv, field->magClass); 
+	      break;
+	    case MAG_LEVEL_AVE:
+	      value.Flt = PhotFluxAve  (equiv, average, secfilt, field->magClass, field->magSource); 
+	      break;
+	    case MAG_LEVEL_REF:
+	      value.Flt = PhotFluxRef  (equiv, average, secfilt, measure, field->magClass, field->magSource); 
+	      break;
+	    case MAG_LEVEL_NONE:
+	      break;
+	  }
 	  break;
 
-	case MAG_CHISQ:
-	  value.Flt = PhotXm (equiv, average, secfilt); 
+	case MAG_OPTION_FLUX_ERR:
+	  switch (field->magLevel) {
+	    case MAG_LEVEL_INST:
+	      value.Flt = PhotFluxInstErr (measure, field->magClass);  
+	      break;
+	    case MAG_LEVEL_CAT:
+	      value.Flt = PhotFluxCatErr (measure, field->magClass);  
+	      break;
+	    case MAG_LEVEL_SYS:
+	    case MAG_LEVEL_REL:
+	    case MAG_LEVEL_CAL:
+	      // value.Flt = PhotFluxErr (measure, field->magClass);  
+	      break;
+	    case MAG_LEVEL_AVE:
+	    case MAG_LEVEL_REF:
+	      // value.Flt = PhotFluxAveErr (equiv, average, secfilt, field->magClass, field->magSource);  
+	      break;
+	    case MAG_LEVEL_NONE:
+	      break;
+	  }
 	  break;
-	case MAG_STDEV:
-	  value.Flt = PhotMstdev (equiv, average, secfilt);
-	  break;
-	case MAG_20:
-	  value.Flt = PhotM20 (equiv, average, secfilt);
-	  break;
-	case MAG_80:
-	  value.Flt = PhotM80 (equiv, average, secfilt);
-	  break;
-	case MAG_UC_DIST:
-	  value.Flt = PhotUCdist (equiv, average, secfilt); 
-	  break;
-
-	case MAG_FLUX_PSF:
-	  value.Flt = PhotAveFluxPSF (field->photcode, average, secfilt);
-	  break;
-	case MAG_FLUX_PSF_ERR:
-	  value.Flt = PhotAvedFluxPSF (field->photcode, average, secfilt);
-	  break;
-	case MAG_FLUX_KRON:
-	  value.Flt = PhotAveFluxKron (field->photcode, average, secfilt);
-	  break;
-	case MAG_FLUX_KRON_ERR:
-	  value.Flt = PhotAvedFluxKron (field->photcode, average, secfilt);
+
+	case MAG_OPTION_STDEV:
+	case MAG_OPTION_CHISQ:
+	case MAG_OPTION_MIN:
+	case MAG_OPTION_MAX:
+	case MAG_OPTION_NCODE:
+	case MAG_OPTION_NPHOT:
+	case MAG_OPTION_UC_DIST:
+	case MAG_OPTION_FLAGS:
+	case MAG_OPTION_NONE:
 	  break;
       }
@@ -309,8 +255,8 @@
     }
     case MEAS_RA: /* OK */
-      value.Flt = average[0].R - measure[0].dR / 3600.0;
+      value.Flt = measure[0].R;
       break;
     case MEAS_DEC: /* OK */
-      value.Flt = average[0].D - measure[0].dD / 3600.0;
+      value.Flt = measure[0].D;
       break;
     case MEAS_RA_AVE: /* OK */
@@ -323,5 +269,5 @@
     case MEAS_GLON:
       if (!haveGalacticMeas) {
-	ApplyTransform (&GLON_MEAS, &GLAT_MEAS, average[0].R - measure[0].dR / 3600.0, average[0].D - measure[0].dD / 3600.0, celestial_to_galactic);
+	ApplyTransform (&GLON_MEAS, &GLAT_MEAS, measure[0].R, measure[0].D, celestial_to_galactic);
 	haveGalacticMeas = TRUE;
       }
@@ -330,5 +276,5 @@
     case MEAS_GLAT:
       if (!haveGalacticMeas) {
-	ApplyTransform (&GLON_MEAS, &GLAT_MEAS, average[0].R - measure[0].dR / 3600.0, average[0].D - measure[0].dD / 3600.0, celestial_to_galactic);
+	ApplyTransform (&GLON_MEAS, &GLAT_MEAS, measure[0].R, measure[0].D, celestial_to_galactic);
 	haveGalacticMeas = TRUE;
       }
@@ -337,5 +283,5 @@
     case MEAS_ELON:
       if (!haveEclipticMeas) {
-	ApplyTransform (&ELON_MEAS, &ELAT_MEAS, average[0].R - measure[0].dR / 3600.0, average[0].D - measure[0].dD / 3600.0, celestial_to_ecliptic);
+	ApplyTransform (&ELON_MEAS, &ELAT_MEAS, measure[0].R, measure[0].D, celestial_to_ecliptic);
 	haveEclipticMeas = TRUE;
       }
@@ -344,5 +290,5 @@
     case MEAS_ELAT:
       if (!haveEclipticMeas) {
-	ApplyTransform (&ELON_MEAS, &ELAT_MEAS, average[0].R - measure[0].dR / 3600.0, average[0].D - measure[0].dD / 3600.0, celestial_to_ecliptic);
+	ApplyTransform (&ELON_MEAS, &ELAT_MEAS, measure[0].R, measure[0].D, celestial_to_ecliptic);
 	haveEclipticMeas = TRUE;
       }
@@ -441,16 +387,18 @@
     // the error.
     case MEAS_RA_OFFSET: /* OK */
-      value.Flt = measure[0].dR;
+      value.Flt = dvoOffsetR (measure, average);
       break;
     case MEAS_DEC_OFFSET: /* OK */
-      value.Flt = measure[0].dD;
+      value.Flt = dvoOffsetD (measure, average);
       break;
     case MEAS_RA_FIT_OFFSET: /* OK */
       dT = (measure[0].t - average[0].Tmean) / (86400*365.25);
-      value.Flt = average[0].uR * dT + measure[0].dR;
+      dR = dvoOffsetR (measure, average);
+      value.Flt = average[0].uR * dT + dR;
       break;
     case MEAS_DEC_FIT_OFFSET: /* OK */
       dT = (measure[0].t - average[0].Tmean) / (86400*365.25);
-      value.Flt = average[0].uD * dT + measure[0].dD;
+      dD = dvoOffsetD (measure, average);
+      value.Flt = average[0].uD * dT + dD;
       break;
     case MEAS_RA_OFFSET_ERR: /* OK */
@@ -524,4 +472,8 @@
     case MEAS_PLATESCALE: /* OK */
       value.Flt = measure[0].pltscale;
+      break;
+
+    case MEAS_REF_COLOR:
+      value.Flt = average[0].refColorBlue;
       break;
 
@@ -552,6 +504,6 @@
 	// measure.xccd if we need it
 	Image *image;
-	ra  = average[0].R - measure[0].dR / 3600.0;
-	dec = average[0].D - measure[0].dD / 3600.0;
+	ra  = measure[0].R;
+	dec = measure[0].D;
 	image = MatchImageDVO (measure[0].t, measure[0].photcode, measure[0].imageID);
 	if (image == NULL) break;
@@ -567,6 +519,6 @@
       {
 	Image *image;
-	ra  = average[0].R - measure[0].dR / 3600.0;
-	dec = average[0].D - measure[0].dD / 3600.0;
+	ra  = measure[0].R;
+	dec = measure[0].D;
 	image = MatchImageDVO (measure[0].t, measure[0].photcode, measure[0].imageID);
 	if (image == NULL) break;
@@ -603,6 +555,6 @@
 	}
 	if (fieldc == NULL) break;
-	double Rm = average[0].R - measure[0].dR / 3600.0;
-	double Dm = average[0].D - measure[0].dD / 3600.0;
+	double Rm = measure[0].R;
+	double Dm = measure[0].D;
 	RD_to_XY (&XFIELD_MEAS, &YFIELD_MEAS, Rm, Dm, fieldc);
       }
@@ -620,6 +572,6 @@
 	}
 	if (fieldc == NULL) break;
-	double Rm = average[0].R - measure[0].dR / 3600.0;
-	double Dm = average[0].D - measure[0].dD / 3600.0;
+	double Rm = measure[0].R;
+	double Dm = measure[0].D;
 	RD_to_XY (&XFIELD_MEAS, &YFIELD_MEAS, Rm, Dm, fieldc);
       }
@@ -638,6 +590,6 @@
 	}
 	if (mosaic == NULL) break;
-	double Rm = average[0].R - measure[0].dR / 3600.0;
-	double Dm = average[0].D - measure[0].dD / 3600.0;
+	double Rm = measure[0].R;
+	double Dm = measure[0].D;
 	RD_to_XY (&XMOS_MEAS, &YMOS_MEAS, Rm, Dm, mosaic);
       }
@@ -655,6 +607,6 @@
 	}
 	if (mosaic == NULL) break;
-	double Rm = average[0].R - measure[0].dR / 3600.0;
-	double Dm = average[0].D - measure[0].dD / 3600.0;
+	double Rm = measure[0].R;
+	double Dm = measure[0].D;
 	RD_to_XY (&XMOS_MEAS, &YMOS_MEAS, Rm, Dm, mosaic);
       }
@@ -694,7 +646,4 @@
     case MEAS_PSF_NPIX: /* OK */
       value.Int = measure[0].psfNpix;
-      break;
-    case MEAS_CR_NSIGMA: /* OK */
-      value.Flt = measure[0].crNsigma;
       break;
     case MEAS_EXT_NSIGMA: /* OK */
@@ -769,16 +718,16 @@
       break;
 
-    case MEAS_FLUX_PSF: /* OK */
-      value.Flt = measure[0].FluxPSF;
-      break;
-    case MEAS_FLUX_PSF_ERR: /* OK */
-      value.Flt = measure[0].dFluxPSF;
-      break;
-    case MEAS_FLUX_KRON: /* OK */
-      value.Flt = measure[0].FluxKron;
-      break;
-    case MEAS_FLUX_KRON_ERR: /* OK */
-      value.Flt = measure[0].dFluxKron;
-      break;
+    // case MEAS_FLUX_PSF: /* OK */
+    //   value.Flt = measure[0].FluxPSF;
+    //   break;
+    // case MEAS_FLUX_PSF_ERR: /* OK */
+    //   value.Flt = measure[0].dFluxPSF;
+    //   break;
+    // case MEAS_FLUX_KRON: /* OK */
+    //   value.Flt = measure[0].FluxKron;
+    //   break;
+    // case MEAS_FLUX_KRON_ERR: /* OK */
+    //   value.Flt = measure[0].dFluxKron;
+    //   break;
   }
   return (value);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dbFields.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dbFields.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dbFields.c	(revision 37403)
@@ -9,9 +9,4 @@
   for (i = 0; i < Nfields; i++) {
     if (fields[i].name != NULL) free (fields[i].name);
-    if (fields[i].photcode != NULL) {
-      if (fields[i].photcode[0].type == PHOT_MAG) {
-        free (fields[i].photcode);
-      }
-    }
   }
   free (fields);
@@ -24,8 +19,69 @@
   field->ID = 0;
   field->type = OPIHI_FLT;
-  field->magMode = 0;
+
+  field->magSource = MAG_SRC_NONE;
+  field->magLevel  = MAG_LEVEL_NONE;
+  field->magClass  = MAG_CLASS_NONE;
+  field->magOption = MAG_OPTION_NONE;
+
   field->photcode = NULL;
 }
 
+dvoMagSourceType GetMagSource (char *string) {
+
+  if (!strcasecmp (string, "chip")) return (MAG_SRC_CHP);
+  if (!strcasecmp (string, "warp")) return (MAG_SRC_WRP);
+  if (!strcasecmp (string, "stack")) return (MAG_SRC_STK);
+
+  if (!strcasecmp (string, "chp")) return (MAG_SRC_CHP);
+  if (!strcasecmp (string, "wrp")) return (MAG_SRC_WRP);
+  if (!strcasecmp (string, "stk")) return (MAG_SRC_STK);
+
+  return MAG_SRC_NONE;
+}
+
+dvoMagLevelType GetMagLevel (char *string) {
+
+  if (!strcasecmp (string, "inst")) return (MAG_LEVEL_INST);
+  if (!strcasecmp (string, "cat"))  return (MAG_LEVEL_CAT);
+  if (!strcasecmp (string, "sys"))  return (MAG_LEVEL_SYS);
+  if (!strcasecmp (string, "rel"))  return (MAG_LEVEL_REL);
+  if (!strcasecmp (string, "cal"))  return (MAG_LEVEL_CAL);
+  if (!strcasecmp (string, "ave"))  return (MAG_LEVEL_AVE);
+  if (!strcasecmp (string, "ref"))  return (MAG_LEVEL_REF);
+
+  return MAG_LEVEL_NONE;
+}
+
+dvoMagClassType GetMagClass (char *string) {
+
+  if (!strcasecmp (string, "psf"))   return (MAG_CLASS_PSF);
+  if (!strcasecmp (string, "kron"))  return (MAG_CLASS_KRON);
+  if (!strcasecmp (string, "aper"))  return (MAG_CLASS_APER);
+  if (!strcasecmp (string, "ap"))    return (MAG_CLASS_APER);
+
+  return MAG_CLASS_NONE;
+}
+
+dvoMagOptionType GetMagOption (char *string) {
+
+  if (!strcasecmp (string, "mag"))          return (MAG_OPTION_MAG);
+  if (!strcasecmp (string, "err"))          return (MAG_OPTION_ERR);
+  if (!strcasecmp (string, "magerr"))       return (MAG_OPTION_ERR);
+  if (!strcasecmp (string, "flux"))         return (MAG_OPTION_FLUX);
+  if (!strcasecmp (string, "fluxerr"))      return (MAG_OPTION_FLUX_ERR);
+  if (!strcasecmp (string, "stdev"))        return (MAG_OPTION_STDEV);
+  if (!strcasecmp (string, "chisq"))        return (MAG_OPTION_CHISQ);
+  if (!strcasecmp (string, "min"))          return (MAG_OPTION_MIN);
+  if (!strcasecmp (string, "max"))          return (MAG_OPTION_MAX);
+  if (!strcasecmp (string, "ncode"))        return (MAG_OPTION_NCODE);
+  if (!strcasecmp (string, "nphot"))        return (MAG_OPTION_NPHOT);
+  if (!strcasecmp (string, "uc_dist"))      return (MAG_OPTION_UC_DIST);
+  if (!strcasecmp (string, "flags"))        return (MAG_OPTION_FLAGS);
+
+  return MAG_OPTION_NONE;
+}
+
+# if (0)
 int GetMagMode (char *string) {
 
@@ -85,8 +141,7 @@
   if (!strcasecmp (string, "nphot"))       return (MAG_NPHOT);
   if (!strcasecmp (string, "stdev"))       return (MAG_STDEV);
-  if (!strcasecmp (string, "20"))          return (MAG_20);
-  if (!strcasecmp (string, "80"))          return (MAG_80);
+  if (!strcasecmp (string, "min"))         return (MAG_MIN);
+  if (!strcasecmp (string, "max"))         return (MAG_MAX);
   if (!strcasecmp (string, "ucdist"))      return (MAG_UC_DIST);
-  if (!strcasecmp (string, "stackDetectID")) return (MAG_STACK_DET_ID);
   if (!strcasecmp (string, "fluxpsf"))     return (MAG_FLUX_PSF);
   if (!strcasecmp (string, "fluxpsferr"))  return (MAG_FLUX_PSF_ERR);
@@ -95,215 +150,151 @@
   return (MAG_NONE);
 }
-
-PhotCode *ParsePhotcodeField (char *field, int *mode, int defMode) {
-
-  int useDefault;
-  char *tmpstring, *p;
-  PhotCode *code;
-
-  *mode = defMode;
-  useDefault = TRUE;
-
-  p = strchr (field, ':');
-  if (p != NULL) {
-    *mode = GetMagMode (p + 1);
-    useDefault = FALSE;
-    if (*mode == MAG_NONE) return (NULL);
-    tmpstring = strncreate (field, p - field);
-  } else {
-    tmpstring = strcreate (field);
-  }
-  if (!strcasecmp (tmpstring, "MAG")) {
-    ALLOCATE (code, PhotCode, 1);
-    code[0].code = 0;
-    strcpy (code[0].name, "MAG");
-    code[0].type = PHOT_MAG;
-    // the field call 'mag' is only valid for mextract
-    // it should default to REL, but other types should default to AVE
-    if (useDefault) {
-      *mode = MAG_REL;
+# endif
+
+// field may be of the form mag:psf:inst:wrp.  except for the first subword, 
+// the words may be in any order
+int ParsePhotcodeField (dbField *field, char *fieldName, int fieldID) {
+
+  int j;
+
+  // defaults:
+  field->ID = fieldID; // change if not true in the end?
+
+  // check what options are provided.  do not allow duplicate types
+  // except mag and flux may exist with err
+  dvoMagSourceType mySource = MAG_SRC_NONE;
+  dvoMagLevelType myLevel = MAG_LEVEL_NONE;
+  dvoMagClassType myClass = MAG_CLASS_NONE;
+  dvoMagOptionType myOption = MAG_OPTION_NONE;
+
+  field->magSource = MAG_SRC_CHP;
+  field->magLevel  = MAG_LEVEL_AVE;
+  field->magClass  = MAG_CLASS_PSF;
+  field->magOption = MAG_OPTION_MAG;
+
+  // make a local working copy of fieldName and replace ':' with spaces
+  char *fieldCopy = strcreate(fieldName);
+  for (j = 0; fieldCopy[j]; j++) { 
+    if (fieldCopy[j] == ':') fieldCopy[j] = ' '; 
+  }
+
+  char *firstWord = getword(fieldCopy);
+  
+  // firstWord may be either flux, mag or photcode
+  if (!strcasecmp (firstWord, "MAG")) {
+    // default level for 'mag' is rel
+    field->magLevel  = MAG_LEVEL_REL;
+    myOption = MAG_OPTION_MAG;
+  } 
+  if (!strcasecmp (firstWord, "FLUX")) {
+    // default level for 'flux' is rel
+    field->magLevel  = MAG_LEVEL_REL;
+    myOption = MAG_OPTION_FLUX;
+  } 
+  PhotCode *code = GetPhotcodebyName (firstWord);
+  free (firstWord);
+
+  if (!code) return FALSE;
+
+  // defaults for photcode clases
+  if (code->type == PHOT_DEP) {
+    field->magLevel = MAG_LEVEL_REL;
+  }
+  if (code->type == PHOT_SEC) {
+    field->magLevel = MAG_LEVEL_AVE;
+  }
+  if (code->type == PHOT_REF) {
+    field->magLevel = MAG_LEVEL_CAT;
+    // is this one required?
+  }
+  
+  // look at the remaining words and assign properties as approrpiate
+  char *ptr = skipword(fieldCopy);
+  while (ptr) {
+
+    char *word = getword(ptr);
+    if (!word) break;
+    
+    dvoMagSourceType source = GetMagSource (word);
+    if (source != MAG_SRC_NONE) {
+      if (mySource != MAG_SRC_NONE) { fprintf (stderr, "invalid selection %s in %s\n", word, fieldName); free (word); return FALSE; } 
+      mySource = source;
+      ptr = skipword (ptr);
+      continue;
     }
-    free (tmpstring);
-    return (code);
-  }
-  code = GetPhotcodebyName (tmpstring);
-  if (!code) {
-      return NULL;
-  }
-
-  // enforce compatibility
-  if (useDefault) {
-    if (code[0].type == PHOT_REF) {
-      *mode = MAG_CAT;
+
+    dvoMagLevelType level = GetMagLevel (word);
+    if (level != MAG_LEVEL_NONE) {
+      if (myLevel != MAG_LEVEL_NONE) { fprintf (stderr, "invalid selection %s in %s\n", word, fieldName); free (word); return FALSE; } 
+      myLevel = level;
+      ptr = skipword (ptr);
+      continue;
     }
-    if (code[0].type == PHOT_DEP) {
-      *mode = MAG_REL;
+
+    dvoMagClassType class = GetMagClass (word);
+    if (class != MAG_CLASS_NONE) {
+      if (myClass != MAG_CLASS_NONE) { fprintf (stderr, "invalid selection %s in %s\n", word, fieldName); free (word); return FALSE; } 
+      myClass = class;
+      ptr = skipword (ptr);
+      continue;
     }
-  } 
-  free (tmpstring);
-  return (code);
-}
-
-# define ESCAPE(F,M,T) { \
-  field->ID = (F); \
-  field->magMode = (M); \
-  field->type = (T); \
-  field->photcode = NULL; \
-  return (TRUE); }
-
-int ParseMeasureField (dbField *field, char *fieldName) {
-
-  int mode;
-  PhotCode *code;
-
-  field->table = DVO_TABLE_MEASURE;
-  field->name  = strcreate (fieldName);
-
-  if (!strcasecmp (fieldName, "GLON"))       {
-    dbExtractMeasuresInitTransform (COORD_GALACTIC);
-    ESCAPE (MEAS_GLON, MAG_NONE, OPIHI_FLT);
-  }
-  if (!strcasecmp (fieldName, "GLAT")) {
-    dbExtractMeasuresInitTransform (COORD_GALACTIC);
-    ESCAPE (MEAS_GLAT, MAG_NONE, OPIHI_FLT);
-  }
-  if (!strcasecmp (fieldName, "GLON:AVE")) {
-    dbExtractMeasuresInitTransform (COORD_GALACTIC);
-    ESCAPE (MEAS_GLON_AVE, MAG_NONE, OPIHI_FLT);
-  }
-  if (!strcasecmp (fieldName, "GLAT:AVE")) {
-    dbExtractMeasuresInitTransform (COORD_GALACTIC);
-    ESCAPE (MEAS_GLAT_AVE, MAG_NONE, OPIHI_FLT);
-  }
-
-  if (!strcasecmp (fieldName, "ELON"))       {
-    dbExtractMeasuresInitTransform (COORD_ECLIPTIC);
-    ESCAPE (MEAS_ELON, MAG_NONE, OPIHI_FLT);
-  }
-  if (!strcasecmp (fieldName, "ELAT")) {
-    dbExtractMeasuresInitTransform (COORD_ECLIPTIC);
-    ESCAPE (MEAS_ELAT, MAG_NONE, OPIHI_FLT);
-  }
-  if (!strcasecmp (fieldName, "ELON:AVE")) {
-    dbExtractMeasuresInitTransform (COORD_ECLIPTIC);
-    ESCAPE (MEAS_ELON_AVE, MAG_NONE, OPIHI_FLT);
-  }
-  if (!strcasecmp (fieldName, "ELAT:AVE")) {
-    dbExtractMeasuresInitTransform (COORD_ECLIPTIC);
-    ESCAPE (MEAS_ELAT_AVE, MAG_NONE, OPIHI_FLT);
-  }
-
-  if (!strcasecmp (fieldName, "RA"))         	 ESCAPE (MEAS_RA,             MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "DEC"))        	 ESCAPE (MEAS_DEC,            MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "RA:AVE"))     	 ESCAPE (MEAS_RA_AVE,         MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "DEC:AVE"))    	 ESCAPE (MEAS_DEC_AVE,        MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "RA:ERR"))     	 ESCAPE (MEAS_RA_AVE_ERR,     MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "DEC:ERR"))    	 ESCAPE (MEAS_DEC_AVE_ERR,    MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "uRA"))        	 ESCAPE (MEAS_U_RA,           MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "uDEC"))       	 ESCAPE (MEAS_U_DEC,          MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "duRA"))       	 ESCAPE (MEAS_U_RA_ERR,       MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "duDEC"))      	 ESCAPE (MEAS_U_DEC_ERR,      MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "PAR"))        	 ESCAPE (MEAS_PAR,            MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "dPAR"))       	 ESCAPE (MEAS_PAR_ERR,        MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "dR"))         	 ESCAPE (MEAS_RA_OFFSET,      MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "dD"))         	 ESCAPE (MEAS_DEC_OFFSET,     MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "dR:FIT"))     	 ESCAPE (MEAS_RA_FIT_OFFSET,  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "dD:FIT"))     	 ESCAPE (MEAS_DEC_FIT_OFFSET, MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "dR:ERR"))     	 ESCAPE (MEAS_RA_OFFSET_ERR,  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "dD:ERR"))     	 ESCAPE (MEAS_DEC_OFFSET_ERR, MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "ChiSqPos"))       ESCAPE (MEAS_CHISQ_POS,      MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "ChiSqPM"))        ESCAPE (MEAS_CHISQ_PM,       MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "ChiSqPar"))       ESCAPE (MEAS_CHISQ_PAR,      MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "Tmean"))          ESCAPE (MEAS_TMEAN,          MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "Trange"))         ESCAPE (MEAS_TRANGE,         MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "nmeas"))      	 ESCAPE (MEAS_NMEAS,          MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "nmiss"))      	 ESCAPE (MEAS_NMISS,          MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "npos"))      	 ESCAPE (MEAS_NPOS,           MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "OBJFLAGS"))   	 ESCAPE (MEAS_OBJ_FLAGS,      MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "OBJ_FLAGS"))   	 ESCAPE (MEAS_OBJ_FLAGS,      MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "OBJ_PHOT_FLAGS")) ESCAPE (MEAS_SECFILT_FLAGS,      MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "SECFLAGS"))   	 ESCAPE (MEAS_SECFILT_FLAGS,      MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "SEC_FLAGS"))   	 ESCAPE (MEAS_SECFILT_FLAGS,      MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "SECFILT_FLAGS"))  ESCAPE (MEAS_SECFILT_FLAGS,      MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "DB_FLAGS"))   	 ESCAPE (MEAS_DB_FLAGS,       MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "PHOT_FLAGS")) 	 ESCAPE (MEAS_PHOT_FLAGS,     MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "DBFLAGS"))   	 ESCAPE (MEAS_DB_FLAGS,       MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "PHOTFLAGS")) 	 ESCAPE (MEAS_PHOT_FLAGS,     MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "AIRMASS"))    	 ESCAPE (MEAS_AIRMASS,        MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "MEAN_AIRMASS"))   ESCAPE (MEAS_MEAN_AIRMASS,   MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "ALT"))        	 ESCAPE (MEAS_ALT,            MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "AZ"))         	 ESCAPE (MEAS_AZ,             MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "EXPTIME"))    	 ESCAPE (MEAS_EXPTIME,        MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "PHOTCODE"))   	 ESCAPE (MEAS_PHOTCODE,       MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "PHOTCODE:KLAM"))  ESCAPE (MEAS_PHOTCODE_KLAM,  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "PHOTCODE:C"))     ESCAPE (MEAS_PHOTCODE_C,     MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "PHOTCODE:EQUIV")) ESCAPE (MEAS_PHOTCODE_EQUIV, MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "TIME"))       	 ESCAPE (MEAS_TIME,           MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "FWHM"))       	 ESCAPE (MEAS_FWHM,           MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "FWHM_MAJ"))   	 ESCAPE (MEAS_FWHM_MAJ,       MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "FWHM_MIN"))   	 ESCAPE (MEAS_FWHM_MIN,       MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "THETA"))      	 ESCAPE (MEAS_THETA,          MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "POSANGLE"))     	 ESCAPE (MEAS_POSANGLE,       MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "PLATESCALE"))   	 ESCAPE (MEAS_PLATESCALE,     MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "MXX"))       	 ESCAPE (MEAS_MXX,            MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "MYY"))       	 ESCAPE (MEAS_MYY,            MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "MXY"))       	 ESCAPE (MEAS_MXY,            MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "DOPHOT"))     	 ESCAPE (MEAS_DOPHOT,         MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "XCCD"))       	 ESCAPE (MEAS_XCCD,           MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "YCCD"))       	 ESCAPE (MEAS_YCCD,           MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "XCCD:ERR"))   	 ESCAPE (MEAS_XCCD_ERR,       MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "YCCD:ERR"))   	 ESCAPE (MEAS_YCCD_ERR,       MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "XFIX"))       	 ESCAPE (MEAS_XFIX,           MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "YFIX"))       	 ESCAPE (MEAS_YFIX,           MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "POS_SYS_ERR"))    ESCAPE (MEAS_POS_SYS_ERR,    MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "XFIELD"))    	 ESCAPE (MEAS_XFIELD,         MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "YFIELD"))    	 ESCAPE (MEAS_YFIELD,         MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "XMOSAIC"))    	 ESCAPE (MEAS_XMOSAIC,        MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "YMOSAIC"))    	 ESCAPE (MEAS_YMOSAIC,        MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "XCHIP"))      	 ESCAPE (MEAS_XCCD,           MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "YCHIP"))      	 ESCAPE (MEAS_YCCD,           MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "XFPA"))       	 ESCAPE (MEAS_XMOSAIC,        MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "YFPA"))       	 ESCAPE (MEAS_YMOSAIC,        MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "DETID"))      	 ESCAPE (MEAS_DET_ID,         MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "OBJID"))      	 ESCAPE (MEAS_OBJ_ID,         MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "CATID"))      	 ESCAPE (MEAS_CAT_ID,         MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "IMAGEID"))    	 ESCAPE (MEAS_IMAGE_ID,       MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "EXTERNID"))    	 ESCAPE (MEAS_EXTERN_ID,      MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "EXPNAME"))    	 ESCAPE (MEAS_EXPNAME_AS_INT, MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "PSF_QF"))     	 ESCAPE (MEAS_PSF_QF,         MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "PSF_QF_PERFECT")) ESCAPE (MEAS_PSF_QF_PERFECT, MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "PSF_CHISQ"))  	 ESCAPE (MEAS_PSF_CHISQ,      MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "PSF_NDOF"))  	 ESCAPE (MEAS_PSF_NDOF,       MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "PSF_NPIX"))  	 ESCAPE (MEAS_PSF_NPIX,       MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "CR_NSIGMA"))  	 ESCAPE (MEAS_CR_NSIGMA,      MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "EXT_NSIGMA")) 	 ESCAPE (MEAS_EXT_NSIGMA,     MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "SKY"))        	 ESCAPE (MEAS_SKY,            MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "SKY_ERR"))    	 ESCAPE (MEAS_dSKY,           MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "MCAL_OFFSET"))    ESCAPE (MEAS_MCAL_OFFSET,    MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "FLAT"))    	 ESCAPE (MEAS_FLAT,           MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "CENTER_OFFSET"))  ESCAPE (MEAS_CENTER_OFFSET,  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "FLUX"))       	 ESCAPE (MEAS_FLUX_PSF,       MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "FLUX_ERR"))       ESCAPE (MEAS_FLUX_PSF_ERR,   MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "FLUX_PSF"))       ESCAPE (MEAS_FLUX_PSF,       MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "FLUX_PSF_ERR"))   ESCAPE (MEAS_FLUX_PSF_ERR,   MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "FLUX_KRON"))      ESCAPE (MEAS_FLUX_KRON,      MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "FLUX_KRON_ERR"))  ESCAPE (MEAS_FLUX_KRON_ERR,  MAG_NONE, OPIHI_FLT);
-
-  // for words that don't parse, try a photcode
-
-  // check for code:mode in photcode name 
-  code = ParsePhotcodeField (fieldName, &mode, MAG_AVE);
-  if (code == NULL) {
-    gprint (GP_ERR, "unknown field '%s' for measurement table in DVO database\n", fieldName);
-    return (FALSE);
-  }
-
-  field->ID = MEAS_MAG;
-  field->magMode = mode;
-  switch (mode) {
-    case MAG_STACK_DET_ID:
-    case MAG_NCODE:
-    case MAG_NPHOT:
-    case MAG_PHOT_FLAGS:
+
+    dvoMagOptionType option = GetMagOption (word);
+    if (option != MAG_OPTION_NONE) {
+      // some combinations are OK: mag + err -> err
+      if ((myOption == MAG_OPTION_MAG) && (option == MAG_OPTION_ERR)) {
+	myOption = option;
+	ptr = skipword (ptr);
+	continue;
+      }
+      // some combinations are OK: err + mag -> err
+      if ((myOption == MAG_OPTION_ERR) && (option == MAG_OPTION_MAG)) {
+	ptr = skipword (ptr);
+	continue;
+      }
+      // some combinations are OK: flux + err -> FLUX_ERR
+      if ((myOption == MAG_OPTION_FLUX) && (option == MAG_OPTION_ERR)) {
+	myOption = MAG_OPTION_FLUX_ERR;
+	ptr = skipword (ptr);
+	continue;
+      }
+      // some combinations are OK: err + flux -> FLUX_ERR
+      if ((myOption == MAG_OPTION_ERR) && (option == MAG_OPTION_FLUX)) {
+	myOption = MAG_OPTION_FLUX_ERR;
+	ptr = skipword (ptr);
+	continue;
+      }
+      // some combinations are OK: flux + fluxerr -> FLUX_ERR
+      if ((myOption == MAG_OPTION_FLUX) && (option == MAG_OPTION_FLUX_ERR)) {
+	myOption = MAG_OPTION_FLUX_ERR;
+	ptr = skipword (ptr);
+	continue;
+      }
+      // some combinations are OK: fluxerr + flux -> FLUX_ERR
+      if ((myOption == MAG_OPTION_FLUX_ERR) && (option == MAG_OPTION_FLUX)) {
+	myOption = MAG_OPTION_FLUX_ERR;
+	ptr = skipword (ptr);
+	continue;
+      }
+      if (myOption != MAG_OPTION_NONE) { fprintf (stderr, "invalid selection %s in %s\n", word, fieldName); free (word); return FALSE; } 
+      myOption = option;
+      ptr = skipword (ptr);
+      continue;
+    }
+
+    fprintf (stderr, "ERROR: unknown mag/photocode argument %s\n", word);
+    free (word);
+  }
+
+  // if nothing is provided, use the defaults
+  field->magSource = (mySource == MAG_SRC_NONE)    ? field->magSource : mySource;
+  field->magLevel  = (myLevel  == MAG_LEVEL_NONE)  ? field->magLevel  : myLevel;
+  field->magClass  = (myClass  == MAG_CLASS_NONE)  ? field->magClass  : myClass;
+  field->magOption = (myOption == MAG_OPTION_NONE) ? field->magOption : myOption;
+
+  switch (field->magOption) {
+    case MAG_OPTION_NCODE:
+    case MAG_OPTION_NPHOT:
+    case MAG_OPTION_FLAGS:
       field->type = OPIHI_INT;
       break;
@@ -313,11 +304,161 @@
   }
   field->photcode = code;
+  return TRUE;
+}
+
+// field needs to be initialized with dbInitField()
+# define ESCAPE(F,T) { \
+  field->ID = (F); \
+  field->type = (T); \
+  return (TRUE); }
+
+int ParseMeasureField (dbField *field, char *fieldName) {
+
+  field->table = DVO_TABLE_MEASURE;
+  field->name  = strcreate (fieldName);
+
+  if (!strcasecmp (fieldName, "GLON"))       {
+    dbExtractMeasuresInitTransform (COORD_GALACTIC);
+    ESCAPE (MEAS_GLON, OPIHI_FLT);
+  }
+  if (!strcasecmp (fieldName, "GLAT")) {
+    dbExtractMeasuresInitTransform (COORD_GALACTIC);
+    ESCAPE (MEAS_GLAT, OPIHI_FLT);
+  }
+  if (!strcasecmp (fieldName, "GLON:AVE")) {
+    dbExtractMeasuresInitTransform (COORD_GALACTIC);
+    ESCAPE (MEAS_GLON_AVE, OPIHI_FLT);
+  }
+  if (!strcasecmp (fieldName, "GLAT:AVE")) {
+    dbExtractMeasuresInitTransform (COORD_GALACTIC);
+    ESCAPE (MEAS_GLAT_AVE, OPIHI_FLT);
+  }
+
+  if (!strcasecmp (fieldName, "ELON"))       {
+    dbExtractMeasuresInitTransform (COORD_ECLIPTIC);
+    ESCAPE (MEAS_ELON, OPIHI_FLT);
+  }
+  if (!strcasecmp (fieldName, "ELAT")) {
+    dbExtractMeasuresInitTransform (COORD_ECLIPTIC);
+    ESCAPE (MEAS_ELAT, OPIHI_FLT);
+  }
+  if (!strcasecmp (fieldName, "ELON:AVE")) {
+    dbExtractMeasuresInitTransform (COORD_ECLIPTIC);
+    ESCAPE (MEAS_ELON_AVE, OPIHI_FLT);
+  }
+  if (!strcasecmp (fieldName, "ELAT:AVE")) {
+    dbExtractMeasuresInitTransform (COORD_ECLIPTIC);
+    ESCAPE (MEAS_ELAT_AVE, OPIHI_FLT);
+  }
+
+  if (!strcasecmp (fieldName, "RA"))         	 ESCAPE (MEAS_RA,             OPIHI_FLT);
+  if (!strcasecmp (fieldName, "DEC"))        	 ESCAPE (MEAS_DEC,            OPIHI_FLT);
+  if (!strcasecmp (fieldName, "RA:AVE"))     	 ESCAPE (MEAS_RA_AVE,         OPIHI_FLT);
+  if (!strcasecmp (fieldName, "DEC:AVE"))    	 ESCAPE (MEAS_DEC_AVE,        OPIHI_FLT);
+  if (!strcasecmp (fieldName, "RA:ERR"))     	 ESCAPE (MEAS_RA_AVE_ERR,     OPIHI_FLT);
+  if (!strcasecmp (fieldName, "DEC:ERR"))    	 ESCAPE (MEAS_DEC_AVE_ERR,    OPIHI_FLT);
+  if (!strcasecmp (fieldName, "uRA"))        	 ESCAPE (MEAS_U_RA,           OPIHI_FLT);
+  if (!strcasecmp (fieldName, "uDEC"))       	 ESCAPE (MEAS_U_DEC,          OPIHI_FLT);
+  if (!strcasecmp (fieldName, "duRA"))       	 ESCAPE (MEAS_U_RA_ERR,       OPIHI_FLT);
+  if (!strcasecmp (fieldName, "duDEC"))      	 ESCAPE (MEAS_U_DEC_ERR,      OPIHI_FLT);
+  if (!strcasecmp (fieldName, "PAR"))        	 ESCAPE (MEAS_PAR,            OPIHI_FLT);
+  if (!strcasecmp (fieldName, "dPAR"))       	 ESCAPE (MEAS_PAR_ERR,        OPIHI_FLT);
+  if (!strcasecmp (fieldName, "dR"))         	 ESCAPE (MEAS_RA_OFFSET,      OPIHI_FLT);
+  if (!strcasecmp (fieldName, "dD"))         	 ESCAPE (MEAS_DEC_OFFSET,     OPIHI_FLT);
+  if (!strcasecmp (fieldName, "dR:FIT"))     	 ESCAPE (MEAS_RA_FIT_OFFSET,  OPIHI_FLT);
+  if (!strcasecmp (fieldName, "dD:FIT"))     	 ESCAPE (MEAS_DEC_FIT_OFFSET, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "dR:ERR"))     	 ESCAPE (MEAS_RA_OFFSET_ERR,  OPIHI_FLT);
+  if (!strcasecmp (fieldName, "dD:ERR"))     	 ESCAPE (MEAS_DEC_OFFSET_ERR, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "ChiSqPos"))       ESCAPE (MEAS_CHISQ_POS,      OPIHI_FLT);
+  if (!strcasecmp (fieldName, "ChiSqPM"))        ESCAPE (MEAS_CHISQ_PM,       OPIHI_FLT);
+  if (!strcasecmp (fieldName, "ChiSqPar"))       ESCAPE (MEAS_CHISQ_PAR,      OPIHI_FLT);
+  if (!strcasecmp (fieldName, "Tmean"))          ESCAPE (MEAS_TMEAN,          OPIHI_FLT);
+  if (!strcasecmp (fieldName, "Trange"))         ESCAPE (MEAS_TRANGE,         OPIHI_FLT);
+  if (!strcasecmp (fieldName, "nmeas"))      	 ESCAPE (MEAS_NMEAS,          OPIHI_INT);
+  if (!strcasecmp (fieldName, "nmiss"))      	 ESCAPE (MEAS_NMISS,          OPIHI_INT);
+  if (!strcasecmp (fieldName, "npos"))      	 ESCAPE (MEAS_NPOS,           OPIHI_INT);
+  if (!strcasecmp (fieldName, "OBJFLAGS"))   	 ESCAPE (MEAS_OBJ_FLAGS,      OPIHI_INT);
+  if (!strcasecmp (fieldName, "OBJ_FLAGS"))   	 ESCAPE (MEAS_OBJ_FLAGS,      OPIHI_INT);
+  if (!strcasecmp (fieldName, "OBJ_PHOT_FLAGS")) ESCAPE (MEAS_SECFILT_FLAGS,      OPIHI_INT);
+  if (!strcasecmp (fieldName, "SECFLAGS"))   	 ESCAPE (MEAS_SECFILT_FLAGS,      OPIHI_INT);
+  if (!strcasecmp (fieldName, "SEC_FLAGS"))   	 ESCAPE (MEAS_SECFILT_FLAGS,      OPIHI_INT);
+  if (!strcasecmp (fieldName, "SECFILT_FLAGS"))  ESCAPE (MEAS_SECFILT_FLAGS,      OPIHI_INT);
+  if (!strcasecmp (fieldName, "DB_FLAGS"))   	 ESCAPE (MEAS_DB_FLAGS,       OPIHI_INT);
+  if (!strcasecmp (fieldName, "PHOT_FLAGS")) 	 ESCAPE (MEAS_PHOT_FLAGS,     OPIHI_INT);
+  if (!strcasecmp (fieldName, "DBFLAGS"))   	 ESCAPE (MEAS_DB_FLAGS,       OPIHI_INT);
+  if (!strcasecmp (fieldName, "PHOTFLAGS")) 	 ESCAPE (MEAS_PHOT_FLAGS,     OPIHI_INT);
+  if (!strcasecmp (fieldName, "AIRMASS"))    	 ESCAPE (MEAS_AIRMASS,        OPIHI_FLT);
+  if (!strcasecmp (fieldName, "MEAN_AIRMASS"))   ESCAPE (MEAS_MEAN_AIRMASS,   OPIHI_FLT);
+  if (!strcasecmp (fieldName, "ALT"))        	 ESCAPE (MEAS_ALT,            OPIHI_FLT);
+  if (!strcasecmp (fieldName, "AZ"))         	 ESCAPE (MEAS_AZ,             OPIHI_FLT);
+  if (!strcasecmp (fieldName, "EXPTIME"))    	 ESCAPE (MEAS_EXPTIME,        OPIHI_FLT);
+  if (!strcasecmp (fieldName, "PHOTCODE"))   	 ESCAPE (MEAS_PHOTCODE,       OPIHI_INT);
+  if (!strcasecmp (fieldName, "PHOTCODE:KLAM"))  ESCAPE (MEAS_PHOTCODE_KLAM,  OPIHI_FLT);
+  if (!strcasecmp (fieldName, "PHOTCODE:C"))     ESCAPE (MEAS_PHOTCODE_C,     OPIHI_FLT);
+  if (!strcasecmp (fieldName, "PHOTCODE:EQUIV")) ESCAPE (MEAS_PHOTCODE_EQUIV, OPIHI_INT);
+  if (!strcasecmp (fieldName, "TIME"))       	 ESCAPE (MEAS_TIME,           OPIHI_FLT);
+  if (!strcasecmp (fieldName, "FWHM"))       	 ESCAPE (MEAS_FWHM,           OPIHI_FLT);
+  if (!strcasecmp (fieldName, "FWHM_MAJ"))   	 ESCAPE (MEAS_FWHM_MAJ,       OPIHI_FLT);
+  if (!strcasecmp (fieldName, "FWHM_MIN"))   	 ESCAPE (MEAS_FWHM_MIN,       OPIHI_FLT);
+  if (!strcasecmp (fieldName, "THETA"))      	 ESCAPE (MEAS_THETA,          OPIHI_FLT);
+  if (!strcasecmp (fieldName, "POSANGLE"))     	 ESCAPE (MEAS_POSANGLE,       OPIHI_FLT);
+  if (!strcasecmp (fieldName, "PLATESCALE"))   	 ESCAPE (MEAS_PLATESCALE,     OPIHI_FLT);
+  if (!strcasecmp (fieldName, "MXX"))       	 ESCAPE (MEAS_MXX,            OPIHI_FLT);
+  if (!strcasecmp (fieldName, "MYY"))       	 ESCAPE (MEAS_MYY,            OPIHI_FLT);
+  if (!strcasecmp (fieldName, "MXY"))       	 ESCAPE (MEAS_MXY,            OPIHI_FLT);
+  if (!strcasecmp (fieldName, "DOPHOT"))     	 ESCAPE (MEAS_DOPHOT,         OPIHI_INT);
+  if (!strcasecmp (fieldName, "XCCD"))       	 ESCAPE (MEAS_XCCD,           OPIHI_FLT);
+  if (!strcasecmp (fieldName, "YCCD"))       	 ESCAPE (MEAS_YCCD,           OPIHI_FLT);
+  if (!strcasecmp (fieldName, "XCCD:ERR"))   	 ESCAPE (MEAS_XCCD_ERR,       OPIHI_FLT);
+  if (!strcasecmp (fieldName, "YCCD:ERR"))   	 ESCAPE (MEAS_YCCD_ERR,       OPIHI_FLT);
+  if (!strcasecmp (fieldName, "XFIX"))       	 ESCAPE (MEAS_XFIX,           OPIHI_FLT);
+  if (!strcasecmp (fieldName, "YFIX"))       	 ESCAPE (MEAS_YFIX,           OPIHI_FLT);
+  if (!strcasecmp (fieldName, "POS_SYS_ERR"))    ESCAPE (MEAS_POS_SYS_ERR,    OPIHI_FLT);
+  if (!strcasecmp (fieldName, "XFIELD"))    	 ESCAPE (MEAS_XFIELD,         OPIHI_FLT);
+  if (!strcasecmp (fieldName, "YFIELD"))    	 ESCAPE (MEAS_YFIELD,         OPIHI_FLT);
+  if (!strcasecmp (fieldName, "XMOSAIC"))    	 ESCAPE (MEAS_XMOSAIC,        OPIHI_FLT);
+  if (!strcasecmp (fieldName, "YMOSAIC"))    	 ESCAPE (MEAS_YMOSAIC,        OPIHI_FLT);
+  if (!strcasecmp (fieldName, "XCHIP"))      	 ESCAPE (MEAS_XCCD,           OPIHI_FLT);
+  if (!strcasecmp (fieldName, "YCHIP"))      	 ESCAPE (MEAS_YCCD,           OPIHI_FLT);
+  if (!strcasecmp (fieldName, "XFPA"))       	 ESCAPE (MEAS_XMOSAIC,        OPIHI_FLT);
+  if (!strcasecmp (fieldName, "YFPA"))       	 ESCAPE (MEAS_YMOSAIC,        OPIHI_FLT);
+  if (!strcasecmp (fieldName, "DETID"))      	 ESCAPE (MEAS_DET_ID,         OPIHI_INT);
+  if (!strcasecmp (fieldName, "OBJID"))      	 ESCAPE (MEAS_OBJ_ID,         OPIHI_INT);
+  if (!strcasecmp (fieldName, "CATID"))      	 ESCAPE (MEAS_CAT_ID,         OPIHI_INT);
+  if (!strcasecmp (fieldName, "IMAGEID"))    	 ESCAPE (MEAS_IMAGE_ID,       OPIHI_INT);
+  if (!strcasecmp (fieldName, "EXTERNID"))    	 ESCAPE (MEAS_EXTERN_ID,      OPIHI_INT);
+  if (!strcasecmp (fieldName, "EXPNAME"))    	 ESCAPE (MEAS_EXPNAME_AS_INT, OPIHI_INT);
+  if (!strcasecmp (fieldName, "PSF_QF"))     	 ESCAPE (MEAS_PSF_QF,         OPIHI_FLT);
+  if (!strcasecmp (fieldName, "PSF_QF_PERFECT")) ESCAPE (MEAS_PSF_QF_PERFECT, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "PSF_CHISQ"))  	 ESCAPE (MEAS_PSF_CHISQ,      OPIHI_FLT);
+  if (!strcasecmp (fieldName, "PSF_NDOF"))  	 ESCAPE (MEAS_PSF_NDOF,       OPIHI_INT);
+  if (!strcasecmp (fieldName, "PSF_NPIX"))  	 ESCAPE (MEAS_PSF_NPIX,       OPIHI_INT);
+  if (!strcasecmp (fieldName, "CR_NSIGMA"))  	 ESCAPE (MEAS_CR_NSIGMA,      OPIHI_FLT);
+  if (!strcasecmp (fieldName, "EXT_NSIGMA")) 	 ESCAPE (MEAS_EXT_NSIGMA,     OPIHI_FLT);
+  if (!strcasecmp (fieldName, "SKY"))        	 ESCAPE (MEAS_SKY,            OPIHI_FLT);
+  if (!strcasecmp (fieldName, "SKY_ERR"))    	 ESCAPE (MEAS_dSKY,           OPIHI_FLT);
+  if (!strcasecmp (fieldName, "MCAL_OFFSET"))    ESCAPE (MEAS_MCAL_OFFSET,    OPIHI_FLT);
+  if (!strcasecmp (fieldName, "FLAT"))    	 ESCAPE (MEAS_FLAT,           OPIHI_FLT);
+  if (!strcasecmp (fieldName, "CENTER_OFFSET"))  ESCAPE (MEAS_CENTER_OFFSET,  OPIHI_FLT);
+  // if (!strcasecmp (fieldName, "FLUX"))       	 ESCAPE (MEAS_FLUX_PSF,       OPIHI_FLT);
+  // if (!strcasecmp (fieldName, "FLUX_ERR"))       ESCAPE (MEAS_FLUX_PSF_ERR,   OPIHI_FLT);
+  // if (!strcasecmp (fieldName, "FLUX_PSF"))       ESCAPE (MEAS_FLUX_PSF,       OPIHI_FLT);
+  // if (!strcasecmp (fieldName, "FLUX_PSF_ERR"))   ESCAPE (MEAS_FLUX_PSF_ERR,   OPIHI_FLT);
+  // if (!strcasecmp (fieldName, "FLUX_KRON"))      ESCAPE (MEAS_FLUX_KRON,      OPIHI_FLT);
+  // if (!strcasecmp (fieldName, "FLUX_KRON_ERR"))  ESCAPE (MEAS_FLUX_KRON_ERR,  OPIHI_FLT);
+  if (!strcasecmp (fieldName, "REF_COLOR"))      ESCAPE (MEAS_REF_COLOR,      OPIHI_FLT);
+
+  // for words that don't parse, try a photcode
+
+  // check for code:mode in photcode name 
+  if (!ParsePhotcodeField (field, fieldName, MEAS_PHOT)) {
+    gprint (GP_ERR, "unknown field '%s' for measurement table in DVO database\n", fieldName);
+    return (FALSE);
+  }
+
   return (TRUE);
 }
 
 int ParseAverageField (dbField *field, char *fieldName) {
-
-  int mode;
-  PhotCode *code;
 
   field->table = DVO_TABLE_AVERAGE;
@@ -328,9 +469,9 @@
   if (!strcasecmp (fieldName, "GLON"))  { 
     dbExtractAveragesInitTransform (COORD_GALACTIC);
-    ESCAPE (AVE_GLON, MAG_NONE, OPIHI_FLT);
+    ESCAPE (AVE_GLON, OPIHI_FLT);
   }
   if (!strcasecmp (fieldName, "GLAT"))  {
     dbExtractAveragesInitTransform (COORD_GALACTIC);
-    ESCAPE (AVE_GLAT, MAG_NONE, OPIHI_FLT);
+    ESCAPE (AVE_GLAT, OPIHI_FLT);
   }
 
@@ -339,74 +480,59 @@
   if (!strcasecmp (fieldName, "ELON"))  { 
     dbExtractAveragesInitTransform (COORD_ECLIPTIC);
-    ESCAPE (AVE_ELON, MAG_NONE, OPIHI_FLT);
+    ESCAPE (AVE_ELON, OPIHI_FLT);
   }
   if (!strcasecmp (fieldName, "ELAT"))  {
     dbExtractAveragesInitTransform (COORD_ECLIPTIC);
-    ESCAPE (AVE_ELAT, MAG_NONE, OPIHI_FLT);
-  }
-
-  if (!strcasecmp (fieldName, "RA"))          ESCAPE (AVE_RA,          MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "DEC"))         ESCAPE (AVE_DEC,         MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "GLON"))        ESCAPE (AVE_GLON,        MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "GLAT"))        ESCAPE (AVE_GLAT,        MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "ELON"))        ESCAPE (AVE_ELON,        MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "ELAT"))        ESCAPE (AVE_ELAT,        MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "dRA"))         ESCAPE (AVE_RA_ERR,      MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "dDEC"))        ESCAPE (AVE_DEC_ERR,     MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "uRA"))         ESCAPE (AVE_U_RA,        MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "uDEC"))        ESCAPE (AVE_U_DEC,       MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "duRA"))        ESCAPE (AVE_U_RA_ERR,    MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "duDEC"))       ESCAPE (AVE_U_DEC_ERR,   MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "PAR"))         ESCAPE (AVE_PAR,         MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "dPAR"))        ESCAPE (AVE_PAR_ERR,     MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "ChiSqPos"))    ESCAPE (AVE_CHISQ_POS,   MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "ChiSqPM"))     ESCAPE (AVE_CHISQ_PM,    MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "ChiSqPar"))    ESCAPE (AVE_CHISQ_PAR,   MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "Tmean"))       ESCAPE (AVE_TMEAN,       MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "Trange"))      ESCAPE (AVE_TRANGE,      MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "psfqf"))       ESCAPE (AVE_PSF_QF,      MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "psfqfperf"))   ESCAPE (AVE_PSF_QF_PERF, MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "psf_qf"))      ESCAPE (AVE_PSF_QF,      MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "psf_qf_perf")) ESCAPE (AVE_PSF_QF_PERF, MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "stargal"))     ESCAPE (AVE_STARGAL,     MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "NMEAS"))       ESCAPE (AVE_NMEAS,       MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "NMISS"))       ESCAPE (AVE_NMISS,       MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "NPOS"))        ESCAPE (AVE_NPOS,        MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "NASTROM"))     ESCAPE (AVE_NPOS,        MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "FLAGS"))       ESCAPE (AVE_OBJ_FLAGS,   MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "OBJ_FLAGS"))   ESCAPE (AVE_OBJ_FLAGS,   MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "OBJFLAGS"))    ESCAPE (AVE_OBJ_FLAGS,   MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "OBJID"))       ESCAPE (AVE_OBJID,       MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "CATID"))       ESCAPE (AVE_CATID,       MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "EXTID_HI"))    ESCAPE (AVE_EXTID_HI,    MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "EXTID_LO"))    ESCAPE (AVE_EXTID_LO,    MAG_NONE, OPIHI_INT);
+    ESCAPE (AVE_ELAT, OPIHI_FLT);
+  }
+
+  if (!strcasecmp (fieldName, "RA"))          ESCAPE (AVE_RA,          OPIHI_FLT);
+  if (!strcasecmp (fieldName, "DEC"))         ESCAPE (AVE_DEC,         OPIHI_FLT);
+  if (!strcasecmp (fieldName, "GLON"))        ESCAPE (AVE_GLON,        OPIHI_FLT);
+  if (!strcasecmp (fieldName, "GLAT"))        ESCAPE (AVE_GLAT,        OPIHI_FLT);
+  if (!strcasecmp (fieldName, "ELON"))        ESCAPE (AVE_ELON,        OPIHI_FLT);
+  if (!strcasecmp (fieldName, "ELAT"))        ESCAPE (AVE_ELAT,        OPIHI_FLT);
+  if (!strcasecmp (fieldName, "dRA"))         ESCAPE (AVE_RA_ERR,      OPIHI_FLT);
+  if (!strcasecmp (fieldName, "dDEC"))        ESCAPE (AVE_DEC_ERR,     OPIHI_FLT);
+  if (!strcasecmp (fieldName, "uRA"))         ESCAPE (AVE_U_RA,        OPIHI_FLT);
+  if (!strcasecmp (fieldName, "uDEC"))        ESCAPE (AVE_U_DEC,       OPIHI_FLT);
+  if (!strcasecmp (fieldName, "duRA"))        ESCAPE (AVE_U_RA_ERR,    OPIHI_FLT);
+  if (!strcasecmp (fieldName, "duDEC"))       ESCAPE (AVE_U_DEC_ERR,   OPIHI_FLT);
+  if (!strcasecmp (fieldName, "PAR"))         ESCAPE (AVE_PAR,         OPIHI_FLT);
+  if (!strcasecmp (fieldName, "dPAR"))        ESCAPE (AVE_PAR_ERR,     OPIHI_FLT);
+  if (!strcasecmp (fieldName, "ChiSqPos"))    ESCAPE (AVE_CHISQ_POS,   OPIHI_FLT);
+  if (!strcasecmp (fieldName, "ChiSqPM"))     ESCAPE (AVE_CHISQ_PM,    OPIHI_FLT);
+  if (!strcasecmp (fieldName, "ChiSqPar"))    ESCAPE (AVE_CHISQ_PAR,   OPIHI_FLT);
+  if (!strcasecmp (fieldName, "Tmean"))       ESCAPE (AVE_TMEAN,       OPIHI_FLT);
+  if (!strcasecmp (fieldName, "Trange"))      ESCAPE (AVE_TRANGE,      OPIHI_FLT);
+  if (!strcasecmp (fieldName, "psfqf"))       ESCAPE (AVE_PSF_QF,      OPIHI_FLT);
+  if (!strcasecmp (fieldName, "psfqfperf"))   ESCAPE (AVE_PSF_QF_PERF, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "psf_qf"))      ESCAPE (AVE_PSF_QF,      OPIHI_FLT);
+  if (!strcasecmp (fieldName, "psf_qf_perf")) ESCAPE (AVE_PSF_QF_PERF, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "stargal"))     ESCAPE (AVE_STARGAL,     OPIHI_FLT);
+  if (!strcasecmp (fieldName, "NMEAS"))       ESCAPE (AVE_NMEAS,       OPIHI_INT);
+  if (!strcasecmp (fieldName, "NMISS"))       ESCAPE (AVE_NMISS,       OPIHI_INT);
+  if (!strcasecmp (fieldName, "NPOS"))        ESCAPE (AVE_NPOS,        OPIHI_INT);
+  if (!strcasecmp (fieldName, "NASTROM"))     ESCAPE (AVE_NPOS,        OPIHI_INT);
+  if (!strcasecmp (fieldName, "FLAGS"))       ESCAPE (AVE_OBJ_FLAGS,   OPIHI_INT);
+  if (!strcasecmp (fieldName, "OBJ_FLAGS"))   ESCAPE (AVE_OBJ_FLAGS,   OPIHI_INT);
+  if (!strcasecmp (fieldName, "OBJFLAGS"))    ESCAPE (AVE_OBJ_FLAGS,   OPIHI_INT);
+  if (!strcasecmp (fieldName, "OBJID"))       ESCAPE (AVE_OBJID,       OPIHI_INT);
+  if (!strcasecmp (fieldName, "CATID"))       ESCAPE (AVE_CATID,       OPIHI_INT);
+  if (!strcasecmp (fieldName, "EXTID_HI"))    ESCAPE (AVE_EXTID_HI,    OPIHI_INT);
+  if (!strcasecmp (fieldName, "EXTID_LO"))    ESCAPE (AVE_EXTID_LO,    OPIHI_INT);
+  if (!strcasecmp (fieldName, "REF_COLOR"))   ESCAPE (AVE_REF_COLOR,   OPIHI_FLT);
 
   // check for code:mode in photcode name 
-  code = ParsePhotcodeField (fieldName, &mode, MAG_AVE);
-  if (code == NULL) {
+  if (!ParsePhotcodeField (field, fieldName, AVE_PHOT)) {
     gprint (GP_ERR, "unknown field '%s' for average table in DVO database\n", fieldName);
     return (FALSE);
   }
 
-  if (code[0].type == PHOT_MAG) {
+  if (field->photcode->type == PHOT_MAG) {
     gprint (GP_ERR, "'mag' is ambiguous for avextract\n");
-    free (code);
     return (FALSE);
   }
 
-  field->ID = AVE_MAG;
-  field->magMode = mode;
-  switch (mode) {
-    case MAG_STACK_DET_ID:
-    case MAG_NCODE:
-    case MAG_NPHOT:
-    case MAG_PHOT_FLAGS:
-      field->type = OPIHI_INT;
-      break;
-    default:
-      field->type = OPIHI_FLT;
-      break;
-  }
-  field->photcode = code;
   return (TRUE);
 }
@@ -422,9 +548,9 @@
   if (!strcasecmp (fieldName, "GLON"))  { 
     dbExtractImagesInitTransform (COORD_GALACTIC);
-    ESCAPE (IMAGE_GLON, MAG_NONE, OPIHI_FLT);
+    ESCAPE (IMAGE_GLON, OPIHI_FLT);
   }
   if (!strcasecmp (fieldName, "GLAT"))  {
     dbExtractImagesInitTransform (COORD_GALACTIC);
-    ESCAPE (IMAGE_GLAT, MAG_NONE, OPIHI_FLT);
+    ESCAPE (IMAGE_GLAT, OPIHI_FLT);
   }
 
@@ -433,97 +559,98 @@
   if (!strcasecmp (fieldName, "ELON"))  { 
     dbExtractImagesInitTransform (COORD_ECLIPTIC);
-    ESCAPE (IMAGE_ELON, MAG_NONE, OPIHI_FLT);
+    ESCAPE (IMAGE_ELON, OPIHI_FLT);
   }
   if (!strcasecmp (fieldName, "ELAT"))  {
     dbExtractImagesInitTransform (COORD_ECLIPTIC);
-    ESCAPE (IMAGE_ELAT, MAG_NONE, OPIHI_FLT);
-  }
-
-  if (!strcasecmp (fieldName, "RA"       )) ESCAPE (IMAGE_RA,        MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "DEC"      )) ESCAPE (IMAGE_DEC,       MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "GLON"     )) ESCAPE (IMAGE_GLON,      MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "GLAT"     )) ESCAPE (IMAGE_GLAT,      MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "ELON"     )) ESCAPE (IMAGE_ELON,      MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "ELAT"     )) ESCAPE (IMAGE_ELAT,      MAG_NONE, OPIHI_FLT);
-
-  if (!strcasecmp (fieldName, "theta"    )) ESCAPE (IMAGE_THETA,     MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "skew"     )) ESCAPE (IMAGE_SKEW,      MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "scale"    )) ESCAPE (IMAGE_SCALE,     MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "dscale"   )) ESCAPE (IMAGE_DSCALE,    MAG_NONE, OPIHI_FLT);
-
-  if (!strcasecmp (fieldName, "time"     )) ESCAPE (IMAGE_TIME,      MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "nstar"    )) ESCAPE (IMAGE_NSTAR,     MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "airmass"  )) ESCAPE (IMAGE_AIRMASS,   MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "NX"       )) ESCAPE (IMAGE_NX_PIX,    MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "NY"       )) ESCAPE (IMAGE_NY_PIX,    MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "apresid"  )) ESCAPE (IMAGE_APRESID,   MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "dapresid" )) ESCAPE (IMAGE_DAPRESID,  MAG_NONE, OPIHI_FLT);
-
-  if (!strcasecmp (fieldName, "Mcal"     )) ESCAPE (IMAGE_MCAL,      MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "dMcal"    )) ESCAPE (IMAGE_dMCAL,     MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "Xm"       )) ESCAPE (IMAGE_XM,        MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "photcode" )) ESCAPE (IMAGE_PHOTCODE,  MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "exptime"  )) ESCAPE (IMAGE_EXPTIME,   MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "sidtime"  )) ESCAPE (IMAGE_SIDTIME,   MAG_NONE, OPIHI_FLT);
-
-  if (!strcasecmp (fieldName, "latitude" )) ESCAPE (IMAGE_LATITUDE,  MAG_NONE, OPIHI_FLT);
-
-  if (!strcasecmp (fieldName, "detlimit" )) ESCAPE (IMAGE_DET_LIMIT, MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "satlimit" )) ESCAPE (IMAGE_SAT_LIMIT, MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "cerror"   )) ESCAPE (IMAGE_CERROR,    MAG_NONE, OPIHI_FLT);
-
-  if (!strcasecmp (fieldName, "FWHM"       )) ESCAPE (IMAGE_FWHM,      MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "FWHM_MAJ"   )) ESCAPE (IMAGE_FWHM_MAJ,  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "FWHM_MIN"   )) ESCAPE (IMAGE_FWHM_MIN,  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "FWHM_MAJOR" )) ESCAPE (IMAGE_FWHM_MAJ,  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "FWHM_MINOR" )) ESCAPE (IMAGE_FWHM_MIN,  MAG_NONE, OPIHI_FLT);
-
-  if (!strcasecmp (fieldName, "FWHM_MEDIAN"    ))   ESCAPE (IMAGE_FWHM_MEDIAN,      MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "FWHM_MAJ_MEDIAN"))   ESCAPE (IMAGE_FWHM_MAJ_MEDIAN,  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "FWHM_MIN_MEDIAN"))   ESCAPE (IMAGE_FWHM_MIN_MEDIAN,  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "FWHM_MAJOR_MEDIAN")) ESCAPE (IMAGE_FWHM_MAJ_MEDIAN,  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "FWHM_MINOR_MEDIAN")) ESCAPE (IMAGE_FWHM_MIN_MEDIAN,  MAG_NONE, OPIHI_FLT);
-
-  if (!strcasecmp (fieldName, "trate"    )) ESCAPE (IMAGE_TRATE,     MAG_NONE, OPIHI_FLT);
-
-  if (!strcasecmp (fieldName, "ncal"     )) ESCAPE (IMAGE_NCAL,      MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "sky"      )) ESCAPE (IMAGE_SKY,       MAG_NONE, OPIHI_FLT); // deprecated for now
-
-  if (!strcasecmp (fieldName, "imflags"  )) ESCAPE (IMAGE_FLAGS,     MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "flags"    )) ESCAPE (IMAGE_FLAGS,     MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "ccdnum"   )) ESCAPE (IMAGE_CCDNUM,    MAG_NONE, OPIHI_INT);
-
-  if (!strcasecmp (fieldName, "imageID"  )) ESCAPE (IMAGE_IMAGE_ID,  MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "externID" )) ESCAPE (IMAGE_EXTERN_ID, MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "sourceID" )) ESCAPE (IMAGE_SOURCE_ID, MAG_NONE, OPIHI_INT);
-
-  if (!strcasecmp (fieldName, "X_LL_CHIP")) ESCAPE (IMAGE_X_LL_CHIP, MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "X_LR_CHIP")) ESCAPE (IMAGE_X_LR_CHIP, MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "X_UL_CHIP")) ESCAPE (IMAGE_X_UL_CHIP, MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "X_UR_CHIP")) ESCAPE (IMAGE_X_UR_CHIP, MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "Y_LL_CHIP")) ESCAPE (IMAGE_Y_LL_CHIP, MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "Y_LR_CHIP")) ESCAPE (IMAGE_Y_LR_CHIP, MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "Y_UL_CHIP")) ESCAPE (IMAGE_Y_UL_CHIP, MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "Y_UR_CHIP")) ESCAPE (IMAGE_Y_UR_CHIP, MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "X_LL_FP"  )) ESCAPE (IMAGE_X_LL_FP,   MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "X_LR_FP"  )) ESCAPE (IMAGE_X_LR_FP,   MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "X_UL_FP"  )) ESCAPE (IMAGE_X_UL_FP,   MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "X_UR_FP"  )) ESCAPE (IMAGE_X_UR_FP,   MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "Y_LL_FP"  )) ESCAPE (IMAGE_Y_LL_FP,   MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "Y_LR_FP"  )) ESCAPE (IMAGE_Y_LR_FP,   MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "Y_UL_FP"  )) ESCAPE (IMAGE_Y_UL_FP,   MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "Y_UR_FP"  )) ESCAPE (IMAGE_Y_UR_FP,   MAG_NONE, OPIHI_FLT);
-
-  if (!strcasecmp (fieldName, "dX_SYS"  )) ESCAPE (IMAGE_X_ERR_SYS,  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "dY_SYS"  )) ESCAPE (IMAGE_Y_ERR_SYS,  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "dM_SYS"  )) ESCAPE (IMAGE_MAG_ERR_SYS,MAG_NONE, OPIHI_FLT);
-
-  if (!strcasecmp (fieldName, "UBERCAL_DIST")) ESCAPE (IMAGE_UBERCAL_DIST,MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "UCDIST")) ESCAPE (IMAGE_UBERCAL_DIST,MAG_NONE, OPIHI_INT);
-
-  if (!strcasecmp (fieldName, "NFIT_PHOTOM")) ESCAPE (IMAGE_NFIT_PHOTOM,MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "NFIT_ASTROM")) ESCAPE (IMAGE_NFIT_ASTROM,MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "NLINK_PHOTOM")) ESCAPE (IMAGE_NLINK_PHOTOM,MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "NLINK_ASTROM")) ESCAPE (IMAGE_NLINK_ASTROM,MAG_NONE, OPIHI_INT);
+    ESCAPE (IMAGE_ELAT, OPIHI_FLT);
+  }
+
+  if (!strcasecmp (fieldName, "RA"       )) ESCAPE (IMAGE_RA,        OPIHI_FLT);
+  if (!strcasecmp (fieldName, "DEC"      )) ESCAPE (IMAGE_DEC,       OPIHI_FLT);
+  if (!strcasecmp (fieldName, "GLON"     )) ESCAPE (IMAGE_GLON,      OPIHI_FLT);
+  if (!strcasecmp (fieldName, "GLAT"     )) ESCAPE (IMAGE_GLAT,      OPIHI_FLT);
+  if (!strcasecmp (fieldName, "ELON"     )) ESCAPE (IMAGE_ELON,      OPIHI_FLT);
+  if (!strcasecmp (fieldName, "ELAT"     )) ESCAPE (IMAGE_ELAT,      OPIHI_FLT);
+
+  if (!strcasecmp (fieldName, "theta"    )) ESCAPE (IMAGE_THETA,     OPIHI_FLT);
+  if (!strcasecmp (fieldName, "skew"     )) ESCAPE (IMAGE_SKEW,      OPIHI_FLT);
+  if (!strcasecmp (fieldName, "scale"    )) ESCAPE (IMAGE_SCALE,     OPIHI_FLT);
+  if (!strcasecmp (fieldName, "dscale"   )) ESCAPE (IMAGE_DSCALE,    OPIHI_FLT);
+
+  if (!strcasecmp (fieldName, "time"     )) ESCAPE (IMAGE_TIME,      OPIHI_FLT);
+  if (!strcasecmp (fieldName, "nstar"    )) ESCAPE (IMAGE_NSTAR,     OPIHI_INT);
+  if (!strcasecmp (fieldName, "airmass"  )) ESCAPE (IMAGE_AIRMASS,   OPIHI_FLT);
+  if (!strcasecmp (fieldName, "NX"       )) ESCAPE (IMAGE_NX_PIX,    OPIHI_INT);
+  if (!strcasecmp (fieldName, "NY"       )) ESCAPE (IMAGE_NY_PIX,    OPIHI_INT);
+  if (!strcasecmp (fieldName, "apresid"  )) ESCAPE (IMAGE_APRESID,   OPIHI_FLT);
+  if (!strcasecmp (fieldName, "dapresid" )) ESCAPE (IMAGE_DAPRESID,  OPIHI_FLT);
+
+  if (!strcasecmp (fieldName, "Mcal"     )) ESCAPE (IMAGE_MCAL,      OPIHI_FLT);
+  if (!strcasecmp (fieldName, "dMcal"    )) ESCAPE (IMAGE_dMCAL,     OPIHI_FLT);
+  if (!strcasecmp (fieldName, "Xm"       )) ESCAPE (IMAGE_XM,        OPIHI_FLT);
+  if (!strcasecmp (fieldName, "photcode" )) ESCAPE (IMAGE_PHOTCODE,  OPIHI_INT);
+  if (!strcasecmp (fieldName, "exptime"  )) ESCAPE (IMAGE_EXPTIME,   OPIHI_FLT);
+  if (!strcasecmp (fieldName, "sidtime"  )) ESCAPE (IMAGE_SIDTIME,   OPIHI_FLT);
+
+  if (!strcasecmp (fieldName, "latitude" )) ESCAPE (IMAGE_LATITUDE,  OPIHI_FLT);
+
+  if (!strcasecmp (fieldName, "detlimit" )) ESCAPE (IMAGE_DET_LIMIT, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "satlimit" )) ESCAPE (IMAGE_SAT_LIMIT, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "cerror"   )) ESCAPE (IMAGE_CERROR,    OPIHI_FLT);
+
+  if (!strcasecmp (fieldName, "FWHM"       )) ESCAPE (IMAGE_FWHM,      OPIHI_FLT);
+  if (!strcasecmp (fieldName, "FWHM_MAJ"   )) ESCAPE (IMAGE_FWHM_MAJ,  OPIHI_FLT);
+  if (!strcasecmp (fieldName, "FWHM_MIN"   )) ESCAPE (IMAGE_FWHM_MIN,  OPIHI_FLT);
+  if (!strcasecmp (fieldName, "FWHM_MAJOR" )) ESCAPE (IMAGE_FWHM_MAJ,  OPIHI_FLT);
+  if (!strcasecmp (fieldName, "FWHM_MINOR" )) ESCAPE (IMAGE_FWHM_MIN,  OPIHI_FLT);
+
+  if (!strcasecmp (fieldName, "FWHM_MEDIAN"    ))   ESCAPE (IMAGE_FWHM_MEDIAN,      OPIHI_FLT);
+  if (!strcasecmp (fieldName, "FWHM_MAJ_MEDIAN"))   ESCAPE (IMAGE_FWHM_MAJ_MEDIAN,  OPIHI_FLT);
+  if (!strcasecmp (fieldName, "FWHM_MIN_MEDIAN"))   ESCAPE (IMAGE_FWHM_MIN_MEDIAN,  OPIHI_FLT);
+  if (!strcasecmp (fieldName, "FWHM_MAJOR_MEDIAN")) ESCAPE (IMAGE_FWHM_MAJ_MEDIAN,  OPIHI_FLT);
+  if (!strcasecmp (fieldName, "FWHM_MINOR_MEDIAN")) ESCAPE (IMAGE_FWHM_MIN_MEDIAN,  OPIHI_FLT);
+
+  if (!strcasecmp (fieldName, "trate"    )) ESCAPE (IMAGE_TRATE,     OPIHI_FLT);
+
+  if (!strcasecmp (fieldName, "ncal"     )) ESCAPE (IMAGE_NCAL,      OPIHI_INT);
+  if (!strcasecmp (fieldName, "sky"      )) ESCAPE (IMAGE_SKY,       OPIHI_FLT); // deprecated for now
+
+  if (!strcasecmp (fieldName, "imflags"  )) ESCAPE (IMAGE_FLAGS,     OPIHI_INT);
+  if (!strcasecmp (fieldName, "flags"    )) ESCAPE (IMAGE_FLAGS,     OPIHI_INT);
+  if (!strcasecmp (fieldName, "ccdnum"   )) ESCAPE (IMAGE_CCDNUM,    OPIHI_INT);
+
+  if (!strcasecmp (fieldName, "imageID"  )) ESCAPE (IMAGE_IMAGE_ID,  OPIHI_INT);
+  if (!strcasecmp (fieldName, "externID" )) ESCAPE (IMAGE_EXTERN_ID, OPIHI_INT);
+  if (!strcasecmp (fieldName, "sourceID" )) ESCAPE (IMAGE_SOURCE_ID, OPIHI_INT);
+
+  if (!strcasecmp (fieldName, "X_LL_CHIP")) ESCAPE (IMAGE_X_LL_CHIP, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "X_LR_CHIP")) ESCAPE (IMAGE_X_LR_CHIP, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "X_UL_CHIP")) ESCAPE (IMAGE_X_UL_CHIP, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "X_UR_CHIP")) ESCAPE (IMAGE_X_UR_CHIP, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "Y_LL_CHIP")) ESCAPE (IMAGE_Y_LL_CHIP, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "Y_LR_CHIP")) ESCAPE (IMAGE_Y_LR_CHIP, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "Y_UL_CHIP")) ESCAPE (IMAGE_Y_UL_CHIP, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "Y_UR_CHIP")) ESCAPE (IMAGE_Y_UR_CHIP, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "X_LL_FP"  )) ESCAPE (IMAGE_X_LL_FP,   OPIHI_FLT);
+  if (!strcasecmp (fieldName, "X_LR_FP"  )) ESCAPE (IMAGE_X_LR_FP,   OPIHI_FLT);
+  if (!strcasecmp (fieldName, "X_UL_FP"  )) ESCAPE (IMAGE_X_UL_FP,   OPIHI_FLT);
+  if (!strcasecmp (fieldName, "X_UR_FP"  )) ESCAPE (IMAGE_X_UR_FP,   OPIHI_FLT);
+  if (!strcasecmp (fieldName, "Y_LL_FP"  )) ESCAPE (IMAGE_Y_LL_FP,   OPIHI_FLT);
+  if (!strcasecmp (fieldName, "Y_LR_FP"  )) ESCAPE (IMAGE_Y_LR_FP,   OPIHI_FLT);
+  if (!strcasecmp (fieldName, "Y_UL_FP"  )) ESCAPE (IMAGE_Y_UL_FP,   OPIHI_FLT);
+  if (!strcasecmp (fieldName, "Y_UR_FP"  )) ESCAPE (IMAGE_Y_UR_FP,   OPIHI_FLT);
+
+  if (!strcasecmp (fieldName, "dX_SYS"  )) ESCAPE (IMAGE_X_ERR_SYS,  OPIHI_FLT);
+  if (!strcasecmp (fieldName, "dY_SYS"  )) ESCAPE (IMAGE_Y_ERR_SYS,  OPIHI_FLT);
+  if (!strcasecmp (fieldName, "dM_SYS"  )) ESCAPE (IMAGE_MAG_ERR_SYS,OPIHI_FLT);
+
+  if (!strcasecmp (fieldName, "UBERCAL_DIST")) ESCAPE (IMAGE_UBERCAL_DIST,OPIHI_INT);
+  if (!strcasecmp (fieldName, "UCDIST")) ESCAPE (IMAGE_UBERCAL_DIST,OPIHI_INT);
+
+  if (!strcasecmp (fieldName, "NFIT_PHOTOM"))  ESCAPE (IMAGE_NFIT_PHOTOM,  OPIHI_INT);
+  if (!strcasecmp (fieldName, "NFIT_ASTROM"))  ESCAPE (IMAGE_NFIT_ASTROM,  OPIHI_INT);
+  if (!strcasecmp (fieldName, "NLINK_PHOTOM")) ESCAPE (IMAGE_NLINK_PHOTOM, OPIHI_INT);
+  if (!strcasecmp (fieldName, "NLINK_ASTROM")) ESCAPE (IMAGE_NLINK_ASTROM, OPIHI_INT);
+  if (!strcasecmp (fieldName, "REF_COLOR"))    ESCAPE (IMAGE_REF_COLOR,    OPIHI_FLT);
 
   // for words that don't parse, try a photcode
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_catalog.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_catalog.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_catalog.c	(revision 37403)
@@ -56,4 +56,5 @@
   if (!strcasecmp (catformat, "PS1_V3"))          return (DVO_FORMAT_PS1_V3);
   if (!strcasecmp (catformat, "PS1_V4"))          return (DVO_FORMAT_PS1_V4);
+  if (!strcasecmp (catformat, "PS1_V5"))          return (DVO_FORMAT_PS1_V5);
   if (!strcasecmp (catformat, "PS1_REF"))         return (DVO_FORMAT_PS1_REF);
   return (DVO_FORMAT_UNDEF);
@@ -69,17 +70,46 @@
 }
 
+float dvoOffsetR (Measure *measure, Average *average) {
+
+  float dR = (measure[0].R - average[0].R) * 3600.0;
+  return dR;
+}
+
+float dvoOffsetD (Measure *measure, Average *average) {
+
+  float dD = (measure[0].D - average[0].D) * 3600.0;
+  return dD;
+}
+
+double dvoMeanR (float dR, Average *average) {
+
+  double ra = average[0].R - dR / 3600.0;
+  return ra;
+}
+
+double dvoMeanD (float dD, Average *average) {
+
+  double dec = average[0].D - dD / 3600.0;
+  return dec;
+}
+
 // init all data, or just catalog data
 void dvo_average_init (Average *average) {
   average->R         	   = 0;
   average->D         	   = 0;
-  average->dR        	   = 0;
-  average->dD        	   = 0;
+  average->dR        	   = NAN;
+  average->dD        	   = NAN;
 
   average->uR        	   = 0;
   average->uD        	   = 0;
-  average->duR       	   = 0;
-  average->duD       	   = 0;
+  average->duR       	   = NAN;
+  average->duD       	   = NAN;
   average->P         	   = 0;
-  average->dP        	   = 0;
+  average->dP        	   = NAN;
+
+  average->Rstk        	   = NAN;
+  average->Dstk        	   = NAN;
+  average->dRstk       	   = NAN;
+  average->dDstk       	   = NAN;
 
   average->ChiSqAve  	   = NAN;
@@ -97,8 +127,22 @@
   average->Nmeasure        = 0;
   average->Nmissing        = 0;
+  average->Nlensing        = 0;
+  average->Nlensobj        = 0;
   average->Nextend         = 0;
+
   average->measureOffset   = -1;
   average->missingOffset   = -1;
+  average->lensingOffset   = -1;
+  average->lensobjOffset   = -1;
   average->extendOffset    = -1;
+  average->paramsOffset    = -1;
+
+  average->refColorBlue    = NAN;
+  average->refColorRed     = NAN;
+
+  average->tessID          = 0;
+  average->skycellID       = 0;
+  average->projectionID    = 0;
+  average->dummy           = 0;
 
   average->flags           = 0;
@@ -109,4 +153,5 @@
   average->catID     	   = 0;
   average->extID     	   = 0;
+  average->extIDgc    	   = 0;
 }
 
@@ -125,37 +170,82 @@
 void dvo_secfilt_init (SecFilt *secfilt) {
   secfilt->M           = NAN;
+  secfilt->dM          = NAN;
   secfilt->Map         = NAN;
+  secfilt->dMap        = NAN;
+  secfilt->sMap        = NAN;
   secfilt->Mkron       = NAN;
   secfilt->dMkron      = NAN;
-  secfilt->dM          = NAN;
-  secfilt->Xm          = NAN_S_SHORT;
-
-  secfilt->FluxPSF     = NAN;
-  secfilt->dFluxPSF    = NAN;
-  secfilt->FluxKron    = NAN;
-  secfilt->dFluxKron   = NAN;
-
-  secfilt->flags       = 0;
+  secfilt->sMkron      = NAN;
+
+  secfilt->psfQfMax     = NAN;
+  secfilt->psfQfPerfMax = NAN;
+
+  secfilt->Mstdev      = NAN;
+  secfilt->Mmin        = NAN;
+  secfilt->Mmax        = NAN;
+  secfilt->Mchisq      = NAN;
+
   secfilt->Ncode       = 0;
   secfilt->Nused       = 0;
-
-  secfilt->M_20        = NAN_S_SHORT;
-  secfilt->M_80        = NAN_S_SHORT;
+  secfilt->NusedKron   = 0;
+  secfilt->NusedAp     = 0;
+
+  secfilt->flags       = 0;
+
+  secfilt->MpsfStk     = NAN;
+  secfilt->FpsfStk     = NAN;
+  secfilt->dFpsfStk    = NAN;
+
+  secfilt->MkronStk    = NAN;
+  secfilt->FkronStk    = NAN;
+  secfilt->dFkronStk   = NAN;
+
+  secfilt->MapStk      = NAN;
+  secfilt->FapStk      = NAN;
+  secfilt->dFapStk     = NAN;
+
+  secfilt->Nstack      = 0;
+  secfilt->NstackDet   = 0;
+
+  secfilt->stackPrmryOff = -1;
+  secfilt->stackBestOff  = -1;
+
+  secfilt->MpsfWrp     = NAN;
+  secfilt->FpsfWrp     = NAN;
+  secfilt->dFpsfWrp    = NAN;
+  secfilt->sFpsfWrp    = NAN;
+
+  secfilt->MkronWrp    = NAN;
+  secfilt->FkronWrp    = NAN;
+  secfilt->dFkronWrp   = NAN;
+  secfilt->sFkronWrp   = NAN;
+
+  secfilt->MapWrp      = NAN;
+  secfilt->FapWrp      = NAN;
+  secfilt->dFapWrp     = NAN;
+  secfilt->sFapWrp     = NAN;
+
+  secfilt->NusedWrp     = 0;
+  secfilt->NusedKronWrp = 0;
+  secfilt->NusedApWrp   = 0;
+
+  secfilt->Nwarp        = 0;
+  secfilt->NwarpGood    = 0;
 
   secfilt->ubercalDist = 1000;
-  secfilt->Mstdev      = NAN_S_SHORT;
-  secfilt->stackDetectID     = 0;
 }
 
 // init all data, or just catalog data
 void dvo_measure_init (Measure *measure) {
+ measure->R         = NAN;
+ measure->D         = NAN;
+
  measure->M         = NAN;
- measure->dR        = NAN;
- measure->dD        = NAN;
- measure->Mcal      = NAN;
+ measure->dM        = NAN;
  measure->Map       = NAN;
+ measure->dMap      = NAN;
  measure->Mkron     = NAN;
  measure->dMkron    = NAN;
- measure->dM        = NAN;
+ measure->Mcal      = NAN;
  measure->dMcal     = NAN;
  measure->dt        = NAN;
@@ -165,4 +255,6 @@
  measure->FluxKron  = NAN;
  measure->dFluxKron = NAN;
+ measure->FluxAp    = NAN;
+ measure->dFluxAp   = NAN;
 
  measure->airmass   = NAN;
@@ -174,23 +266,31 @@
  measure->Yfix      = NAN;
 
+ measure->XoffKH    = NAN;
+ measure->YoffKH    = NAN;
+ measure->XoffDCR   = NAN;
+ measure->YoffDCR   = NAN;
+ measure->RoffGAL   = NAN;
+ measure->DoffGAL   = NAN;
+
  measure->Sky       = NAN;
  measure->dSky      = NAN;
 
  measure->t         = 0;
- measure->t_msec    = 0;
  measure->averef    = 0;
 
  measure->detID     = 0;
- measure->imageID   = 0;
  measure->objID     = 0;
  measure->catID     = 0;
+
  measure->extID     = 0;
+
+ measure->imageID   = 0;
 
  measure->psfQF     = NAN;
  measure->psfQFperf = NAN;
  measure->psfChisq  = NAN;
+
  measure->psfNdof   = 0;
  measure->psfNpix   = 0;
- measure->crNsigma  = NAN;
  measure->extNsigma = NAN;
 
@@ -203,4 +303,7 @@
  measure->Myy       = 0;
 
+ measure->t_msec    = 0;
+ measure->photcode  = 0;
+
  measure->dXccd     = 0;
  measure->dYccd     = 0;
@@ -210,12 +313,12 @@
  measure->pltscale  = NAN;
 
- measure->photcode  = 0;
  measure->dbFlags   = 0;
  measure->photFlags = 0;
+ measure->photFlags2= 0;
 }
 
 void dvo_measureT_init (MeasureTiny *measure) {
- measure->dR        = NAN;
- measure->dD        = NAN;
+ measure->R         = NAN;
+ measure->D         = NAN;
  measure->M         = NAN;
  measure->Mcal      = NAN;
@@ -244,4 +347,91 @@
  measure->dRsys     = 0;
  measure->myDet     = FALSE;
+}
+
+// init all data, or just catalog data
+void dvo_lensing_init (Lensing *lensing) {
+  lensing->X11_sm_obj = NAN;
+  lensing->X12_sm_obj = NAN;
+  lensing->X22_sm_obj = NAN;
+  lensing->E1_sm_obj  = NAN;
+  lensing->E2_sm_obj  = NAN;
+
+  lensing->X11_sh_obj = NAN;
+  lensing->X12_sh_obj = NAN;
+  lensing->X22_sh_obj = NAN;
+  lensing->E1_sh_obj  = NAN;
+  lensing->E2_sh_obj  = NAN;
+
+  lensing->X11_sm_psf = NAN;
+  lensing->X12_sm_psf = NAN;
+  lensing->X22_sm_psf = NAN;
+  lensing->E1_sm_psf  = NAN;
+  lensing->E2_sm_psf  = NAN;
+
+  lensing->X11_sh_psf = NAN;
+  lensing->X12_sh_psf = NAN;
+  lensing->X22_sh_psf = NAN;
+  lensing->E1_sh_psf  = NAN;
+  lensing->E2_sh_psf  = NAN;
+
+  lensing->F_ApR5     = NAN;
+  lensing->dF_ApR5    = NAN;
+  lensing->sF_ApR5    = NAN;
+  lensing->fF_ApR5    = NAN;
+
+  lensing->F_ApR6     = NAN;
+  lensing->dF_ApR6    = NAN;
+  lensing->sF_ApR6    = NAN;
+  lensing->fF_ApR6    = NAN;
+
+  lensing->detID = -1;
+  lensing->objID = -1;
+  lensing->catID = -1;
+  lensing->averef = 0;
+
+  lensing->imageID = -1;
+  lensing->padding = 0;
+}
+
+// init all data, or just catalog data
+void dvo_lensobj_init (Lensobj *lensobj, int toZero) {
+  lensobj->X11_sm_obj = toZero ? 0 : NAN;
+  lensobj->X12_sm_obj = toZero ? 0 : NAN;
+  lensobj->X22_sm_obj = toZero ? 0 : NAN;
+  lensobj->E1_sm_obj  = toZero ? 0 : NAN;
+  lensobj->E2_sm_obj  = toZero ? 0 : NAN;
+  lensobj->X11_sh_obj = toZero ? 0 : NAN;
+  lensobj->X12_sh_obj = toZero ? 0 : NAN;
+  lensobj->X22_sh_obj = toZero ? 0 : NAN;
+  lensobj->E1_sh_obj  = toZero ? 0 : NAN;
+  lensobj->E2_sh_obj  = toZero ? 0 : NAN;
+  lensobj->X11_sm_psf = toZero ? 0 : NAN;
+  lensobj->X12_sm_psf = toZero ? 0 : NAN;
+  lensobj->X22_sm_psf = toZero ? 0 : NAN;
+  lensobj->E1_sm_psf  = toZero ? 0 : NAN;
+  lensobj->E2_sm_psf  = toZero ? 0 : NAN;
+  lensobj->X11_sh_psf = toZero ? 0 : NAN;
+  lensobj->X12_sh_psf = toZero ? 0 : NAN;
+  lensobj->X22_sh_psf = toZero ? 0 : NAN;
+  lensobj->E1_sh_psf  = toZero ? 0 : NAN;
+  lensobj->E2_sh_psf  = toZero ? 0 : NAN;
+  lensobj->F_ApR5     = toZero ? 0 : NAN;
+  lensobj->dF_ApR5    = toZero ? 0 : NAN;
+  lensobj->sF_ApR5    = toZero ? 0 : NAN;
+  lensobj->fF_ApR5    = toZero ? 0 : NAN;
+  lensobj->F_ApR6     = toZero ? 0 : NAN;
+  lensobj->dF_ApR6    = toZero ? 0 : NAN;
+  lensobj->sF_ApR6    = toZero ? 0 : NAN;
+  lensobj->fF_ApR6    = toZero ? 0 : NAN;
+
+  lensobj->gamma = NAN;
+  lensobj->E1 = NAN;
+  lensobj->E2 = NAN;
+
+  lensobj->objID = -1;
+  lensobj->catID = -1;
+
+  lensobj->photcode = 0;
+  lensobj->Nmeas = 0;
 }
 
@@ -269,4 +459,7 @@
   catalog[0].secfilt = NULL;
   
+  catalog[0].lensing = NULL; 
+  catalog[0].lensobj = NULL; 
+
   catalog[0].averageT = NULL;
   catalog[0].measureT = NULL; 
@@ -281,4 +474,7 @@
   catalog[0].Nsecf_mem = 0;
 
+  catalog[0].Nlensing = 0;
+  catalog[0].Nlensobj = 0;
+
   catalog[0].Naves_disk = 0;
   catalog[0].Nmeas_disk = 0;
@@ -286,4 +482,7 @@
   catalog[0].Nsecf_disk = 0;
 
+  catalog[0].Nlensing_disk = 0;
+  catalog[0].Nlensobj_disk = 0;
+
   catalog[0].Naves_off  = 0;
   catalog[0].Nmeas_off  = 0;
@@ -291,15 +490,22 @@
   catalog[0].Nsecf_off  = 0;
 
+  catalog[0].Nlensing_off  = 0;
+  catalog[0].Nlensobj_off  = 0;
+
   /* pointers to SPLIT data files */
   catalog[0].measure_catalog = NULL;
   catalog[0].missing_catalog = NULL;
   catalog[0].secfilt_catalog = NULL;
+  catalog[0].lensing_catalog = NULL;
+  catalog[0].lensobj_catalog = NULL;
 
   /* pointers for data manipulation */
-  catalog[0].found = NULL;
-  catalog[0].image = NULL;
-  catalog[0].mosaic = NULL;
-  catalog[0].X = NULL;
-  catalog[0].Y = NULL;
+  // catalog[0].X_t = NULL;
+  // catalog[0].Y_t = NULL;
+  catalog[0].nOwn_t = NULL;
+  catalog[0].found_t = NULL;
+  // catalog[0].image_t = NULL;
+  // catalog[0].mosaic_t = NULL;
+  catalog[0].foundWarp_t = NULL;
 }
 
@@ -345,10 +551,13 @@
   }
 
+  // closes f but does not set back to NULL
   fclearlockfile (catalog[0].filename, catalog[0].f, catalog[0].lockmode, &dbstate);
 
   if (catalog[0].catmode == DVO_MODE_SPLIT) {
-    if (catalog[0].measure_catalog != NULL) dvo_catalog_unlock (catalog[0].measure_catalog);
-    if (catalog[0].missing_catalog != NULL) dvo_catalog_unlock (catalog[0].missing_catalog);
-    if (catalog[0].secfilt_catalog != NULL) dvo_catalog_unlock (catalog[0].secfilt_catalog);
+    if (catalog[0].measure_catalog) dvo_catalog_unlock (catalog[0].measure_catalog);
+    if (catalog[0].missing_catalog) dvo_catalog_unlock (catalog[0].missing_catalog);
+    if (catalog[0].secfilt_catalog) dvo_catalog_unlock (catalog[0].secfilt_catalog);
+    if (catalog[0].lensing_catalog) dvo_catalog_unlock (catalog[0].lensing_catalog);
+    if (catalog[0].lensobj_catalog) dvo_catalog_unlock (catalog[0].lensobj_catalog);
   }
   return (1);
@@ -579,12 +788,12 @@
     for (in = out = i = 0; i < catalog[0].Naverage; i++) {
       for (j = 0; j < catalog[0].Nsecfilt; j++, in++, out++) {
-	outsec[out].M  = insec[in].M;
-	outsec[out].dM = insec[in].dM;
-	outsec[out].Xm = insec[in].Xm;
+	outsec[out].M  	   = insec[in].M;
+	outsec[out].dM 	   = insec[in].dM;
+	outsec[out].Mchisq = insec[in].Mchisq;
       }
       for (j = 0; j < Nextra; j++, out++) {
-	outsec[out].M  = NAN;
-	outsec[out].dM = NAN;
-	outsec[out].Xm = NAN_S_SHORT;
+	outsec[out].M  	   = NAN;
+	outsec[out].dM 	   = NAN;
+	outsec[out].Mchisq = NAN;
       }
     }
@@ -616,4 +825,14 @@
       free (catalog[0].secfilt_catalog);
     }
+    if (catalog[0].lensing_catalog) {
+      free (catalog[0].lensing_catalog[0].filename);
+      dvo_catalog_free (catalog[0].lensing_catalog);
+      free (catalog[0].lensing_catalog);
+    }
+    if (catalog[0].lensobj_catalog) {
+      free (catalog[0].lensobj_catalog[0].filename);
+      dvo_catalog_free (catalog[0].lensobj_catalog);
+      free (catalog[0].lensobj_catalog);
+    }
   }
   dvo_catalog_free_data (catalog);
@@ -625,24 +844,37 @@
 
   /* free, initialize data structures */
-  if (catalog[0].average != NULL) {
+  if (catalog[0].average) {
     free (catalog[0].average); 
     catalog[0].Naverage = 0;
     catalog[0].average = NULL;
   }
-  if (catalog[0].measure != NULL) {
+  if (catalog[0].measure) {
     free (catalog[0].measure); 
     catalog[0].Nmeasure = 0;
     catalog[0].measure = NULL;
   }
-  if (catalog[0].missing != NULL) {
+  if (catalog[0].missing) {
     free (catalog[0].missing); 
     catalog[0].Nmissing = 0;
     catalog[0].missing = NULL;
   }
-  if (catalog[0].secfilt != NULL) {
+  if (catalog[0].secfilt) {
     free (catalog[0].secfilt); 
     catalog[0].Nsecf_mem = 0;
     catalog[0].secfilt = NULL;
   }
+  if (catalog[0].lensing) {
+    free (catalog[0].lensing); 
+    catalog[0].Nlensing = 0;
+    catalog[0].lensing = NULL;
+  }
+  if (catalog[0].lensobj) {
+    free (catalog[0].lensobj); 
+    catalog[0].Nlensobj = 0;
+    catalog[0].lensobj = NULL;
+  }
+  if (catalog[0].nOwn_t)      { free (catalog[0].nOwn_t); catalog[0].nOwn_t = NULL; }
+  if (catalog[0].found_t)     { free (catalog[0].found_t); catalog[0].found_t = NULL; }
+  if (catalog[0].foundWarp_t) { free (catalog[0].foundWarp_t); catalog[0].foundWarp_t = NULL; }
 }
 
@@ -733,4 +965,24 @@
       }
     }
+    if (catalog[0].lensing_catalog != NULL) {
+      if (catalog[0].Nlensing_disk == 0) {
+	// need to relock (and re-open) file for close elsewhere
+	status = dvo_catalog_lock (catalog[0].lensing_catalog, lockmode);
+      } else {
+	if (!dvo_catalog_backup (catalog[0].lensing_catalog, FALSE)) {
+	  return FALSE;
+	}
+      }
+    }
+    if (catalog[0].lensobj_catalog != NULL) {
+      if (catalog[0].Nlensobj_disk == 0) {
+	// need to relock (and re-open) file for close elsewhere
+	status = dvo_catalog_lock (catalog[0].lensobj_catalog, lockmode);
+      } else {
+	if (!dvo_catalog_backup (catalog[0].lensobj_catalog, FALSE)) {
+	  return FALSE;
+	}
+      }
+    }
   }
   return TRUE;
@@ -754,5 +1006,5 @@
   status = unlink (tmpfilename);
   if (status) {
-    fprintf (stderr, "failed to unlink catalog %s\n", catalog->filename);
+    fprintf (stderr, "failed to unlink catalog %s~\n", catalog->filename);
     return FALSE;
   }
@@ -774,4 +1026,14 @@
       }
     }
+    if ((catalog[0].lensing_catalog != NULL) && (catalog[0].Nlensing_disk > 0)) {
+      if (!dvo_catalog_unlink_backup (catalog[0].lensing_catalog, FALSE)) {
+	return FALSE;
+      }
+    }
+    if ((catalog[0].lensobj_catalog != NULL) && (catalog[0].Nlensobj_disk > 0)) {
+      if (!dvo_catalog_unlink_backup (catalog[0].lensobj_catalog, FALSE)) {
+	return FALSE;
+      }
+    }
   }
   return TRUE;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_catalog_chipcoords.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_catalog_chipcoords.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_catalog_chipcoords.c	(revision 37403)
@@ -56,6 +56,6 @@
     m = average[i].measureOffset;
     for (j = 0; j < average[i].Nmeasure; j++, m++) {
-      ra  = average[i].R - measure[m].dR / 3600.0;
-      dec = average[i].D - measure[m].dD / 3600.0;
+      ra  = measure[m].R;
+      dec = measure[m].D;
       N = dvo_match_image (image, Nimage, measure[m].t, measure[m].photcode);
       if (N == -1) continue;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_catalog_create.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_catalog_create.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_catalog_create.c	(revision 37403)
@@ -70,4 +70,29 @@
     gfits_modify (&catalog[0].header, "SECFILT", "%s", 1, file);
     free (file);
+
+    /* define lensing catalog file */
+    ALLOCATE (catalog[0].lensing_catalog, Catalog, 1);
+    dvo_catalog_init (catalog[0].lensing_catalog, TRUE);
+
+    /* create basic data for lensing catalog file */
+    gfits_create_header (&catalog[0].lensing_catalog[0].header);
+    ALLOCATE (catalog[0].lensing_catalog[0].filename, char, length);
+    sprintf (catalog[0].lensing_catalog[0].filename, "%s/%s.cpx", path, root);
+    file = filebasename (catalog[0].lensing_catalog[0].filename);
+    gfits_modify (&catalog[0].header, "LENSING", "%s", 1, file);
+    free (file);
+
+    /* define lensobj catalog file */
+    ALLOCATE (catalog[0].lensobj_catalog, Catalog, 1);
+    dvo_catalog_init (catalog[0].lensobj_catalog, TRUE);
+
+    /* create basic data for lensobj catalog file */
+    gfits_create_header (&catalog[0].lensobj_catalog[0].header);
+    ALLOCATE (catalog[0].lensobj_catalog[0].filename, char, length);
+    sprintf (catalog[0].lensobj_catalog[0].filename, "%s/%s.cpy", path, root);
+    file = filebasename (catalog[0].lensobj_catalog[0].filename);
+    gfits_modify (&catalog[0].header, "LENSOBJ", "%s", 1, file);
+    free (file);
+
     free (path);
     free (root);
@@ -84,4 +109,12 @@
     }
     if (dvo_catalog_lock (catalog[0].secfilt_catalog, catalog[0].lockmode) != DVO_CAT_OPEN_EMPTY) {
+      fprintf (stderr, "error with file lock\n");
+      exit (2);
+    }
+    if (dvo_catalog_lock (catalog[0].lensing_catalog, catalog[0].lockmode) != DVO_CAT_OPEN_EMPTY) {
+      fprintf (stderr, "error with file lock\n");
+      exit (2);
+    }
+    if (dvo_catalog_lock (catalog[0].lensobj_catalog, catalog[0].lockmode) != DVO_CAT_OPEN_EMPTY) {
       fprintf (stderr, "error with file lock\n");
       exit (2);
@@ -111,4 +144,6 @@
   ALLOCATE (catalog[0].missing, Missing, 1);
   ALLOCATE (catalog[0].secfilt, SecFilt, 1);
+  ALLOCATE (catalog[0].lensing, Lensing, 1);
+  ALLOCATE (catalog[0].lensobj, Lensobj, 1);
 
   /* setup secondary filters to match photcodes:
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_catalog_mef.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_catalog_mef.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_catalog_mef.c	(revision 37403)
@@ -7,4 +7,6 @@
   off_t Nmeasure;
   off_t Nmissing;
+  off_t Nlensing;
+  off_t Nlensobj;
   off_t Nitems, Nexpect;
   int Nsecfilt;
@@ -22,4 +24,6 @@
   if (!gfits_scan (&catalog[0].header, "NMISS",    OFF_T_FMT, 1,  &Nmissing)) return (FALSE);
   if (!gfits_scan (&catalog[0].header, "NSECFILT", "%d",   1,               &Nsecfilt)) Nsecfilt = 0;
+  if (!gfits_scan (&catalog[0].header, "NLENSING", OFF_T_FMT, 1,  &Nlensing)) return (FALSE);
+  if (!gfits_scan (&catalog[0].header, "NLENSOBJ", OFF_T_FMT, 1,  &Nlensobj)) return (FALSE);
 
   /* the OBJID is a counter that uniquely defines an average entry and never changes.  if
@@ -40,4 +44,6 @@
   catalog[0].Nmiss_disk = Nmissing;
   catalog[0].Nsecf_disk = Naverage * Nsecfilt;
+  catalog[0].Nlensing_disk = Nlensing;
+  catalog[0].Nlensobj_disk = Nlensobj;
 
   /**  Nsecfilt is unusual: it does not list the number of data items in the table
@@ -50,4 +56,6 @@
   catalog[0].missing = NULL;
   catalog[0].secfilt = NULL;
+  catalog[0].lensing = NULL;
+  catalog[0].lensobj = NULL;
 
   /* validate table mode ?*/
@@ -101,5 +109,5 @@
       return (FALSE);
     }
-    catalog[0].measure = FtableToMeasure (&ftable, &catalog[0].Nmeasure, &catalog[0].catformat);
+    catalog[0].measure = FtableToMeasure (&ftable, catalog[0].average, &catalog[0].Nmeasure, &catalog[0].catformat);
     if (Nmeasure != catalog[0].Nmeas_disk) {
       fprintf (stderr, "Warning: mismatch between Nmeasure in PHU and Table headers ("OFF_T_FMT" vs "OFF_T_FMT")\n",  Nmeasure,  catalog[0].Nmeas_disk);
@@ -201,4 +209,54 @@
   }
 
+  /* read Lensing table header */
+  if (!gfits_fread_header (catalog[0].f, &header)) {
+    if (VERBOSE) fprintf (stderr, "can't read table lensing header");
+    return (FALSE);
+  }
+  /* read Lensing table data */
+  if (catalog[0].catflags & LOAD_LENSING) {
+    if (!gfits_fread_ftable_data (catalog[0].f, &ftable, FALSE)) {
+      if (VERBOSE) fprintf (stderr, "can't read table lensing data");
+      return (FALSE);
+    }
+    catalog[0].lensing = FtableToLensing (&ftable, &catalog[0].Nlensing, &catalog[0].catformat);
+    if (Nlensing != catalog[0].Nlensing_disk) {
+      fprintf (stderr, "Warning: mismatch between Nlensing in PHU and Table headers ("OFF_T_FMT" vs "OFF_T_FMT")\n",  Nlensing,  catalog[0].Nlensing_disk);
+    }
+    catalog[0].Nlensing = catalog[0].Nlensing_disk;
+    catalog[0].Nlensing_off = 0;
+  } else {
+    Nbytes = gfits_data_size (&header);
+    fseeko (catalog[0].f, Nbytes, SEEK_CUR);
+    ALLOCATE (catalog[0].lensing, Lensing, 1);
+    catalog[0].Nlensing = 0;
+    catalog[0].Nlensing_off = catalog[0].Nlensing_disk;
+  }
+
+  /* read Lensobj table header */
+  if (!gfits_fread_header (catalog[0].f, &header)) {
+    if (VERBOSE) fprintf (stderr, "can't read table lensobj header");
+    return (FALSE);
+  }
+  /* read Lensobj table data */
+  if (catalog[0].catflags & LOAD_LENSOBJ) {
+    if (!gfits_fread_ftable_data (catalog[0].f, &ftable, FALSE)) {
+      if (VERBOSE) fprintf (stderr, "can't read table lensobj data");
+      return (FALSE);
+    }
+    catalog[0].lensobj = FtableToLensobj (&ftable, &catalog[0].Nlensobj, &catalog[0].catformat);
+    if (Nlensobj != catalog[0].Nlensobj_disk) {
+      fprintf (stderr, "Warning: mismatch between Nlensobj in PHU and Table headers ("OFF_T_FMT" vs "OFF_T_FMT")\n",  Nlensobj,  catalog[0].Nlensobj_disk);
+    }
+    catalog[0].Nlensobj = catalog[0].Nlensobj_disk;
+    catalog[0].Nlensobj_off = 0;
+  } else {
+    Nbytes = gfits_data_size (&header);
+    fseeko (catalog[0].f, Nbytes, SEEK_CUR);
+    ALLOCATE (catalog[0].lensobj, Lensobj, 1);
+    catalog[0].Nlensobj = 0;
+    catalog[0].Nlensobj_off = catalog[0].Nlensobj_disk;
+  }
+
   return (TRUE);
 }
@@ -249,4 +307,6 @@
   gfits_modify (&catalog[0].header, "NMISS",    OFF_T_FMT, 1,  catalog[0].Nmissing);
   gfits_modify (&catalog[0].header, "NSECFILT", "%d",   1,                        Nsecfilt);
+  gfits_modify (&catalog[0].header, "NLENSING", OFF_T_FMT, 1,  catalog[0].Nlensing);
+  gfits_modify (&catalog[0].header, "NLENSOBJ", OFF_T_FMT, 1,  catalog[0].Nlensobj);
   gfits_modify_alt (&catalog[0].header, "EXTEND",   "%t", 1, TRUE);
   gfits_modify (&catalog[0].header, "OBJID",    "%d", 1, catalog[0].objID);
@@ -289,5 +349,5 @@
 
   /* write out Measure table (convert to FITS table format) */
-  MeasureToFtable (&ftable, catalog[0].measure, catalog[0].Nmeasure, catalog[0].catformat);
+  MeasureToFtable (&ftable, catalog[0].average, catalog[0].measure, catalog[0].Nmeasure, catalog[0].catformat);
   if (!gfits_fwrite_Theader (catalog[0].f, &header)) {
     fprintf (stderr, "can't write table header");
@@ -317,4 +377,30 @@
   Nitems = catalog[0].Naverage * Nsecfilt;
   SecFiltToFtable (&ftable, secfilt, Nitems, catalog[0].catformat);
+  if (!gfits_fwrite_Theader (catalog[0].f, &header)) {
+    fprintf (stderr, "can't write table header");
+    goto failure;
+  }
+  if (!gfits_fwrite_table (catalog[0].f, &ftable)) {
+    fprintf (stderr, "can't write table data");
+    goto failure;
+  }
+  gfits_free_table (&ftable);
+  gfits_free_header (&header);
+
+  /* write out Lensing table (convert to FITS table format) */
+  LensingToFtable (&ftable, catalog[0].lensing, catalog[0].Nlensing, catalog[0].catformat);
+  if (!gfits_fwrite_Theader (catalog[0].f, &header)) {
+    fprintf (stderr, "can't write table header");
+    goto failure;
+  }
+  if (!gfits_fwrite_table (catalog[0].f, &ftable)) {
+    fprintf (stderr, "can't write table data");
+    goto failure;
+  }
+  gfits_free_table (&ftable);
+  gfits_free_header (&header);
+
+  /* write out Lensobj table (convert to FITS table format) */
+  LensobjToFtable (&ftable, catalog[0].lensobj, catalog[0].Nlensobj, catalog[0].catformat);
   if (!gfits_fwrite_Theader (catalog[0].f, &header)) {
     fprintf (stderr, "can't write table header");
@@ -356,4 +442,8 @@
   secfilt header
   secfilt table
+  lensing header
+  lensing table
+  lensobj header
+  lensobj table
 */
    
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_catalog_raw.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_catalog_raw.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_catalog_raw.c	(revision 37403)
@@ -90,4 +90,5 @@
       FORMAT_CASE (PS1_V3,    PS1_V3);
       FORMAT_CASE (PS1_V4,    PS1_V4);
+      FORMAT_CASE (PS1_V5,    PS1_V5);
       FORMAT_CASE (PS1_REF,   PS1_REF);
 
@@ -144,5 +145,5 @@
   /* read and convert the measures (use a macro to clean this up?) */
   if (catalog[0].catflags & LOAD_MEAS) {
-    catalog[0].measure = ReadRawMeasure (catalog[0].f, catalog[0].Nmeasure, catalog[0].catformat);
+    catalog[0].measure = ReadRawMeasure (catalog[0].f, catalog[0].average, catalog[0].Nmeasure, catalog[0].catformat);
   } else {
     /* skip over measures */
@@ -284,4 +285,5 @@
   if (catalog[0].catformat == DVO_FORMAT_PS1_V3)          gfits_modify (&catalog[0].header, "FORMAT", "%s", 1, "PS1_V3");
   if (catalog[0].catformat == DVO_FORMAT_PS1_V4)          gfits_modify (&catalog[0].header, "FORMAT", "%s", 1, "PS1_V4");
+  if (catalog[0].catformat == DVO_FORMAT_PS1_V5)          gfits_modify (&catalog[0].header, "FORMAT", "%s", 1, "PS1_V5");
   if (catalog[0].catformat == DVO_FORMAT_PS1_REF)         gfits_modify (&catalog[0].header, "FORMAT", "%s", 1, "PS1_REF");
 
@@ -303,5 +305,5 @@
   /* write averages and measures */
   WriteRawAverage (f, catalog[0].average, catalog[0].Naverage, catalog[0].catformat, primary);
-  WriteRawMeasure (f, catalog[0].measure, catalog[0].Nmeasure, catalog[0].catformat);
+  WriteRawMeasure (f, catalog[0].average, catalog[0].measure, catalog[0].Nmeasure, catalog[0].catformat);
 
   /* write missing data */
@@ -387,4 +389,5 @@
       FORMAT_CASE (PS1_V3,    PS1_V3);
       FORMAT_CASE (PS1_V4,    PS1_V4);
+      FORMAT_CASE (PS1_V5,    PS1_V5);
       FORMAT_CASE (PS1_REF,   PS1_REF);
 
@@ -438,4 +441,5 @@
       FORMAT_CASE (PS1_V3,    PS1_V3);
       FORMAT_CASE (PS1_V4,    PS1_V4);
+      FORMAT_CASE (PS1_V5,    PS1_V5);
       FORMAT_CASE (PS1_REF,   PS1_REF);
 
@@ -451,5 +455,5 @@
 /** Average / Raw Table conversions **/
 
-Measure *ReadRawMeasure (FILE *f, off_t Nmeasure, char format) {
+Measure *ReadRawMeasure (FILE *f, Average *average, off_t Nmeasure, char format) {
 
   Measure *measure;
@@ -467,5 +471,5 @@
       } \
       gfits_convert_Measure_##TYPE (tmpMeasure, sizeof(Measure_##TYPE), Nmeasure); \
-      measure = Measure_##TYPE##_ToInternal (tmpMeasure, Nmeasure); \
+      measure = Measure_##TYPE##_ToInternal (average, tmpMeasure, Nmeasure); \
       free (tmpMeasure); \
       break; }
@@ -481,4 +485,55 @@
       }
       gfits_convert_Measure (measure, sizeof(Measure), Nmeasure);
+      break; }
+
+      FORMAT_CASE (LONEOS, Loneos);
+      FORMAT_CASE (ELIXIR, Elixir);
+      FORMAT_CASE (PANSTARRS_DEV_0, Panstarrs_DEV_0);
+      FORMAT_CASE (PANSTARRS_DEV_1, Panstarrs_DEV_1);
+      FORMAT_CASE (PS1_DEV_1, PS1_DEV_1);
+      FORMAT_CASE (PS1_DEV_2, PS1_DEV_2);
+      FORMAT_CASE (PS1_V1,    PS1_V1);
+      FORMAT_CASE (PS1_V2,    PS1_V2);
+      FORMAT_CASE (PS1_V3,    PS1_V3);
+      FORMAT_CASE (PS1_V5,    PS1_V5);
+      FORMAT_CASE (PS1_REF,   PS1_REF);
+
+    default:
+      fprintf (stderr, "error reading measures\n");
+      return (NULL);
+  }
+# undef FORMAT_CASE
+
+  return (measure);
+}
+
+/* accepts and converts internal measure formats and outputs 
+   raw data in the specified format */
+int WriteRawMeasure (FILE *f, Average *average, Measure *measure, off_t Nmeasure, char format) {
+
+// this macro generates the case statements for each type
+# define FORMAT_CASE(NAME,TYPE) \
+    case DVO_FORMAT_##NAME: { \
+      off_t nitems; \
+      Measure_##TYPE *tmpMeasure; \
+      tmpMeasure = MeasureInternalTo_##TYPE (average, measure, Nmeasure); \
+      gfits_convert_Measure_##TYPE (tmpMeasure, sizeof(Measure_##TYPE), Nmeasure); \
+      nitems = fwrite (tmpMeasure, sizeof(Measure_##TYPE), Nmeasure, f); \
+      free (tmpMeasure); \
+      if (nitems != Nmeasure) { \
+	fprintf (stderr, "failed to write measures ("OFF_T_FMT" vs "OFF_T_FMT")\n",  nitems,  Nmeasure); \
+	return (FALSE); \
+      } \
+      break; }
+
+  switch (format) {
+    case DVO_FORMAT_INTERNAL: {
+      off_t nitems;
+      gfits_convert_Measure (measure, sizeof(Measure), Nmeasure);
+      nitems = fwrite (measure, sizeof(Measure), Nmeasure, f);
+      if (nitems != Nmeasure) {
+	fprintf (stderr, "failed to write measures ("OFF_T_FMT" vs "OFF_T_FMT")\n",  nitems,  Nmeasure);
+	return (FALSE);
+      }
       break; }
 
@@ -493,55 +548,5 @@
       FORMAT_CASE (PS1_V3,    PS1_V3);
       FORMAT_CASE (PS1_V4,    PS1_V4);
-      FORMAT_CASE (PS1_REF,   PS1_REF);
-
-    default:
-      fprintf (stderr, "error reading measures\n");
-      return (NULL);
-  }
-# undef FORMAT_CASE
-
-  return (measure);
-}
-
-/* accepts and converts internal measure formats and outputs 
-   raw data in the specified format */
-int WriteRawMeasure (FILE *f, Measure *measure, off_t Nmeasure, char format) {
-
-// this macro generates the case statements for each type
-# define FORMAT_CASE(NAME,TYPE) \
-    case DVO_FORMAT_##NAME: { \
-      off_t nitems; \
-      Measure_##TYPE *tmpMeasure; \
-      tmpMeasure = MeasureInternalTo_##TYPE (measure, Nmeasure); \
-      gfits_convert_Measure_##TYPE (tmpMeasure, sizeof(Measure_##TYPE), Nmeasure); \
-      nitems = fwrite (tmpMeasure, sizeof(Measure_##TYPE), Nmeasure, f); \
-      free (tmpMeasure); \
-      if (nitems != Nmeasure) { \
-	fprintf (stderr, "failed to write measures ("OFF_T_FMT" vs "OFF_T_FMT")\n",  nitems,  Nmeasure); \
-	return (FALSE); \
-      } \
-      break; }
-
-  switch (format) {
-    case DVO_FORMAT_INTERNAL: {
-      off_t nitems;
-      gfits_convert_Measure (measure, sizeof(Measure), Nmeasure);
-      nitems = fwrite (measure, sizeof(Measure), Nmeasure, f);
-      if (nitems != Nmeasure) {
-	fprintf (stderr, "failed to write measures ("OFF_T_FMT" vs "OFF_T_FMT")\n",  nitems,  Nmeasure);
-	return (FALSE);
-      }
-      break; }
-
-      FORMAT_CASE (LONEOS, Loneos);
-      FORMAT_CASE (ELIXIR, Elixir);
-      FORMAT_CASE (PANSTARRS_DEV_0, Panstarrs_DEV_0);
-      FORMAT_CASE (PANSTARRS_DEV_1, Panstarrs_DEV_1);
-      FORMAT_CASE (PS1_DEV_1, PS1_DEV_1);
-      FORMAT_CASE (PS1_DEV_2, PS1_DEV_2);
-      FORMAT_CASE (PS1_V1,    PS1_V1);
-      FORMAT_CASE (PS1_V2,    PS1_V2);
-      FORMAT_CASE (PS1_V3,    PS1_V3);
-      FORMAT_CASE (PS1_V4,    PS1_V4);
+      FORMAT_CASE (PS1_V5,    PS1_V5);
       FORMAT_CASE (PS1_REF,   PS1_REF);
 
@@ -599,4 +604,5 @@
       FORMAT_CASE (PS1_V3,    PS1_V3);
       FORMAT_CASE (PS1_V4,    PS1_V4);
+      FORMAT_CASE (PS1_V5,    PS1_V5);
       FORMAT_CASE (PS1_REF,   PS1_REF);
 
@@ -650,4 +656,5 @@
       FORMAT_CASE (PS1_V3,    PS1_V3);
       FORMAT_CASE (PS1_V4,    PS1_V4);
+      FORMAT_CASE (PS1_V5,    PS1_V5);
       FORMAT_CASE (PS1_REF,   PS1_REF);
 
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_catalog_split.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_catalog_split.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_catalog_split.c	(revision 37403)
@@ -134,4 +134,8 @@
   if (!gfits_scan (&catalog[0].header, name,  "%s", 1, string)) {
     free (path);
+    // databases created prior to ~2014.07.01 did not have the LENSING or LENSOBJ paths in their headers.
+    // in these cases, we do not try to lock or open the relevant file
+    if (!strcmp (name, "LENSING")) return (DVO_CAT_OPEN_EMPTY);
+    if (!strcmp (name, "LENSOBJ")) return (DVO_CAT_OPEN_EMPTY);
     return (DVO_CAT_OPEN_FAIL);
   }
@@ -161,5 +165,5 @@
   fseeko (subcat[0].f, Nskip, SEEK_CUR);
 
-  /* read Measure table header */
+  /* read table header */
   if (!gfits_fread_header (subcat[0].f, header)) {
     if (VERBOSE) fprintf (stderr, "can't read %s PHU header\n", name);
@@ -176,4 +180,6 @@
   off_t Nmeasure;
   off_t Nmissing;
+  off_t Nlensing;
+  off_t Nlensobj;
   off_t Nitems;
   int status, Nsecfilt;
@@ -190,8 +196,11 @@
 
   /* get the components from the header - these duplicate information in the split files (NAXIS2) */
+  // NSTARS, NMEAS, NMISS are required; NLENSING, NLENSOBJ are not (0 if not found)
   if (!gfits_scan (&catalog[0].header, "NSTARS",   OFF_T_FMT, 1,  &Naverage)) return (FALSE);
   if (!gfits_scan (&catalog[0].header, "NMEAS",    OFF_T_FMT, 1,  &Nmeasure)) return (FALSE);
   if (!gfits_scan (&catalog[0].header, "NMISS",    OFF_T_FMT, 1,  &Nmissing)) return (FALSE);
-  if (!gfits_scan (&catalog[0].header, "NSECFILT", "%d",   1,               &Nsecfilt)) Nsecfilt = 0;
+  if (!gfits_scan (&catalog[0].header, "NSECFILT",      "%d", 1,  &Nsecfilt)) Nsecfilt = 0;
+  if (!gfits_scan (&catalog[0].header, "NLENSING", OFF_T_FMT, 1,  &Nlensing)) Nlensing = 0;
+  if (!gfits_scan (&catalog[0].header, "NLENSOBJ", OFF_T_FMT, 1,  &Nlensobj)) Nlensobj = 0;
 
   /* the OBJID is a counter that uniquely defines an average entry and never changes.  if
@@ -212,4 +221,6 @@
   catalog[0].Nmiss_disk = Nmissing;
   catalog[0].Nsecf_disk = Naverage * Nsecfilt;
+  catalog[0].Nlensing_disk = Nlensing;
+  catalog[0].Nlensobj_disk = Nlensobj;
 
   /**  Nsecfilt is unusual: it does not list the number of data items in the table
@@ -222,4 +233,6 @@
   catalog[0].missing = NULL;
   catalog[0].secfilt = NULL;
+  catalog[0].lensing = NULL;
+  catalog[0].lensobj = NULL;
 
   /*** Average Table ***/
@@ -277,5 +290,5 @@
     }
     /* convert data format to internal : returns number of row read in Nmeasure */
-    catalog[0].measure = FtableToMeasure (&ftable, &Nmeasure, &catalog[0].catformat);
+    catalog[0].measure = FtableToMeasure (&ftable, catalog[0].average, &Nmeasure, &catalog[0].catformat);
     if (Nmeasure != catalog[0].Nmeas_disk) {
       fprintf (stderr, "Warning: mismatch between Nmeasure in PHU and Table headers ("OFF_T_FMT" vs "OFF_T_FMT")\n",  Nmeasure,  catalog[0].Nmeas_disk);
@@ -372,4 +385,84 @@
   gfits_free_header (ftable.header);
 
+  /*** Lensing Table ***/
+  if (!(catalog[0].catflags & SKIP_LENSING)) {
+    // unless we specify 'skip', we still need to load the Lensing table
+    status = dvo_catalog_open_subcat (catalog, &catalog[0].lensing_catalog, ftable.header, "LENSING", VERBOSE);
+    if (status == DVO_CAT_OPEN_FAIL) {
+      return (FALSE);
+    }
+    // the Lensing file need not exist, unless we expect data to exist
+    if ((status == DVO_CAT_OPEN_EMPTY) && (catalog[0].Nlensing_disk > 0)) {
+      return (FALSE);
+    }
+  }
+  if ((status != DVO_CAT_OPEN_EMPTY) && (catalog[0].catflags & LOAD_LENSING)) {
+    // only read the Lensing table if the file actually exists
+    /* read Lensing table data */
+    if (!gfits_fread_ftable_data (catalog[0].lensing_catalog[0].f, &ftable, FALSE)) {
+      if (VERBOSE) fprintf (stderr, "can't read table lensing data\n");
+      return (FALSE);
+    }
+    /* convert data format to internal : returns number of row read in Nlensing */
+    catalog[0].lensing = FtableToLensing (&ftable, &Nlensing, &catalog[0].catformat);
+    if (Nlensing != catalog[0].Nlensing_disk) {
+      fprintf (stderr, "Warning: mismatch between Nlensing in PHU and Table headers ("OFF_T_FMT" vs "OFF_T_FMT")\n",  Nlensing,  catalog[0].Nlensing_disk);
+    }
+    catalog[0].Nlensing = catalog[0].Nlensing_disk;
+    catalog[0].Nlensing_off = 0;
+  } else {
+    if (catalog[0].lensing_catalog) {
+      gfits_free_header (&catalog[0].lensing_catalog[0].header);
+    } else {
+      ALLOCATE (catalog[0].lensing_catalog, Catalog, 1);
+      dvo_catalog_init (catalog[0].lensing_catalog, TRUE);
+    }
+    gfits_create_header (&catalog[0].lensing_catalog[0].header);
+    ALLOCATE (catalog[0].lensing, Lensing, 1);
+    catalog[0].Nlensing = 0;
+    catalog[0].Nlensing_off = catalog[0].Nlensing_disk;
+  }
+  gfits_free_header (&header);
+
+  /*** Lensobj Table ***/
+  if (!(catalog[0].catflags & SKIP_LENSOBJ)) {
+    // unless we specify 'skip', we still need to load the 
+    status = dvo_catalog_open_subcat (catalog, &catalog[0].lensobj_catalog, ftable.header, "LENSOBJ", VERBOSE);
+    if (status == DVO_CAT_OPEN_FAIL) {
+      return (FALSE);
+    }
+    // the Lensobj file need not exist, unless we expect data to exist
+    if ((status == DVO_CAT_OPEN_EMPTY) && (catalog[0].Nlensobj_disk > 0)) {
+      return (FALSE);
+    }
+  }
+  if ((status != DVO_CAT_OPEN_EMPTY) && (catalog[0].catflags & LOAD_LENSOBJ)) {
+    // only read the Lensobj table if the file actually exists
+    /* read Lensobj table data */
+    if (!gfits_fread_ftable_data (catalog[0].lensobj_catalog[0].f, &ftable, FALSE)) {
+      if (VERBOSE) fprintf (stderr, "can't read table lensobj data\n");
+      return (FALSE);
+    }
+    /* convert data format to internal : returns number of row read in Nlensobj */
+    catalog[0].lensobj = FtableToLensobj (&ftable, &Nlensobj, &catalog[0].catformat);
+    if (Nlensobj != catalog[0].Nlensobj_disk) {
+      fprintf (stderr, "Warning: mismatch between Nlensobj in PHU and Table headers ("OFF_T_FMT" vs "OFF_T_FMT")\n",  Nlensobj,  catalog[0].Nlensobj_disk);
+    }
+    catalog[0].Nlensobj = catalog[0].Nlensobj_disk;
+    catalog[0].Nlensobj_off = 0;
+  } else {
+    if (catalog[0].lensobj_catalog) {
+      gfits_free_header (&catalog[0].lensobj_catalog[0].header);
+    } else {
+      ALLOCATE (catalog[0].lensobj_catalog, Catalog, 1);
+      dvo_catalog_init (catalog[0].lensobj_catalog, TRUE);
+    }
+    gfits_create_header (&catalog[0].lensobj_catalog[0].header);
+    ALLOCATE (catalog[0].lensobj, Lensobj, 1);
+    catalog[0].Nlensobj = 0;
+    catalog[0].Nlensobj_off = catalog[0].Nlensobj_disk;
+  }
+  gfits_free_header (&header);
+
   return (TRUE);
 }
@@ -380,5 +473,5 @@
 
   off_t Nbytes;
-  off_t Naverage, Nexpect, Nitems, Nmeasure, Nmissing;
+  off_t Naverage, Nexpect, Nitems, Nmeasure, Nmissing, Nlensing, Nlensobj;
   Header header;
   FTable ftable;
@@ -476,5 +569,5 @@
 
     /* convert data format to internal : returns number of row read in Nmeasure */
-    catalog[0].measure = FtableToMeasure (&ftable, &Nmeasure, &catalog[0].catformat);
+    catalog[0].measure = FtableToMeasure (&ftable, catalog[0].average, &Nmeasure, &catalog[0].catformat);
     if (Nmeasure != Nrows) {
       // XXX this condition denotes the eof has been reached; not an error or a warning
@@ -519,4 +612,67 @@
     catalog[0].Nmiss_off = start;
   }
+
+  // XXX check the open status of the catalog
+  if (catalog[0].catflags & LOAD_LENSING) {
+
+    Catalog *subcat = catalog[0].lensing_catalog;
+
+    /* move pointer past header -- must be already read (load_catalog) */
+    Nbytes = subcat[0].header.datasize + gfits_data_size (&subcat[0].header);
+    fseeko (subcat[0].f, Nbytes, SEEK_SET);
+
+    /* read Lensing table header */
+    if (!gfits_fread_header (subcat[0].f, &header)) {
+      if (VERBOSE) fprintf (stderr, "can't read table lensing header");
+      return (FALSE);
+    }
+    /* read Lensing table data : format is irrelevant here */
+    if (!gfits_fread_ftable_range (subcat[0].f, &ftable, start, Nrows)) {
+      if (VERBOSE) fprintf (stderr, "can't read table lensing data");
+      return (FALSE);
+    }
+
+    /* convert data format to internal : returns number of row read in Nlensing */
+    catalog[0].lensing = FtableToLensing (&ftable, &Nlensing, &catalog[0].catformat);
+    if (Nlensing != Nrows) {
+      // XXX this condition denotes the eof has been reached; not an error or a warning
+      // fprintf (stderr, "Warning: mismatch between Nlensing in PHU and Table headers ("OFF_T_FMT" vs "OFF_T_FMT")\n",  Nlensing,  Nrows);
+    }
+    gfits_free_header (&header);
+    catalog[0].Nlensing = Nlensing;
+    catalog[0].Nlensing_off = start;
+  }
+
+  // XXX check the open status of the catalog
+  if (catalog[0].catflags & LOAD_LENSOBJ) {
+
+    Catalog *subcat = catalog[0].lensobj_catalog;
+
+    /* move pointer past header -- must be already read (load_catalog) */
+    Nbytes = subcat[0].header.datasize + gfits_data_size (&subcat[0].header);
+    fseeko (subcat[0].f, Nbytes, SEEK_SET);
+
+    /* read Lensobj table header */
+    if (!gfits_fread_header (subcat[0].f, &header)) {
+      if (VERBOSE) fprintf (stderr, "can't read table lensobj header");
+      return (FALSE);
+    }
+    /* read Lensobj table data : format is irrelevant here */
+    if (!gfits_fread_ftable_range (subcat[0].f, &ftable, start, Nrows)) {
+      if (VERBOSE) fprintf (stderr, "can't read table lensobj data");
+      return (FALSE);
+    }
+
+    /* convert data format to internal : returns number of row read in Nlensobj */
+    catalog[0].lensobj = FtableToLensobj (&ftable, &Nlensobj, &catalog[0].catformat);
+    if (Nlensobj != Nrows) {
+      // XXX this condition denotes the eof has been reached; not an error or a warning
+      // fprintf (stderr, "Warning: mismatch between Nlensobj in PHU and Table headers ("OFF_T_FMT" vs "OFF_T_FMT")\n",  Nlensobj,  Nrows);
+    }
+    gfits_free_header (&header);
+    catalog[0].Nlensobj = Nlensobj;
+    catalog[0].Nlensobj_off = start;
+  }
+
   return (TRUE);
 }
@@ -530,5 +686,5 @@
   SecFilt *primary, *secfilt;
   int Nsecfilt;
-  off_t Naves_disk_new, Nmeas_disk_new, Nmiss_disk_new, Nsecf_disk_new;
+  off_t Naves_disk_new, Nmeas_disk_new, Nmiss_disk_new, Nsecf_disk_new, Nlensing_disk_new, Nlensobj_disk_new;
   off_t first, start, Nrows;
 
@@ -561,4 +717,6 @@
   Nmiss_disk_new = MAX (catalog[0].Nmiss_disk, catalog[0].Nmissing + catalog[0].Nmiss_off);
   Nsecf_disk_new = MAX (catalog[0].Nsecf_disk, catalog[0].Naverage*Nsecfilt + catalog[0].Nsecf_off);
+  Nlensing_disk_new = MAX (catalog[0].Nlensing_disk, catalog[0].Nlensing + catalog[0].Nlensing_off);
+  Nlensobj_disk_new = MAX (catalog[0].Nlensobj_disk, catalog[0].Nlensobj + catalog[0].Nlensobj_off);
 
   /* make sure header is consistent with data */
@@ -567,4 +725,6 @@
   gfits_modify (&catalog[0].header, "NMISS",    OFF_T_FMT, 1,  Nmiss_disk_new);
   gfits_modify (&catalog[0].header, "NSECFILT", "%d",   1, Nsecfilt);
+  gfits_modify (&catalog[0].header, "NLENSING", OFF_T_FMT, 1,  Nlensing_disk_new);
+  gfits_modify (&catalog[0].header, "NLENSOBJ", OFF_T_FMT, 1,  Nlensobj_disk_new);
   gfits_modify_alt (&catalog[0].header, "EXTEND",   "%t", 1, TRUE);
   gfits_modify (&catalog[0].header, "OBJID",    "%d", 1, catalog[0].objID);
@@ -621,6 +781,6 @@
     assert (catalog[0].Nmeas_disk >= catalog[0].Nmeas_off);
 
-    // convert to external table format
-    if (!MeasureToFtable (&ftable, &catalog[0].measure[first], Nrows, catalog[0].catformat)) {
+    // convert to external table format (note that the block above does not damage or free catalog.average) 
+    if (!MeasureToFtable (&ftable, catalog[0].average, &catalog[0].measure[first], Nrows, catalog[0].catformat)) {
       fprintf (stderr, "trouble converting format\n");
       goto failure;
@@ -679,4 +839,58 @@
     if (!dvo_catalog_save_subcat (catalog[0].secfilt_catalog, &ftable, start, Nrows, catalog[0].Nsecf_disk, Nsecf_disk_new)) {
       fprintf (stderr, "failure writing SecFilt table\n");
+      goto failure;
+    }
+    gfits_free_header (&header);
+    gfits_free_table (&ftable);
+  }
+
+  /*** Lensing Table ***/
+  if ((catalog[0].catflags & LOAD_LENSING) && (catalog[0].lensing != NULL)) {
+
+    first  = 0;                    // first row in memory to write
+    start  = catalog[0].Nlensing_off; // first disk row to write
+    Nrows  = catalog[0].Nlensing - first;
+
+    assert (Nrows >= 0);
+    assert (first >= 0);
+    assert (first <= catalog[0].Nlensing);
+    assert (catalog[0].Nlensing_disk >= catalog[0].Nlensing_off);
+
+    // convert to external table format (note that the block above does not damage or free catalog.average) 
+    if (!LensingToFtable (&ftable, &catalog[0].lensing[first], Nrows, catalog[0].catformat)) {
+      fprintf (stderr, "trouble converting format\n");
+      goto failure;
+    }
+
+    // write out Lensing table
+    if (!dvo_catalog_save_subcat (catalog[0].lensing_catalog, &ftable, start, Nrows, catalog[0].Nlensing_disk, Nlensing_disk_new)) {
+      fprintf (stderr, "trouble writing Lensing table\n");
+      goto failure;
+    }
+    gfits_free_header (&header);
+    gfits_free_table (&ftable);
+  }
+
+  /*** Lensobj Table ***/
+  if ((catalog[0].catflags & LOAD_LENSOBJ) && (catalog[0].lensobj != NULL)) {
+
+    first  = 0;                    // first row in memory to write
+    start  = catalog[0].Nlensobj_off; // first disk row to write
+    Nrows  = catalog[0].Nlensobj - first;
+
+    assert (Nrows >= 0);
+    assert (first >= 0);
+    assert (first <= catalog[0].Nlensobj);
+    assert (catalog[0].Nlensobj_disk >= catalog[0].Nlensobj_off);
+
+    // convert to external table format (note that the block above does not damage or free catalog.average) 
+    if (!LensobjToFtable (&ftable, &catalog[0].lensobj[first], Nrows, catalog[0].catformat)) {
+      fprintf (stderr, "trouble converting format\n");
+      goto failure;
+    }
+
+    // write out Lensobj table
+    if (!dvo_catalog_save_subcat (catalog[0].lensobj_catalog, &ftable, start, Nrows, catalog[0].Nlensobj_disk, Nlensobj_disk_new)) {
+      fprintf (stderr, "trouble writing Lensobj table\n");
       goto failure;
     }
@@ -711,5 +925,5 @@
   SecFilt *primary, *secfilt;
   int Nsecfilt;
-  off_t Naves_disk_new, Nmeas_disk_new, Nmiss_disk_new, Nsecf_disk_new;
+  off_t Naves_disk_new, Nmeas_disk_new, Nmiss_disk_new, Nsecf_disk_new, Nlensing_disk_new, Nlensobj_disk_new;
   off_t first, start, Nrows;
 
@@ -734,4 +948,12 @@
   if (catalog[0].Nsecf_off > 0) {
     fprintf (stderr, "ERROR: only partial catalog (Secfilt) was loaded\n");
+    goto failure;
+  }
+  if (catalog[0].Nlensing_off > 0) {
+    fprintf (stderr, "ERROR: only partial catalog (Lensing) was loaded\n");
+    goto failure;
+  }
+  if (catalog[0].Nlensobj_off > 0) {
+    fprintf (stderr, "ERROR: only partial catalog (Lensobj) was loaded\n");
     goto failure;
   }
@@ -760,4 +982,6 @@
   Nmiss_disk_new = catalog[0].Nmissing;
   Nsecf_disk_new = catalog[0].Naverage*Nsecfilt;
+  Nlensing_disk_new = catalog[0].Nlensing;
+  Nlensobj_disk_new = catalog[0].Nlensobj;
 
   /* make sure header is consistent with data */
@@ -766,4 +990,6 @@
   gfits_modify (&catalog[0].header, "NMISS",    OFF_T_FMT, 1,  Nmiss_disk_new);
   gfits_modify (&catalog[0].header, "NSECFILT", "%d", 1, Nsecfilt);
+  gfits_modify (&catalog[0].header, "NLENSING", OFF_T_FMT, 1,  Nlensing_disk_new);
+  gfits_modify (&catalog[0].header, "NLENSOBJ", OFF_T_FMT, 1,  Nlensobj_disk_new);
   gfits_modify_alt (&catalog[0].header, "EXTEND",   "%t", 1, TRUE);
   gfits_modify (&catalog[0].header, "OBJID",    "%d", 1, catalog[0].objID);
@@ -821,5 +1047,5 @@
 
     // convert to external table format
-    if (!MeasureToFtable (&ftable, &catalog[0].measure[first], Nrows, catalog[0].catformat)) {
+    if (!MeasureToFtable (&ftable, catalog[0].average, &catalog[0].measure[first], Nrows, catalog[0].catformat)) {
       fprintf (stderr, "trouble converting format\n");
       goto failure;
@@ -878,4 +1104,58 @@
     if (!dvo_catalog_save_subcat (catalog[0].secfilt_catalog, &ftable, start, Nrows, catalog[0].Nsecf_disk, Nsecf_disk_new)) {
       fprintf (stderr, "failure writing SecFilt table\n");
+      goto failure;
+    }
+    gfits_free_header (&header);
+    gfits_free_table (&ftable);
+  }
+
+  /*** Lensing Table ***/
+  if ((catalog[0].catflags & LOAD_LENSING) && (catalog[0].lensing != NULL)) {
+
+    first  = 0;                    // first row in memory to write
+    start  = catalog[0].Nlensing_off; // first disk row to write
+    Nrows  = catalog[0].Nlensing - first;
+
+    assert (Nrows >= 0);
+    assert (first >= 0);
+    assert (first <= catalog[0].Nlensing);
+    assert (catalog[0].Nlensing_disk >= catalog[0].Nlensing_off);
+
+    // convert to external table format
+    if (!LensingToFtable (&ftable, &catalog[0].lensing[first], Nrows, catalog[0].catformat)) {
+      fprintf (stderr, "trouble converting format\n");
+      goto failure;
+    }
+
+    // write out Lensing table
+    if (!dvo_catalog_save_subcat (catalog[0].lensing_catalog, &ftable, start, Nrows, catalog[0].Nlensing_disk, Nlensing_disk_new)) {
+      fprintf (stderr, "trouble writing Lensing table\n");
+      goto failure;
+    }
+    gfits_free_header (&header);
+    gfits_free_table (&ftable);
+  }
+
+  /*** Lensobj Table ***/
+  if ((catalog[0].catflags & LOAD_LENSOBJ) && (catalog[0].lensobj != NULL)) {
+
+    first  = 0;                    // first row in memory to write
+    start  = catalog[0].Nlensobj_off; // first disk row to write
+    Nrows  = catalog[0].Nlensobj - first;
+
+    assert (Nrows >= 0);
+    assert (first >= 0);
+    assert (first <= catalog[0].Nlensobj);
+    assert (catalog[0].Nlensobj_disk >= catalog[0].Nlensobj_off);
+
+    // convert to external table format
+    if (!LensobjToFtable (&ftable, &catalog[0].lensobj[first], Nrows, catalog[0].catformat)) {
+      fprintf (stderr, "trouble converting format\n");
+      goto failure;
+    }
+
+    // write out Lensobj table
+    if (!dvo_catalog_save_subcat (catalog[0].lensobj_catalog, &ftable, start, Nrows, catalog[0].Nlensobj_disk, Nlensobj_disk_new)) {
+      fprintf (stderr, "trouble writing Lensobj table\n");
       goto failure;
     }
@@ -909,5 +1189,5 @@
   SecFilt *primary, *secfilt;
   int Nsecfilt;
-  off_t Naves_disk_new, Nmeas_disk_new, Nmiss_disk_new, Nsecf_disk_new;
+  off_t Naves_disk_new, Nmeas_disk_new, Nmiss_disk_new, Nsecf_disk_new, Nlensing_disk_new, Nlensobj_disk_new;
   off_t first, start, Nrows;
 
@@ -939,4 +1219,6 @@
   Nmiss_disk_new = MAX (catalog[0].Nmiss_disk, catalog[0].Nmissing + catalog[0].Nmiss_off);
   Nsecf_disk_new = MAX (catalog[0].Nsecf_disk, catalog[0].Naverage*Nsecfilt + catalog[0].Nsecf_off);
+  Nlensing_disk_new = MAX (catalog[0].Nlensing_disk, catalog[0].Nlensing + catalog[0].Nlensing_off);
+  Nlensobj_disk_new = MAX (catalog[0].Nlensobj_disk, catalog[0].Nlensobj + catalog[0].Nlensobj_off);
 
   /* make sure header is consistent with data */
@@ -945,4 +1227,6 @@
   gfits_modify (&catalog[0].header, "NMISS",    OFF_T_FMT, 1,  Nmiss_disk_new);
   gfits_modify (&catalog[0].header, "NSECFILT", "%d", 1, Nsecfilt);
+  gfits_modify (&catalog[0].header, "NLENSING", OFF_T_FMT, 1,  Nlensing_disk_new);
+  gfits_modify (&catalog[0].header, "NLENSOBJ", OFF_T_FMT, 1,  Nlensobj_disk_new);
   gfits_modify_alt (&catalog[0].header, "EXTEND",   "%t", 1, TRUE);
   gfits_modify (&catalog[0].header, "OBJID",    "%d", 1, catalog[0].objID);
@@ -1000,5 +1284,6 @@
 
     // convert to external table format
-    if (!MeasureToFtable (&ftable, &catalog[0].measure[first], Nrows, catalog[0].catformat)) {
+    // XXX does catalog.measure have averef correctly set up?
+    if (!MeasureToFtable (&ftable, catalog[0].average, &catalog[0].measure[first], Nrows, catalog[0].catformat)) {
       fprintf (stderr, "trouble converting format\n");
       goto failure;
@@ -1058,4 +1343,60 @@
     if (!dvo_catalog_save_subcat (catalog[0].secfilt_catalog, &ftable, start, Nrows, catalog[0].Nsecf_disk, Nsecf_disk_new)) {
       fprintf (stderr, "failure writing SecFilt table\n");
+      goto failure;
+    }
+    gfits_free_header (&header);
+    gfits_free_table (&ftable);
+  }
+
+  /*** Lensing Table ***/
+  if (catalog[0].lensing != NULL) {
+
+    first  = catalog[0].Nlensing_disk - catalog[0].Nlensing_off;  // first row in memory to write
+    start  = catalog[0].Nlensing_disk; // first disk row to write
+    Nrows  = catalog[0].Nlensing - first;
+
+    assert (Nrows >= 0);
+    assert (first >= 0);
+    assert (first <= catalog[0].Nlensing);
+    assert (catalog[0].Nlensing_disk >= catalog[0].Nlensing_off);
+
+    // convert to external table format
+    // XXX does catalog.lensing have averef correctly set up?
+    if (!LensingToFtable (&ftable, &catalog[0].lensing[first], Nrows, catalog[0].catformat)) {
+      fprintf (stderr, "trouble converting format\n");
+      goto failure;
+    }
+
+    // write out Lensing table
+    if (!dvo_catalog_save_subcat (catalog[0].lensing_catalog, &ftable, start, Nrows, catalog[0].Nlensing_disk, Nlensing_disk_new)) {
+      fprintf (stderr, "trouble writing Lensing table\n");
+      goto failure;
+    }
+    gfits_free_header (&header);
+    gfits_free_table (&ftable);
+  }
+
+  /*** Lensobj Table ***/
+  if (catalog[0].lensobj != NULL) {
+
+    first  = catalog[0].Nlensobj_disk - catalog[0].Nlensobj_off;  // first row in memory to write
+    start  = catalog[0].Nlensobj_disk; // first disk row to write
+    Nrows  = catalog[0].Nlensobj - first;
+
+    assert (Nrows >= 0);
+    assert (first >= 0);
+    assert (first <= catalog[0].Nlensobj);
+    assert (catalog[0].Nlensobj_disk >= catalog[0].Nlensobj_off);
+
+    // convert to external table format
+    // XXX does catalog.lensobj have averef correctly set up?
+    if (!LensobjToFtable (&ftable, &catalog[0].lensobj[first], Nrows, catalog[0].catformat)) {
+      fprintf (stderr, "trouble converting format\n");
+      goto failure;
+    }
+
+    // write out Lensobj table
+    if (!dvo_catalog_save_subcat (catalog[0].lensobj_catalog, &ftable, start, Nrows, catalog[0].Nlensobj_disk, Nlensobj_disk_new)) {
+      fprintf (stderr, "trouble writing Lensobj table\n");
       goto failure;
     }
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert.c	(revision 37403)
@@ -41,4 +41,5 @@
   CONVERT_FORMAT ("DVO_AVERAGE_PS1_V3",          PS1_V3);
   CONVERT_FORMAT ("DVO_AVERAGE_PS1_V4",          PS1_V4);
+  CONVERT_FORMAT ("DVO_AVERAGE_PS1_V5",          PS1_V5);
   CONVERT_FORMAT ("DVO_AVERAGE_PS1_REF",         PS1_REF);
 # undef CONVERT_FORMAT
@@ -76,4 +77,18 @@
     free (tmpAverage);
     *format = DVO_FORMAT_PS1_V4;
+    return (average); 
+  }
+
+  // block to convert old tables (PS1_V5 versions made during development)
+  if (!strcmp (extname, "DVO_AVERAGE_PS1_V5") && (ftable[0].header[0].Naxis[0] == 184)) {
+    Average_PS1_V5alt *tmpAverage;
+    tmpAverage = gfits_table_get_Average_PS1_V5alt (ftable, Naverage, NULL);
+    if (!tmpAverage) {
+      fprintf (stderr, "ERROR: failed to read averages\n");
+      exit (2);
+    }
+    average = Average_PS1_V5alt_ToInternal (tmpAverage, *Naverage);
+    free (tmpAverage);
+    *format = DVO_FORMAT_PS1_V5;
     return (average); 
   }
@@ -112,4 +127,5 @@
   CONVERT_FORMAT ("DVO_AVERAGE_PS1_V3",          PS1_V3,          PS1_V3);
   CONVERT_FORMAT ("DVO_AVERAGE_PS1_V4",          PS1_V4,          PS1_V4);
+  CONVERT_FORMAT ("DVO_AVERAGE_PS1_V5",          PS1_V5,          PS1_V5);
   CONVERT_FORMAT ("DVO_AVERAGE_PS1_REF",         PS1_REF,         PS1_REF);
 # undef CONVERT_FORMAT
@@ -147,4 +163,5 @@
       FORMAT_CASE (PS1_V3,          PS1_V3);
       FORMAT_CASE (PS1_V4,          PS1_V4);
+      FORMAT_CASE (PS1_V5,          PS1_V5);
       FORMAT_CASE (PS1_REF,         PS1_REF);
 # undef FORMAT_CASE
@@ -159,5 +176,6 @@
 /*** Measure / FTable conversion functions ***/
 
-Measure *FtableToMeasure (FTable *ftable, off_t *Nmeasure, char *format) {
+// FtableToMeasure needs the Average since old formats stored measure.dR,dD only
+Measure *FtableToMeasure (FTable *ftable, Average *average, off_t *Nmeasure, char *format) {
 
   Measure *measure;
@@ -179,5 +197,6 @@
       exit (2);
     }
-    measure = Measure_PS1_V4alt_ToInternal (tmpMeasure, *Nmeasure);
+    myAssert (average, "conversion to internal needs average table");
+    measure = Measure_PS1_V4alt_ToInternal (average, tmpMeasure, *Nmeasure);
     free (tmpMeasure);
     *format = DVO_FORMAT_PS1_V4;
@@ -185,15 +204,16 @@
   }
 
-# define CONVERT_FORMAT(NAME, FORMAT, TYPE) \
-  if (!strcmp (extname, NAME)) { \
-    Measure_##TYPE *tmpMeasure; \
+# define CONVERT_FORMAT(NAME, FORMAT, TYPE, ABS_COORDS)		\
+  if (!strcmp (extname, NAME)) {					\
+    Measure_##TYPE *tmpMeasure;						\
     tmpMeasure = gfits_table_get_Measure_##TYPE (ftable, Nmeasure, NULL); \
-    if (!tmpMeasure) { \
-      fprintf (stderr, "ERROR: failed to read measures\n"); \
-      exit (2); \
-    } \
-    measure = Measure_##TYPE##_ToInternal (tmpMeasure, *Nmeasure); \
-    free (tmpMeasure); \
-    *format = DVO_FORMAT_##FORMAT; \
+    if (!tmpMeasure) {							\
+      fprintf (stderr, "ERROR: failed to read measures\n");		\
+      exit (2);								\
+    }									\
+    myAssert (ABS_COORDS || average, "conversion to internal needs average table"); \
+    measure = Measure_##TYPE##_ToInternal (average, tmpMeasure, *Nmeasure); \
+    free (tmpMeasure);							\
+    *format = DVO_FORMAT_##FORMAT;					\
     return (measure); }
 
@@ -208,15 +228,16 @@
   }
 
-  CONVERT_FORMAT ("DVO_MEASURE_ELIXIR", 	 ELIXIR, 	  Elixir);
-  CONVERT_FORMAT ("DVO_MEASURE_LONEOS", 	 LONEOS,          Loneos);
-  CONVERT_FORMAT ("DVO_MEASURE_PANSTARRS_DEV_0", PANSTARRS_DEV_0, Panstarrs_DEV_0);
-  CONVERT_FORMAT ("DVO_MEASURE_PANSTARRS_DEV_1", PANSTARRS_DEV_1, Panstarrs_DEV_1);
-  CONVERT_FORMAT ("DVO_MEASURE_PS1_DEV_1",       PS1_DEV_1,       PS1_DEV_1);
-  CONVERT_FORMAT ("DVO_MEASURE_PS1_DEV_2",       PS1_DEV_2,       PS1_DEV_2);
-  CONVERT_FORMAT ("DVO_MEASURE_PS1_V1",          PS1_V1,          PS1_V1);
-  CONVERT_FORMAT ("DVO_MEASURE_PS1_V2",          PS1_V2,          PS1_V2);
-  CONVERT_FORMAT ("DVO_MEASURE_PS1_V3",          PS1_V3,          PS1_V3);
-  CONVERT_FORMAT ("DVO_MEASURE_PS1_V4",          PS1_V4,          PS1_V4);
-  CONVERT_FORMAT ("DVO_MEASURE_PS1_REF",         PS1_REF,         PS1_REF);
+  CONVERT_FORMAT ("DVO_MEASURE_ELIXIR", 	 ELIXIR, 	  Elixir,          FALSE);
+  CONVERT_FORMAT ("DVO_MEASURE_LONEOS", 	 LONEOS,          Loneos,          FALSE);
+  CONVERT_FORMAT ("DVO_MEASURE_PANSTARRS_DEV_0", PANSTARRS_DEV_0, Panstarrs_DEV_0, FALSE);
+  CONVERT_FORMAT ("DVO_MEASURE_PANSTARRS_DEV_1", PANSTARRS_DEV_1, Panstarrs_DEV_1, FALSE);
+  CONVERT_FORMAT ("DVO_MEASURE_PS1_DEV_1",       PS1_DEV_1,       PS1_DEV_1,       FALSE);
+  CONVERT_FORMAT ("DVO_MEASURE_PS1_DEV_2",       PS1_DEV_2,       PS1_DEV_2,       FALSE);
+  CONVERT_FORMAT ("DVO_MEASURE_PS1_V1",          PS1_V1,          PS1_V1,          FALSE);
+  CONVERT_FORMAT ("DVO_MEASURE_PS1_V2",          PS1_V2,          PS1_V2,          FALSE);
+  CONVERT_FORMAT ("DVO_MEASURE_PS1_V3",          PS1_V3,          PS1_V3,          FALSE);
+  CONVERT_FORMAT ("DVO_MEASURE_PS1_V4",          PS1_V4,          PS1_V4,          FALSE);
+  CONVERT_FORMAT ("DVO_MEASURE_PS1_V5",          PS1_V5,          PS1_V5,          TRUE);
+  CONVERT_FORMAT ("DVO_MEASURE_PS1_REF",         PS1_REF,         PS1_REF,         FALSE);
 # undef CONVERT_FORMAT
 
@@ -227,10 +248,12 @@
 }
 
-int MeasureToFtable (FTable *ftable, Measure *measure, off_t Nmeasure, char format) {
-
-# define FORMAT_CASE(FORMAT, TYPE) \
+// MeasureToFtable needs the Average since old formats stored measure.dR,dD only
+int MeasureToFtable (FTable *ftable, Average *average, Measure *measure, off_t Nmeasure, char format) {
+
+# define FORMAT_CASE(FORMAT, TYPE, ABS_COORDS)		\
     case DVO_FORMAT_##FORMAT: { \
       Measure_##TYPE *tmpMeasure; \
-      tmpMeasure = MeasureInternalTo_##TYPE (measure, Nmeasure); \
+      myAssert (ABS_COORDS || average, "conversion to internal needs average table"); \
+      tmpMeasure = MeasureInternalTo_##TYPE (average, measure, Nmeasure); \
       gfits_table_set_Measure_##TYPE (ftable, tmpMeasure, Nmeasure); \
       free (tmpMeasure); \
@@ -243,15 +266,16 @@
       break; }
 
-      FORMAT_CASE (ELIXIR, 	    Elixir);
-      FORMAT_CASE (LONEOS, 	    Loneos);
-      FORMAT_CASE (PANSTARRS_DEV_0, Panstarrs_DEV_0);
-      FORMAT_CASE (PANSTARRS_DEV_1, Panstarrs_DEV_1);
-      FORMAT_CASE (PS1_DEV_1,       PS1_DEV_1);
-      FORMAT_CASE (PS1_DEV_2,       PS1_DEV_2);
-      FORMAT_CASE (PS1_V1,          PS1_V1);
-      FORMAT_CASE (PS1_V2,          PS1_V2);
-      FORMAT_CASE (PS1_V3,          PS1_V3);
-      FORMAT_CASE (PS1_V4,          PS1_V4);
-      FORMAT_CASE (PS1_REF,         PS1_REF);
+      FORMAT_CASE (ELIXIR, 	    Elixir,          FALSE);
+      FORMAT_CASE (LONEOS, 	    Loneos,          FALSE);
+      FORMAT_CASE (PANSTARRS_DEV_0, Panstarrs_DEV_0, FALSE);
+      FORMAT_CASE (PANSTARRS_DEV_1, Panstarrs_DEV_1, FALSE);
+      FORMAT_CASE (PS1_DEV_1,       PS1_DEV_1,       FALSE);
+      FORMAT_CASE (PS1_DEV_2,       PS1_DEV_2,       FALSE);
+      FORMAT_CASE (PS1_V1,          PS1_V1,          FALSE);
+      FORMAT_CASE (PS1_V2,          PS1_V2,          FALSE);
+      FORMAT_CASE (PS1_V3,          PS1_V3,          FALSE);
+      FORMAT_CASE (PS1_V4,          PS1_V4,          FALSE);
+      FORMAT_CASE (PS1_V5,          PS1_V5,          TRUE);
+      FORMAT_CASE (PS1_REF,         PS1_REF,         FALSE);
 # undef FORMAT_CASE
 
@@ -275,4 +299,19 @@
     return (FALSE);
   }
+
+  // block to convert old tables (PS1_V5 versions made during development)
+  if (!strcmp (extname, "DVO_SECFILT_PS1_V5") && (ftable[0].header[0].Naxis[0] == 160)) {
+    SecFilt_PS1_V5alt *tmpSecFilt;
+    tmpSecFilt = gfits_table_get_SecFilt_PS1_V5alt (ftable, Nsecfilt, NULL);
+    if (!tmpSecFilt) {
+      fprintf (stderr, "ERROR: failed to read secfilts\n");
+      exit (2);
+    }
+    secfilt = SecFilt_PS1_V5alt_ToInternal (tmpSecFilt, *Nsecfilt);
+    free (tmpSecFilt);
+    *format = DVO_FORMAT_PS1_V5;
+    return (secfilt); 
+  }
+
 
 # define CONVERT_FORMAT(NAME, FORMAT, TYPE) \
@@ -309,4 +348,5 @@
   CONVERT_FORMAT ("DVO_SECFILT_PS1_V3",          PS1_V3,          PS1_V3);
   CONVERT_FORMAT ("DVO_SECFILT_PS1_V4",          PS1_V4,          PS1_V4);
+  CONVERT_FORMAT ("DVO_SECFILT_PS1_V5",          PS1_V5,          PS1_V5);
   CONVERT_FORMAT ("DVO_SECFILT_PS1_REF",         PS1_REF,         PS1_REF);
 # undef CONVERT_FORMAT
@@ -344,4 +384,5 @@
       FORMAT_CASE (PS1_V3,          PS1_V3);
       FORMAT_CASE (PS1_V4,          PS1_V4);
+      FORMAT_CASE (PS1_V5,          PS1_V5);
       FORMAT_CASE (PS1_REF,         PS1_REF);
 # undef FORMAT_CASE
@@ -349,4 +390,199 @@
     default:
       fprintf (stderr, "table format unknown (secfilt)\n");
+      return (FALSE);
+  }
+  return (TRUE);
+}
+
+/*** Lensing / FTable conversion functions ***/
+
+Lensing *FtableToLensing (FTable *ftable, off_t *Nlensing, char *format) {
+
+  Lensing *lensing;
+  char extname[80];
+
+  /* convert to the internal format */
+  if (!gfits_scan (ftable[0].header, "EXTNAME", "%s", 1, extname)) {
+    fprintf (stderr, "EXTNAME missing for lensing table\n");
+    return (FALSE);
+  }
+
+# define CONVERT_FORMAT(NAME, FORMAT, TYPE)		\
+  if (!strcmp (extname, NAME)) {					\
+    Lensing_##TYPE *tmpLensing;						\
+    tmpLensing = gfits_table_get_Lensing_##TYPE (ftable, Nlensing, NULL); \
+    if (!tmpLensing) {							\
+      fprintf (stderr, "ERROR: failed to read lensings\n");		\
+      exit (2);								\
+    }									\
+    lensing = Lensing_##TYPE##_ToInternal (tmpLensing, *Nlensing); \
+    free (tmpLensing);							\
+    *format = DVO_FORMAT_##FORMAT;					\
+    return (lensing); }
+
+# define SKIPPING_FORMAT(NAME, FORMAT, TYPE)		\
+  if (!strcmp (extname, NAME)) {					\
+    fprintf (stderr, "ERROR: format %s not defined for lensing, skipping\n", NAME); \
+    *Nlensing = 0; \
+    return NULL; \
+  }
+
+  if (!strcmp (extname, "DVO_LENSING")) {
+    lensing = gfits_table_get_Lensing (ftable, Nlensing, NULL);
+    if (!lensing) {
+      fprintf (stderr, "ERROR: failed to read lensings\n");
+      exit (2);
+    }
+    *format = DVO_FORMAT_INTERNAL;
+    return (lensing);
+  }
+
+  SKIPPING_FORMAT ("DVO_LENSING_PS1_REF",         PS1_REF,         PS1_REF);
+  SKIPPING_FORMAT ("DVO_LENSING_ELIXIR", 	  ELIXIR,  	   Elixir);
+  SKIPPING_FORMAT ("DVO_LENSING_LONEOS", 	  LONEOS,          Loneos);
+  SKIPPING_FORMAT ("DVO_LENSING_PANSTARRS_DEV_0", PANSTARRS_DEV_0, Panstarrs_DEV_0);
+  SKIPPING_FORMAT ("DVO_LENSING_PANSTARRS_DEV_1", PANSTARRS_DEV_1, Panstarrs_DEV_1);
+  SKIPPING_FORMAT ("DVO_LENSING_PS1_DEV_1",       PS1_DEV_1,       PS1_DEV_1);
+  SKIPPING_FORMAT ("DVO_LENSING_PS1_DEV_2",       PS1_DEV_2,       PS1_DEV_2);
+  SKIPPING_FORMAT ("DVO_LENSING_PS1_V1",          PS1_V1,          PS1_V1);
+  SKIPPING_FORMAT ("DVO_LENSING_PS1_V2",          PS1_V2,          PS1_V2);
+  SKIPPING_FORMAT ("DVO_LENSING_PS1_V3",          PS1_V3,          PS1_V3);
+  SKIPPING_FORMAT ("DVO_LENSING_PS1_V4",          PS1_V4,          PS1_V4);
+  CONVERT_FORMAT  ("DVO_LENSING_PS1_V5",          PS1_V5,          PS1_V5);
+# undef CONVERT_FORMAT
+
+  fprintf (stderr, "table format unknown: %s\n", extname);
+
+  *Nlensing = 0;
+  return (NULL);
+}
+
+// LensingToFtable needs the Average since old formats stored lensing.dR,dD only
+int LensingToFtable (FTable *ftable, Lensing *lensing, off_t Nlensing, char format) {
+
+# define FORMAT_CASE(FORMAT, TYPE)		\
+    case DVO_FORMAT_##FORMAT: { \
+      Lensing_##TYPE *tmpLensing; \
+      tmpLensing = LensingInternalTo_##TYPE (lensing, Nlensing); \
+      gfits_table_set_Lensing_##TYPE (ftable, tmpLensing, Nlensing); \
+      free (tmpLensing); \
+      break; }
+
+  /* convert from the internal format */
+  switch (format) {
+    case DVO_FORMAT_INTERNAL: {
+      gfits_table_set_Lensing (ftable, lensing, Nlensing);
+      break; }
+
+//    FORMAT_CASE (PS1_REF,         PS1_REF);
+//    FORMAT_CASE (ELIXIR, 	    Elixir);
+//    FORMAT_CASE (LONEOS, 	    Loneos);
+//    FORMAT_CASE (PANSTARRS_DEV_0, Panstarrs_DEV_0);
+//    FORMAT_CASE (PANSTARRS_DEV_1, Panstarrs_DEV_1);
+//    FORMAT_CASE (PS1_DEV_1,       PS1_DEV_1);
+//    FORMAT_CASE (PS1_DEV_2,       PS1_DEV_2);
+//    FORMAT_CASE (PS1_V1,          PS1_V1);
+//    FORMAT_CASE (PS1_V2,          PS1_V2);
+//    FORMAT_CASE (PS1_V3,          PS1_V3);
+//    FORMAT_CASE (PS1_V4,          PS1_V4);
+      FORMAT_CASE (PS1_V5,          PS1_V5);
+# undef FORMAT_CASE
+
+    default:
+      fprintf (stderr, "table format unknown (lensing)\n");
+      return (FALSE);
+  }
+  return (TRUE);
+}
+
+/*** Lensobj / FTable conversion functions ***/
+
+Lensobj *FtableToLensobj (FTable *ftable, off_t *Nlensobj, char *format) {
+
+  Lensobj *lensobj;
+  char extname[80];
+
+  /* convert to the internal format */
+  if (!gfits_scan (ftable[0].header, "EXTNAME", "%s", 1, extname)) {
+    fprintf (stderr, "EXTNAME missing for lensobj table\n");
+    return (FALSE);
+  }
+
+# define CONVERT_FORMAT(NAME, FORMAT, TYPE)		\
+  if (!strcmp (extname, NAME)) {					\
+    Lensobj_##TYPE *tmpLensobj;						\
+    tmpLensobj = gfits_table_get_Lensobj_##TYPE (ftable, Nlensobj, NULL); \
+    if (!tmpLensobj) {							\
+      fprintf (stderr, "ERROR: failed to read lensobjs\n");		\
+      exit (2);								\
+    }									\
+    lensobj = Lensobj_##TYPE##_ToInternal (tmpLensobj, *Nlensobj); \
+    free (tmpLensobj);							\
+    *format = DVO_FORMAT_##FORMAT;					\
+    return (lensobj); }
+
+  if (!strcmp (extname, "DVO_LENSOBJ")) {
+    lensobj = gfits_table_get_Lensobj (ftable, Nlensobj, NULL);
+    if (!lensobj) {
+      fprintf (stderr, "ERROR: failed to read lensobjs\n");
+      exit (2);
+    }
+    *format = DVO_FORMAT_INTERNAL;
+    return (lensobj);
+  }
+
+// CONVERT_FORMAT ("DVO_LENSOBJ_PS1_REF",         PS1_REF,         PS1_REF);
+// CONVERT_FORMAT ("DVO_LENSOBJ_ELIXIR", 	  ELIXIR,  	   Elixir);
+// CONVERT_FORMAT ("DVO_LENSOBJ_LONEOS", 	  LONEOS,          Loneos);
+// CONVERT_FORMAT ("DVO_LENSOBJ_PANSTARRS_DEV_0", PANSTARRS_DEV_0, Panstarrs_DEV_0);
+// CONVERT_FORMAT ("DVO_LENSOBJ_PANSTARRS_DEV_1", PANSTARRS_DEV_1, Panstarrs_DEV_1);
+// CONVERT_FORMAT ("DVO_LENSOBJ_PS1_DEV_1",       PS1_DEV_1,       PS1_DEV_1);
+// CONVERT_FORMAT ("DVO_LENSOBJ_PS1_DEV_2",       PS1_DEV_2,       PS1_DEV_2);
+// CONVERT_FORMAT ("DVO_LENSOBJ_PS1_V1",          PS1_V1,          PS1_V1);
+// CONVERT_FORMAT ("DVO_LENSOBJ_PS1_V2",          PS1_V2,          PS1_V2);
+// CONVERT_FORMAT ("DVO_LENSOBJ_PS1_V3",          PS1_V3,          PS1_V3);
+// CONVERT_FORMAT ("DVO_LENSOBJ_PS1_V4",          PS1_V4,          PS1_V4);
+  CONVERT_FORMAT ("DVO_LENSOBJ_PS1_V5",          PS1_V5,          PS1_V5);
+# undef CONVERT_FORMAT
+
+  fprintf (stderr, "table format unknown: %s\n", extname);
+
+  *Nlensobj = 0;
+  return (NULL);
+}
+
+// LensobjToFtable needs the Average since old formats stored lensobj.dR,dD only
+int LensobjToFtable (FTable *ftable, Lensobj *lensobj, off_t Nlensobj, char format) {
+
+# define FORMAT_CASE(FORMAT, TYPE)		\
+    case DVO_FORMAT_##FORMAT: { \
+      Lensobj_##TYPE *tmpLensobj; \
+      tmpLensobj = LensobjInternalTo_##TYPE (lensobj, Nlensobj); \
+      gfits_table_set_Lensobj_##TYPE (ftable, tmpLensobj, Nlensobj); \
+      free (tmpLensobj); \
+      break; }
+
+  /* convert from the internal format */
+  switch (format) {
+    case DVO_FORMAT_INTERNAL: {
+      gfits_table_set_Lensobj (ftable, lensobj, Nlensobj);
+      break; }
+
+//    FORMAT_CASE (PS1_REF,         PS1_REF);
+//    FORMAT_CASE (ELIXIR, 	    Elixir);
+//    FORMAT_CASE (LONEOS, 	    Loneos);
+//    FORMAT_CASE (PANSTARRS_DEV_0, Panstarrs_DEV_0);
+//    FORMAT_CASE (PANSTARRS_DEV_1, Panstarrs_DEV_1);
+//    FORMAT_CASE (PS1_DEV_1,       PS1_DEV_1);
+//    FORMAT_CASE (PS1_DEV_2,       PS1_DEV_2);
+//    FORMAT_CASE (PS1_V1,          PS1_V1);
+//    FORMAT_CASE (PS1_V2,          PS1_V2);
+//    FORMAT_CASE (PS1_V3,          PS1_V3);
+//    FORMAT_CASE (PS1_V4,          PS1_V4);
+      FORMAT_CASE (PS1_V5,          PS1_V5);
+# undef FORMAT_CASE
+
+    default:
+      fprintf (stderr, "table format unknown (lensobj)\n");
       return (FALSE);
   }
@@ -428,4 +664,5 @@
   CONVERT_FORMAT ("DVO_IMAGE_PS1_V3",          PS1_V3,          PS1_V3);
   CONVERT_FORMAT ("DVO_IMAGE_PS1_V4",          PS1_V4,          PS1_V4);
+  CONVERT_FORMAT ("DVO_IMAGE_PS1_V5",          PS1_V5,          PS1_V5);
   CONVERT_FORMAT ("DVO_IMAGE_PS1_REF",         PS1_REF,         PS1_REF);
 
@@ -467,4 +704,5 @@
       FORMAT_CASE (PS1_V3,          PS1_V3);
       FORMAT_CASE (PS1_V4,          PS1_V4);
+      FORMAT_CASE (PS1_V5,          PS1_V5);
       FORMAT_CASE (PS1_REF,         PS1_REF);
 
@@ -522,4 +760,5 @@
       FORMAT_CASE (PS1_V3,          PS1_V3);
       FORMAT_CASE (PS1_V4,          PS1_V4);
+      FORMAT_CASE (PS1_V5,          PS1_V5);
       FORMAT_CASE (PS1_REF,         PS1_REF);
 
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert_PS1_DEV_1.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert_PS1_DEV_1.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert_PS1_DEV_1.c	(revision 37403)
@@ -3,5 +3,5 @@
 /* convert PS1_DEV_1 formats to internal formats */
 
-Measure *Measure_PS1_DEV_1_ToInternal (Measure_PS1_DEV_1 *in, off_t Nvalues) {
+Measure *Measure_PS1_DEV_1_ToInternal (Average *ave, Measure_PS1_DEV_1 *in, off_t Nvalues) {
 
   off_t i;
@@ -12,6 +12,8 @@
   for (i = 0; i < Nvalues; i++) {
     dvo_measure_init (&out[i]);
-    out[i].dR         = in[i].dR;
-    out[i].dD         = in[i].dD;
+
+    int averef = in[i].averef;
+    out[i].R          = ave[averef].R - in[i].dR / 3600.0;
+    out[i].D          = ave[averef].D - in[i].dD / 3600.0;
     out[i].M          = in[i].M;
     out[i].Mcal       = in[i].Mcal;
@@ -30,5 +32,4 @@
     out[i].psfQF      = in[i].psfQF;
     out[i].psfChisq   = in[i].psfChisq;
-    out[i].crNsigma   = in[i].crNsigma;
     out[i].extNsigma  = in[i].extNsigma;
     out[i].FWx 	      = in[i].FWx;
@@ -50,5 +51,5 @@
 }
 
-Measure_PS1_DEV_1 *MeasureInternalTo_PS1_DEV_1 (Measure *in, off_t Nvalues) {
+Measure_PS1_DEV_1 *MeasureInternalTo_PS1_DEV_1 (Average *ave, Measure *in, off_t Nvalues) {
 
   off_t i;
@@ -58,6 +59,8 @@
 
   for (i = 0; i < Nvalues; i++) {
-    out[i].dR         = in[i].dR;
-    out[i].dD         = in[i].dD;
+    int averef = in[i].averef;
+
+    out[i].dR         = 3600.0*(ave[averef].R - in[i].R);
+    out[i].dD         = 3600.0*(ave[averef].D - in[i].D);
     out[i].M          = in[i].M;
     out[i].Mcal       = in[i].Mcal;
@@ -76,5 +79,4 @@
     out[i].psfQF      = in[i].psfQF;
     out[i].psfChisq   = in[i].psfChisq;
-    out[i].crNsigma   = in[i].crNsigma;
     out[i].extNsigma  = in[i].extNsigma;
     out[i].FWx 	      = in[i].FWx;
@@ -180,5 +182,5 @@
     out[i].M     = in[i].M;      
     out[i].dM    = in[i].dM;      
-    out[i].Xm    = in[i].Xm;     
+    out[i].Mchisq= pow (10.0, 0.01*in[i].Xm);     
     out[i].Ncode = in[i].Ncode;
     out[i].Nused = in[i].Nused;
@@ -197,5 +199,5 @@
     out[i].M     = in[i].M;      
     out[i].dM    = in[i].dM;      
-    out[i].Xm    = in[i].Xm;     
+    out[i].Xm    = 100.0*log10(in[i].Mchisq);     
     out[i].Ncode = in[i].Ncode;
     out[i].Nused = in[i].Nused;
@@ -203,4 +205,6 @@
   return (out);
 }
+
+# define RAW_IMAGE_NAME_LEN 64
 
 Image *Image_PS1_DEV_1_ToInternal (Image_PS1_DEV_1 *in, off_t Nvalues, off_t Nalloc) {
@@ -217,6 +221,7 @@
     memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
 
-    strncpy (out[i].name, in[i].name, 63); // out[128], in[64]
-    out[i].name[63] = 0; // force termination
+    // RAW_IMAGE_NAME_LEN < DVO_IMAGE_NAME_LEN
+    strncpy (out[i].name, in[i].name, RAW_IMAGE_NAME_LEN - 1);
+    out[i].name[RAW_IMAGE_NAME_LEN - 1] = 0; // force termination
 
     out[i].tzero    	    = in[i].tzero;
@@ -284,6 +289,7 @@
     memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
 
-    strncpy (out[i].name, in[i].name, 63); // out[128], in[64]
-    out[i].name[63] = 0; // force termination
+    // RAW_IMAGE_NAME_LEN < DVO_IMAGE_NAME_LEN
+    strncpy (out[i].name, in[i].name, RAW_IMAGE_NAME_LEN - 1);
+    out[i].name[RAW_IMAGE_NAME_LEN - 1] = 0; // force termination
 
     out[i].tzero    	    = in[i].tzero;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert_PS1_DEV_2.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert_PS1_DEV_2.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert_PS1_DEV_2.c	(revision 37403)
@@ -3,5 +3,5 @@
 /* convert PS1_DEV_2 formats to internal formats */
 
-Measure *Measure_PS1_DEV_2_ToInternal (Measure_PS1_DEV_2 *in, off_t Nvalues) {
+Measure *Measure_PS1_DEV_2_ToInternal (Average *ave, Measure_PS1_DEV_2 *in, off_t Nvalues) {
 
   off_t i;
@@ -12,6 +12,8 @@
   for (i = 0; i < Nvalues; i++) {
     dvo_measure_init (&out[i]);
-    out[i].dR         = in[i].dR;
-    out[i].dD         = in[i].dD;
+
+    int averef = in[i].averef;
+    out[i].R          = ave[averef].R - in[i].dR / 3600.0;
+    out[i].D          = ave[averef].D - in[i].dD / 3600.0;
     out[i].M          = in[i].M;
     out[i].Mcal       = in[i].Mcal;
@@ -32,5 +34,4 @@
     out[i].psfQF      = in[i].psfQF;
     out[i].psfChisq   = in[i].psfChisq;
-    out[i].crNsigma   = in[i].crNsigma;
     out[i].extNsigma  = in[i].extNsigma;
     out[i].FWx 	      = in[i].FWx;
@@ -48,5 +49,5 @@
 }
 
-Measure_PS1_DEV_2 *MeasureInternalTo_PS1_DEV_2 (Measure *in, off_t Nvalues) {
+Measure_PS1_DEV_2 *MeasureInternalTo_PS1_DEV_2 (Average *ave, Measure *in, off_t Nvalues) {
 
   off_t i;
@@ -56,6 +57,8 @@
 
   for (i = 0; i < Nvalues; i++) {
-    out[i].dR         = in[i].dR;
-    out[i].dD         = in[i].dD;
+    int averef = in[i].averef;
+
+    out[i].dR         = 3600.0*(ave[averef].R - in[i].R);
+    out[i].dD         = 3600.0*(ave[averef].D - in[i].D);
     out[i].M          = in[i].M;
     out[i].Mcal       = in[i].Mcal;
@@ -76,5 +79,4 @@
     out[i].psfQF      = in[i].psfQF;
     out[i].psfChisq   = in[i].psfChisq;
-    out[i].crNsigma   = in[i].crNsigma;
     out[i].extNsigma  = in[i].extNsigma;
     out[i].FWx 	      = in[i].FWx;
@@ -119,5 +121,5 @@
     out[i].measureOffset = in[i].measureOffset; 
     out[i].missingOffset = in[i].missingOffset;
-    out[i].extendOffset  = in[i].extendOffset;
+    out[i].refColorBlue  = in[i].refColor;
     out[i].objID 	 = in[i].objID;
     out[i].catID 	 = in[i].catID;
@@ -153,5 +155,5 @@
     out[i].measureOffset = in[i].measureOffset; 
     out[i].missingOffset = in[i].missingOffset;
-    out[i].extendOffset  = in[i].extendOffset;
+    out[i].refColor  = in[i].refColorBlue;
     out[i].objID 	 = in[i].objID;
     out[i].catID 	 = in[i].catID;
@@ -175,5 +177,5 @@
     out[i].M     = in[i].M;      
     out[i].dM    = in[i].dM;      
-    out[i].Xm    = in[i].Xm;     
+    out[i].Mchisq= pow (10.0, 0.01*in[i].Xm);     
     out[i].Ncode = in[i].Ncode;
     out[i].Nused = in[i].Nused;
@@ -192,5 +194,5 @@
     out[i].M     = in[i].M;      
     out[i].dM    = in[i].dM;      
-    out[i].Xm    = in[i].Xm;     
+    out[i].Xm    = 100.0*log10(in[i].Mchisq);     
     out[i].Ncode = in[i].Ncode;
     out[i].Nused = in[i].Nused;
@@ -198,4 +200,6 @@
   return (out);
 }
+
+# define RAW_IMAGE_NAME_LEN 64
 
 Image *Image_PS1_DEV_2_ToInternal (Image_PS1_DEV_2 *in, off_t Nvalues, off_t Nalloc) {
@@ -212,6 +216,7 @@
     memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
 
-    strncpy (out[i].name, in[i].name, 63); // out[121], in[64]
-    out[i].name[63] = 0; // force termination
+    // RAW_IMAGE_NAME_LEN < DVO_IMAGE_NAME_LEN
+    strncpy (out[i].name, in[i].name, RAW_IMAGE_NAME_LEN - 1);
+    out[i].name[RAW_IMAGE_NAME_LEN - 1] = 0; // force termination
 
     out[i].tzero    	    = in[i].tzero;
@@ -276,6 +281,7 @@
     memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
 
-    strncpy (out[i].name, in[i].name, 63); // in[121], out[64]
-    out[i].name[63] = 0; // force termination
+    // RAW_IMAGE_NAME_LEN < DVO_IMAGE_NAME_LEN
+    strncpy (out[i].name, in[i].name, RAW_IMAGE_NAME_LEN - 1);
+    out[i].name[RAW_IMAGE_NAME_LEN - 1] = 0; // force termination
 
     out[i].tzero    	    = in[i].tzero;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert_PS1_DEV_3.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert_PS1_DEV_3.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert_PS1_DEV_3.c	(revision 37403)
@@ -4,4 +4,6 @@
 
 // We only provide image and photcode conversion
+
+# define RAW_IMAGE_NAME_LEN 128
 
 Image *Image_PS1_DEV_3_ToInternal (Image_PS1_DEV_3 *in, off_t Nvalues, off_t Nalloc) {
@@ -18,6 +20,7 @@
     memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
 
-    strncpy (out[i].name, in[i].name, 120); // out[121], in[121]
-    out[i].name[120] = 0; // force termination
+    // RAW_IMAGE_NAME_LEN > DVO_IMAGE_NAME_LEN
+    strncpy (out[i].name, in[i].name, DVO_IMAGE_NAME_LEN - 1);
+    out[i].name[DVO_IMAGE_NAME_LEN - 1] = 0; // force termination
 
     out[i].tzero    	    = in[i].tzero;
@@ -77,6 +80,7 @@
     memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
 
-    strncpy (out[i].name, in[i].name, 127); // out[128], in[128]
-    out[i].name[127] = 0; // force termination
+    // RAW_IMAGE_NAME_LEN > DVO_IMAGE_NAME_LEN
+    strncpy (out[i].name, in[i].name, DVO_IMAGE_NAME_LEN - 1);
+    out[i].name[DVO_IMAGE_NAME_LEN - 1] = 0; // force termination
 
     out[i].tzero    	    = in[i].tzero;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert_PS1_REF.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert_PS1_REF.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert_PS1_REF.c	(revision 37403)
@@ -3,5 +3,5 @@
 /* convert PS1_REF formats to internal formats */
 
-Measure *Measure_PS1_REF_ToInternal (Measure_PS1_REF *in, off_t Nvalues) {
+Measure *Measure_PS1_REF_ToInternal (Average *ave, Measure_PS1_REF *in, off_t Nvalues) {
 
   off_t i;
@@ -13,6 +13,7 @@
     dvo_measure_init (&out[i]);
 
-    out[i].dR         = in[i].dR;
-    out[i].dD         = in[i].dD;
+    int averef = in[i].averef;
+    out[i].R          = ave[averef].R - in[i].dR / 3600.0;
+    out[i].D          = ave[averef].D - in[i].dD / 3600.0;
     out[i].M          = in[i].M;
     out[i].dM         = in[i].dM;
@@ -28,5 +29,5 @@
 }
 
-Measure_PS1_REF *MeasureInternalTo_PS1_REF (Measure *in, off_t Nvalues) {
+Measure_PS1_REF *MeasureInternalTo_PS1_REF (Average *ave, Measure *in, off_t Nvalues) {
 
   off_t i;
@@ -36,6 +37,8 @@
 
   for (i = 0; i < Nvalues; i++) {
-    out[i].dR         = in[i].dR;
-    out[i].dD         = in[i].dD;
+    int averef = in[i].averef;
+
+    out[i].dR         = 3600.0*(ave[averef].R - in[i].R);
+    out[i].dD         = 3600.0*(ave[averef].D - in[i].D);
     out[i].M          = in[i].M;
     out[i].dM         = in[i].dM;
@@ -129,4 +132,6 @@
 }
 
+# define RAW_IMAGE_NAME_LEN 121
+
 Image *Image_PS1_REF_ToInternal (Image_PS1_REF *in, off_t Nvalues, off_t Nalloc) {
 
@@ -142,6 +147,7 @@
     memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
 
-    strncpy (out[i].name, in[i].name, 120); // out[121], in[121]
-    out[i].name[120] = 0; // force termination
+    // RAW_IMAGE_NAME_LEN > DVO_IMAGE_NAME_LEN
+    strncpy (out[i].name, in[i].name, DVO_IMAGE_NAME_LEN - 1);
+    out[i].name[DVO_IMAGE_NAME_LEN - 1] = 0; // force termination
 
     out[i].tzero    	    = in[i].tzero;
@@ -204,6 +210,7 @@
     memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
 
-    strncpy (out[i].name, in[i].name, 120); // out[121], in[121]
-    out[i].name[120] = 0; // force termination
+    // RAW_IMAGE_NAME_LEN > DVO_IMAGE_NAME_LEN
+    strncpy (out[i].name, in[i].name, DVO_IMAGE_NAME_LEN - 1);
+    out[i].name[DVO_IMAGE_NAME_LEN - 1] = 0; // force termination
 
     out[i].tzero    	    = in[i].tzero;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert_PS1_V1.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert_PS1_V1.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert_PS1_V1.c	(revision 37403)
@@ -3,5 +3,5 @@
 /* convert PS1_V1 formats to internal formats */
 
-Measure *Measure_PS1_V1_ToInternal (Measure_PS1_V1 *in, off_t Nvalues) {
+Measure *Measure_PS1_V1_ToInternal (Average *ave, Measure_PS1_V1 *in, off_t Nvalues) {
 
   off_t i;
@@ -13,6 +13,7 @@
     dvo_measure_init (&out[i]);
 
-    out[i].dR         = in[i].dR;
-    out[i].dD         = in[i].dD;
+    int averef = in[i].averef;
+    out[i].R          = ave[averef].R - in[i].dR / 3600.0;
+    out[i].D          = ave[averef].D - in[i].dD / 3600.0;
     out[i].M          = in[i].M;
     out[i].Mcal       = in[i].Mcal;
@@ -39,5 +40,4 @@
     out[i].psfNdof    = in[i].psfNdof;
     out[i].psfNpix    = in[i].psfNpix;
-    out[i].crNsigma   = in[i].crNsigma;
     out[i].extNsigma  = in[i].extNsigma;
     out[i].FWx 	      = in[i].FWx;
@@ -58,5 +58,5 @@
 }
 
-Measure_PS1_V1 *MeasureInternalTo_PS1_V1 (Measure *in, off_t Nvalues) {
+Measure_PS1_V1 *MeasureInternalTo_PS1_V1 (Average *ave, Measure *in, off_t Nvalues) {
 
   off_t i;
@@ -66,6 +66,8 @@
 
   for (i = 0; i < Nvalues; i++) {
-    out[i].dR         = in[i].dR;
-    out[i].dD         = in[i].dD;
+    int averef = in[i].averef;
+
+    out[i].dR         = 3600.0*(ave[averef].R - in[i].R);
+    out[i].dD         = 3600.0*(ave[averef].D - in[i].D);
     out[i].M          = in[i].M;
     out[i].Mcal       = in[i].Mcal;
@@ -92,5 +94,4 @@
     out[i].psfNdof    = in[i].psfNdof;
     out[i].psfNpix    = in[i].psfNpix;
-    out[i].crNsigma   = in[i].crNsigma;
     out[i].extNsigma  = in[i].extNsigma;
     out[i].FWx 	      = in[i].FWx;
@@ -140,5 +141,5 @@
     out[i].measureOffset = in[i].measureOffset; 
     out[i].missingOffset = in[i].missingOffset;
-    out[i].extendOffset  = in[i].extendOffset;
+    out[i].refColorBlue  = in[i].refColor;
     out[i].flags     	 = in[i].flags;   
     out[i].objID 	 = in[i].objID;
@@ -175,5 +176,5 @@
     out[i].measureOffset = in[i].measureOffset; 
     out[i].missingOffset = in[i].missingOffset;
-    out[i].extendOffset  = in[i].extendOffset;
+    out[i].refColor      = in[i].refColorBlue;
     out[i].flags     	 = in[i].flags;   
     out[i].objID 	 = in[i].objID;
@@ -196,9 +197,9 @@
     out[i].M     = in[i].M;      
     out[i].dM    = in[i].dM;      
-    out[i].Xm    = in[i].Xm;     
+    out[i].Mchisq= in[i].Mchisq;     
     out[i].Ncode = in[i].Ncode;
     out[i].Nused = in[i].Nused;
-    out[i].M_20  = in[i].M_20;      
-    out[i].M_80  = in[i].M_80;      
+    out[i].Mmin  = in[i].M_20*0.001;      
+    out[i].Mmax  = in[i].M_80*0.001;      
  }
   return (out);
@@ -215,12 +216,14 @@
     out[i].M     = in[i].M;      
     out[i].dM    = in[i].dM;      
-    out[i].Xm    = in[i].Xm;     
+    out[i].Mchisq= in[i].Mchisq;     
     out[i].Ncode = in[i].Ncode;
     out[i].Nused = in[i].Nused;
-    out[i].M_20  = in[i].M_20;      
-    out[i].M_80  = in[i].M_80;      
-  }
-  return (out);
-}
+    out[i].M_20  = in[i].Mmin*1000.0;      
+    out[i].M_80  = in[i].Mmax*1000.0;      
+  }
+  return (out);
+}
+
+# define RAW_IMAGE_NAME_LEN 121
 
 Image *Image_PS1_V1_ToInternal (Image_PS1_V1 *in, off_t Nvalues, off_t Nalloc) {
@@ -237,6 +240,7 @@
     memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
 
-    strncpy (out[i].name, in[i].name, 120); // out[121], in[121]
-    out[i].name[120] = 0; // force termination
+    // RAW_IMAGE_NAME_LEN > DVO_IMAGE_NAME_LEN
+    strncpy (out[i].name, in[i].name, DVO_IMAGE_NAME_LEN - 1);
+    out[i].name[DVO_IMAGE_NAME_LEN - 1] = 0; // force termination
 
     out[i].tzero    	    = in[i].tzero;
@@ -300,6 +304,7 @@
     memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
 
-    strncpy (out[i].name, in[i].name, 120); // out[121], in[121]
-    out[i].name[120] = 0; // force termination
+    // RAW_IMAGE_NAME_LEN > DVO_IMAGE_NAME_LEN
+    strncpy (out[i].name, in[i].name, DVO_IMAGE_NAME_LEN - 1);
+    out[i].name[DVO_IMAGE_NAME_LEN - 1] = 0; // force termination
 
     out[i].tzero    	    = in[i].tzero;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert_PS1_V2.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert_PS1_V2.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert_PS1_V2.c	(revision 37403)
@@ -3,5 +3,5 @@
 /* convert PS1_V2 formats to internal formats */
 
-Measure *Measure_PS1_V2_ToInternal (Measure_PS1_V2 *in, off_t Nvalues) {
+Measure *Measure_PS1_V2_ToInternal (Average *ave, Measure_PS1_V2 *in, off_t Nvalues) {
 
   off_t i;
@@ -13,6 +13,7 @@
     dvo_measure_init (&out[i]);
 
-    out[i].dR         = in[i].dR;
-    out[i].dD         = in[i].dD;
+    int averef = in[i].averef;
+    out[i].R          = ave[averef].R - in[i].dR / 3600.0;
+    out[i].D          = ave[averef].D - in[i].dD / 3600.0;
     out[i].M          = in[i].M;
     out[i].Mcal       = in[i].Mcal;
@@ -39,5 +40,4 @@
     out[i].psfNdof    = in[i].psfNdof;
     out[i].psfNpix    = in[i].psfNpix;
-    out[i].crNsigma   = in[i].crNsigma;
     out[i].extNsigma  = in[i].extNsigma;
     out[i].FWx 	      = in[i].FWx;
@@ -59,5 +59,5 @@
 }
 
-Measure_PS1_V2 *MeasureInternalTo_PS1_V2 (Measure *in, off_t Nvalues) {
+Measure_PS1_V2 *MeasureInternalTo_PS1_V2 (Average *ave, Measure *in, off_t Nvalues) {
 
   off_t i;
@@ -67,6 +67,8 @@
 
   for (i = 0; i < Nvalues; i++) {
-    out[i].dR         = in[i].dR;
-    out[i].dD         = in[i].dD;
+    int averef = in[i].averef;
+
+    out[i].dR         = 3600.0*(ave[averef].R - in[i].R);
+    out[i].dD         = 3600.0*(ave[averef].D - in[i].D);
     out[i].M          = in[i].M;
     out[i].Mcal       = in[i].Mcal;
@@ -93,5 +95,4 @@
     out[i].psfNdof    = in[i].psfNdof;
     out[i].psfNpix    = in[i].psfNpix;
-    out[i].crNsigma   = in[i].crNsigma;
     out[i].extNsigma  = in[i].extNsigma;
     out[i].FWx 	      = in[i].FWx;
@@ -145,5 +146,5 @@
     out[i].measureOffset = in[i].measureOffset; 
     out[i].missingOffset = in[i].missingOffset;
-    out[i].extendOffset  = in[i].extendOffset;
+    out[i].refColorBlue  = in[i].refColor;
     out[i].flags     	 = in[i].flags;   
     out[i].objID 	 = in[i].objID;
@@ -184,5 +185,5 @@
     out[i].measureOffset = in[i].measureOffset; 
     out[i].missingOffset = in[i].missingOffset;
-    out[i].extendOffset  = in[i].extendOffset;
+    out[i].refColor  = in[i].refColorBlue;
     out[i].flags     	 = in[i].flags;   
     out[i].objID 	 = in[i].objID;
@@ -205,10 +206,10 @@
     out[i].M     = in[i].M;      
     out[i].dM    = in[i].dM;      
-    out[i].Xm    = in[i].Xm;     
+    out[i].Mchisq= in[i].Mchisq;     
     out[i].flags = in[i].flags;     
     out[i].Ncode = in[i].Ncode;
     out[i].Nused = in[i].Nused;
-    out[i].M_20  = in[i].M_20;      
-    out[i].M_80  = in[i].M_80;      
+    out[i].Mmin  = in[i].M_20*0.001;      
+    out[i].Mmax  = in[i].M_80*0.001;      
  }
   return (out);
@@ -225,13 +226,15 @@
     out[i].M     = in[i].M;      
     out[i].dM    = in[i].dM;      
-    out[i].Xm    = in[i].Xm;     
+    out[i].Mchisq= in[i].Mchisq;     
     out[i].flags = in[i].flags;     
     out[i].Ncode = in[i].Ncode;
     out[i].Nused = in[i].Nused;
-    out[i].M_20  = in[i].M_20;      
-    out[i].M_80  = in[i].M_80;      
-  }
-  return (out);
-}
+    out[i].M_20  = in[i].Mmin*1000.0;      
+    out[i].M_80  = in[i].Mmax*1000.0;      
+  }
+  return (out);
+}
+
+# define RAW_IMAGE_NAME_LEN 121
 
 Image *Image_PS1_V2_ToInternal (Image_PS1_V2 *in, off_t Nvalues, off_t Nalloc) {
@@ -248,6 +251,7 @@
     memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
 
-    strncpy (out[i].name, in[i].name, 120); // out[121], in[121]
-    out[i].name[120] = 0; // force termination
+    // RAW_IMAGE_NAME_LEN > DVO_IMAGE_NAME_LEN
+    strncpy (out[i].name, in[i].name, DVO_IMAGE_NAME_LEN - 1);
+    out[i].name[DVO_IMAGE_NAME_LEN - 1] = 0; // force termination
 
     out[i].tzero    	    = in[i].tzero;
@@ -269,4 +273,5 @@
     out[i].DECo  	    = in[i].DECo;
     out[i].Radius  	    = in[i].Radius;
+    out[i].refColorBlue  	    = in[i].refColor;
 
     out[i].detection_limit  = in[i].detection_limit;
@@ -310,6 +315,7 @@
     memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
 
-    strncpy (out[i].name, in[i].name, 120); // out[121], in[121]
-    out[i].name[120] = 0; // force termination
+    // RAW_IMAGE_NAME_LEN > DVO_IMAGE_NAME_LEN
+    strncpy (out[i].name, in[i].name, DVO_IMAGE_NAME_LEN - 1);
+    out[i].name[DVO_IMAGE_NAME_LEN - 1] = 0; // force termination
 
     out[i].tzero    	    = in[i].tzero;
@@ -331,4 +337,5 @@
     out[i].DECo  	    = in[i].DECo;
     out[i].Radius  	    = in[i].Radius;
+    out[i].refColor  	    = in[i].refColorBlue;
 
     out[i].detection_limit  = in[i].detection_limit;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert_PS1_V3.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert_PS1_V3.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert_PS1_V3.c	(revision 37403)
@@ -3,5 +3,5 @@
 /* convert PS1_V3 formats to internal formats */
 
-Measure *Measure_PS1_V3_ToInternal (Measure_PS1_V3 *in, off_t Nvalues) {
+Measure *Measure_PS1_V3_ToInternal (Average *ave, Measure_PS1_V3 *in, off_t Nvalues) {
 
   off_t i;
@@ -13,6 +13,7 @@
     dvo_measure_init (&out[i]);
 
-    out[i].dR         = in[i].dR;
-    out[i].dD         = in[i].dD;
+    int averef = in[i].averef;
+    out[i].R          = ave[averef].R - in[i].dR / 3600.0;
+    out[i].D          = ave[averef].D - in[i].dD / 3600.0;
     out[i].M          = in[i].M;
     out[i].Mcal       = in[i].Mcal;
@@ -39,5 +40,4 @@
     out[i].psfNdof    = in[i].psfNdof;
     out[i].psfNpix    = in[i].psfNpix;
-    out[i].crNsigma   = in[i].crNsigma;
     out[i].extNsigma  = in[i].extNsigma;
     out[i].FWx 	      = in[i].FWx;
@@ -59,5 +59,5 @@
 }
 
-Measure_PS1_V3 *MeasureInternalTo_PS1_V3 (Measure *in, off_t Nvalues) {
+Measure_PS1_V3 *MeasureInternalTo_PS1_V3 (Average *ave, Measure *in, off_t Nvalues) {
 
   off_t i;
@@ -67,6 +67,8 @@
 
   for (i = 0; i < Nvalues; i++) {
-    out[i].dR         = in[i].dR;
-    out[i].dD         = in[i].dD;
+    int averef = in[i].averef;
+
+    out[i].dR         = 3600.0*(ave[averef].R - in[i].R);
+    out[i].dD         = 3600.0*(ave[averef].D - in[i].D);
     out[i].M          = in[i].M;
     out[i].Mcal       = in[i].Mcal;
@@ -93,5 +95,4 @@
     out[i].psfNdof    = in[i].psfNdof;
     out[i].psfNpix    = in[i].psfNpix;
-    out[i].crNsigma   = in[i].crNsigma;
     out[i].extNsigma  = in[i].extNsigma;
     out[i].FWx 	      = in[i].FWx;
@@ -145,5 +146,5 @@
     out[i].measureOffset = in[i].measureOffset; 
     out[i].missingOffset = in[i].missingOffset;
-    out[i].extendOffset  = in[i].extendOffset;
+    out[i].refColorBlue  = in[i].refColor;
     out[i].flags     	 = in[i].flags;   
     out[i].photFlagsUpper = in[i].photFlagsUpper;   
@@ -186,5 +187,5 @@
     out[i].measureOffset = in[i].measureOffset; 
     out[i].missingOffset = in[i].missingOffset;
-    out[i].extendOffset  = in[i].extendOffset;
+    out[i].refColor      = in[i].refColorBlue;
     out[i].flags     	 = in[i].flags;   
     out[i].photFlagsUpper = in[i].photFlagsUpper;   
@@ -210,10 +211,10 @@
     out[i].Map         = in[i].Map;      
     out[i].dM          = in[i].dM;      
-    out[i].Xm          = in[i].Xm;     
+    out[i].Mchisq      = in[i].Mchisq;     
     out[i].flags       = in[i].flags;     
     out[i].Ncode       = in[i].Ncode;
     out[i].Nused       = in[i].Nused;
-    out[i].M_20        = in[i].M_20;      
-    out[i].M_80        = in[i].M_80;      
+    out[i].Mmin        = in[i].M_20*0.001;      
+    out[i].Mmax        = in[i].M_80*0.001;      
     out[i].Mstdev      = in[i].Mstdev;      
     out[i].ubercalDist = in[i].ubercalDist;      
@@ -233,10 +234,10 @@
     out[i].Map         = in[i].Map;      
     out[i].dM          = in[i].dM;      
-    out[i].Xm          = in[i].Xm;     
+    out[i].Mchisq      = in[i].Mchisq;     
     out[i].flags       = in[i].flags;     
     out[i].Ncode       = in[i].Ncode;
     out[i].Nused       = in[i].Nused;
-    out[i].M_20        = in[i].M_20;      
-    out[i].M_80        = in[i].M_80;      
+    out[i].M_20        = in[i].Mmin*1000.0;      
+    out[i].M_80        = in[i].Mmax*1000.0;      
     out[i].Mstdev      = in[i].Mstdev;      
     out[i].ubercalDist = in[i].ubercalDist;      
@@ -244,4 +245,6 @@
   return (out);
 }
+
+# define RAW_IMAGE_NAME_LEN 121
 
 Image *Image_PS1_V3_ToInternal (Image_PS1_V3 *in, off_t Nvalues, off_t Nalloc) {
@@ -258,6 +261,7 @@
     memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
 
-    strncpy (out[i].name, in[i].name, 120); // out[121], in[121]
-    out[i].name[120] = 0; // force termination
+    // RAW_IMAGE_NAME_LEN > DVO_IMAGE_NAME_LEN
+    strncpy (out[i].name, in[i].name, DVO_IMAGE_NAME_LEN - 1);
+    out[i].name[DVO_IMAGE_NAME_LEN - 1] = 0; // force termination
 
     out[i].tzero    	    = in[i].tzero;
@@ -279,4 +283,5 @@
     out[i].DECo  	    = in[i].DECo;
     out[i].Radius  	    = in[i].Radius;
+    out[i].refColorBlue     = in[i].refColor;
 
     out[i].detection_limit  = in[i].detection_limit;
@@ -320,6 +325,7 @@
     memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
 
-    strncpy (out[i].name, in[i].name, 120); // out[121], in[121]
-    out[i].name[120] = 0; // force termination
+    // RAW_IMAGE_NAME_LEN > DVO_IMAGE_NAME_LEN
+    strncpy (out[i].name, in[i].name, DVO_IMAGE_NAME_LEN - 1);
+    out[i].name[DVO_IMAGE_NAME_LEN - 1] = 0; // force termination
 
     out[i].tzero    	    = in[i].tzero;
@@ -341,4 +347,5 @@
     out[i].DECo  	    = in[i].DECo;
     out[i].Radius  	    = in[i].Radius;
+    out[i].refColor  	    = in[i].refColorBlue;
 
     out[i].detection_limit  = in[i].detection_limit;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert_PS1_V4.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert_PS1_V4.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert_PS1_V4.c	(revision 37403)
@@ -3,5 +3,5 @@
 /* convert PS1_V4 formats to internal formats */
 
-Measure *Measure_PS1_V4_ToInternal (Measure_PS1_V4 *in, off_t Nvalues) {
+Measure *Measure_PS1_V4_ToInternal (Average *ave, Measure_PS1_V4 *in, off_t Nvalues) {
 
   off_t i;
@@ -13,6 +13,7 @@
     dvo_measure_init (&out[i]);
 
-    out[i].dR         = in[i].dR;
-    out[i].dD         = in[i].dD;
+    int averef = in[i].averef;
+    out[i].R          = ave[averef].R - in[i].dR / 3600.0;
+    out[i].D          = ave[averef].D - in[i].dD / 3600.0;
     out[i].M          = in[i].M;
     out[i].Mcal       = in[i].Mcal;
@@ -48,5 +49,4 @@
     out[i].psfNdof    = in[i].psfNdof;
     out[i].psfNpix    = in[i].psfNpix;
-    out[i].crNsigma   = in[i].crNsigma;
     out[i].extNsigma  = in[i].extNsigma;
     out[i].FWx 	      = in[i].FWx;
@@ -68,5 +68,5 @@
 }
 
-Measure_PS1_V4 *MeasureInternalTo_PS1_V4 (Measure *in, off_t Nvalues) {
+Measure_PS1_V4 *MeasureInternalTo_PS1_V4 (Average *ave, Measure *in, off_t Nvalues) {
 
   off_t i;
@@ -76,6 +76,8 @@
 
   for (i = 0; i < Nvalues; i++) {
-    out[i].dR         = in[i].dR;
-    out[i].dD         = in[i].dD;
+    int averef = in[i].averef;
+
+    out[i].dR         = 3600.0*(ave[averef].R - in[i].R);
+    out[i].dD         = 3600.0*(ave[averef].D - in[i].D);
     out[i].M          = in[i].M;
     out[i].Mcal       = in[i].Mcal;
@@ -111,5 +113,4 @@
     out[i].psfNdof    = in[i].psfNdof;
     out[i].psfNpix    = in[i].psfNpix;
-    out[i].crNsigma   = in[i].crNsigma;
     out[i].extNsigma  = in[i].extNsigma;
     out[i].FWx 	      = in[i].FWx;
@@ -166,5 +167,5 @@
     out[i].measureOffset = in[i].measureOffset; 
     out[i].missingOffset = in[i].missingOffset;
-    out[i].extendOffset  = in[i].extendOffset;
+    out[i].refColorBlue  = in[i].refColor;
     out[i].flags     	 = in[i].flags;   
     out[i].photFlagsUpper = in[i].photFlagsUpper;   
@@ -210,5 +211,5 @@
     out[i].measureOffset = in[i].measureOffset; 
     out[i].missingOffset = in[i].missingOffset;
-    out[i].extendOffset  = in[i].extendOffset;
+    out[i].refColor      = in[i].refColorBlue;
     out[i].flags     	 = in[i].flags;   
     out[i].photFlagsUpper = in[i].photFlagsUpper;   
@@ -236,17 +237,18 @@
     out[i].dMkron        = in[i].dMkron;      
     out[i].dM            = in[i].dM;      
-    out[i].Xm            = in[i].Xm;     
-    out[i].FluxPSF       = in[i].FluxPSF;
-    out[i].dFluxPSF      = in[i].dFluxPSF;
-    out[i].FluxKron      = in[i].FluxKron;
-    out[i].dFluxKron     = in[i].dFluxKron;
+    out[i].Mchisq        = in[i].Mchisq;     
+    out[i].FpsfStk       = in[i].FluxPSF;
+    out[i].dFpsfStk      = in[i].dFluxPSF;
+    out[i].FkronStk      = in[i].FluxKron;
+    out[i].dFkronStk     = in[i].dFluxKron;
     out[i].flags         = in[i].flags;     
     out[i].Ncode         = in[i].Ncode;
     out[i].Nused         = in[i].Nused;
-    out[i].M_20          = in[i].M_20;      
-    out[i].M_80          = in[i].M_80;      
+    out[i].Mmin          = in[i].M_20*0.001;      
+    out[i].Mmax          = in[i].M_80*0.001;      
     out[i].Mstdev        = in[i].Mstdev;      
     out[i].ubercalDist   = in[i].ubercalDist;      
-    out[i].stackDetectID = in[i].stackDetectID;      
+    out[i].stackPrmryOff = in[i].stackPrmryOff;      
+    out[i].stackBestOff  = in[i].stackBestOff;      
  }
   return (out);
@@ -266,20 +268,23 @@
     out[i].dMkron      	 = in[i].dMkron;      
     out[i].dM          	 = in[i].dM;      
-    out[i].Xm          	 = in[i].Xm;     
-    out[i].FluxPSF     	 = in[i].FluxPSF;
-    out[i].dFluxPSF    	 = in[i].dFluxPSF;
-    out[i].FluxKron    	 = in[i].FluxKron;
-    out[i].dFluxKron   	 = in[i].dFluxKron;
+    out[i].Mchisq        = in[i].Mchisq;
+    out[i].FluxPSF     	 = in[i].FpsfStk;
+    out[i].dFluxPSF    	 = in[i].dFpsfStk;
+    out[i].FluxKron    	 = in[i].FkronStk;
+    out[i].dFluxKron   	 = in[i].dFkronStk;
     out[i].flags       	 = in[i].flags;     
     out[i].Ncode       	 = in[i].Ncode;
     out[i].Nused       	 = in[i].Nused;
-    out[i].M_20        	 = in[i].M_20;      
-    out[i].M_80        	 = in[i].M_80;      
+    out[i].M_20        	 = in[i].Mmin*1000.0;      
+    out[i].M_80        	 = in[i].Mmax*1000.0;      
     out[i].Mstdev      	 = in[i].Mstdev;      
     out[i].ubercalDist 	 = in[i].ubercalDist;      
-    out[i].stackDetectID = in[i].stackDetectID;
-  }
-  return (out);
-}
+    out[i].stackPrmryOff = in[i].stackPrmryOff;      
+    out[i].stackBestOff  = in[i].stackBestOff;      
+  }
+  return (out);
+}
+
+# define RAW_IMAGE_NAME_LEN 121
 
 Image *Image_PS1_V4_ToInternal (Image_PS1_V4 *in, off_t Nvalues, off_t Nalloc) {
@@ -296,6 +301,7 @@
     memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
 
-    strncpy (out[i].name, in[i].name, 120); // out[121], in[121]
-    out[i].name[120] = 0; // force termination
+    // RAW_IMAGE_NAME_LEN > DVO_IMAGE_NAME_LEN
+    strncpy (out[i].name, in[i].name, DVO_IMAGE_NAME_LEN - 1);
+    out[i].name[DVO_IMAGE_NAME_LEN - 1] = 0; // force termination
 
     out[i].tzero    	    = in[i].tzero;
@@ -317,4 +323,5 @@
     out[i].DECo  	    = in[i].DECo;
     out[i].Radius  	    = in[i].Radius;
+    out[i].refColorBlue	    = in[i].refColor;
 
     out[i].detection_limit  = in[i].detection_limit;
@@ -358,6 +365,7 @@
     memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
 
-    strncpy (out[i].name, in[i].name, 120); // out[121], in[121]
-    out[i].name[120] = 0; // force termination
+    // RAW_IMAGE_NAME_LEN > DVO_IMAGE_NAME_LEN
+    strncpy (out[i].name, in[i].name, DVO_IMAGE_NAME_LEN - 1);
+    out[i].name[DVO_IMAGE_NAME_LEN - 1] = 0; // force termination
 
     out[i].tzero    	    = in[i].tzero;
@@ -379,4 +387,5 @@
     out[i].DECo  	    = in[i].DECo;
     out[i].Radius  	    = in[i].Radius;
+    out[i].refColor  	    = in[i].refColorBlue;
 
     out[i].detection_limit  = in[i].detection_limit;
@@ -484,5 +493,5 @@
 /*** there are some mini dvodbs with the wrong PS1_V4 format (missing Xoff,Yoff / Xfix,Yfix) ************/
 
-Measure *Measure_PS1_V4alt_ToInternal (Measure_PS1_V4alt *in, off_t Nvalues) {
+Measure *Measure_PS1_V4alt_ToInternal (Average *ave, Measure_PS1_V4alt *in, off_t Nvalues) {
 
   off_t i;
@@ -494,6 +503,7 @@
     dvo_measure_init (&out[i]);
 
-    out[i].dR         = in[i].dR;
-    out[i].dD         = in[i].dD;
+    int averef = in[i].averef;
+    out[i].R          = ave[averef].R - in[i].dR / 3600.0;
+    out[i].D          = ave[averef].D - in[i].dD / 3600.0;
     out[i].M          = in[i].M;
     out[i].Mcal       = in[i].Mcal;
@@ -529,5 +539,4 @@
     out[i].psfNdof    = in[i].psfNdof;
     out[i].psfNpix    = in[i].psfNpix;
-    out[i].crNsigma   = in[i].crNsigma;
     out[i].extNsigma  = in[i].extNsigma;
     out[i].FWx 	      = in[i].FWx;
@@ -680,5 +689,5 @@
     out[i].measureOffset = in[i].measureOffset; 
     out[i].missingOffset = in[i].missingOffset;
-    out[i].extendOffset  = in[i].extendOffset;
+    out[i].refColorBlue  = in[i].refColor;
     out[i].flags     	 = in[i].flags;   
     out[i].photFlagsUpper = in[i].photFlagsUpper;   
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert_PS1_V5.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert_PS1_V5.c	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert_PS1_V5.c	(revision 37403)
@@ -0,0 +1,1195 @@
+# include <dvo.h>
+
+/* convert PS1_V5 formats to internal formats */
+
+Measure *Measure_PS1_V5_ToInternal (Average *ave, Measure_PS1_V5 *in, off_t Nvalues) {
+
+  off_t i;
+  Measure *out;
+
+  ALLOCATE_ZERO (out, Measure, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    dvo_measure_init (&out[i]);
+
+    out[i].R          = in[i].R;
+    out[i].D          = in[i].D;
+    out[i].M          = in[i].M;
+    out[i].dM         = in[i].dM;
+    out[i].Map        = in[i].Map;
+    out[i].dMap       = in[i].dMap;
+    out[i].Mkron      = in[i].Mkron;
+    out[i].dMkron     = in[i].dMkron;
+    out[i].Mcal       = in[i].Mcal;
+    out[i].dMcal      = in[i].dMcal;
+    out[i].dt         = in[i].dt;
+    out[i].FluxPSF    = in[i].FluxPSF;
+    out[i].dFluxPSF   = in[i].dFluxPSF;
+    out[i].FluxKron   = in[i].FluxKron;
+    out[i].dFluxKron  = in[i].dFluxKron;
+    out[i].FluxAp     = in[i].FluxAp;
+    out[i].dFluxAp    = in[i].dFluxAp;
+    out[i].airmass    = in[i].airmass;
+    out[i].az         = in[i].az;
+    out[i].Xccd       = in[i].Xccd;
+    out[i].Yccd       = in[i].Yccd;
+    out[i].Xfix       = in[i].Xfix;
+    out[i].Yfix       = in[i].Yfix;
+    out[i].XoffKH     = in[i].XoffKH;
+    out[i].YoffKH     = in[i].YoffKH;
+    out[i].XoffDCR    = in[i].XoffDCR;
+    out[i].YoffDCR    = in[i].YoffDCR;
+    out[i].RoffGAL    = in[i].RoffGAL;
+    out[i].DoffGAL    = in[i].DoffGAL;
+    out[i].Sky        = in[i].Sky;
+    out[i].dSky       = in[i].dSky;
+    out[i].t          = in[i].t;
+    out[i].averef     = in[i].averef;
+    out[i].detID      = in[i].detID;
+    out[i].objID      = in[i].objID;
+    out[i].catID      = in[i].catID;
+    out[i].extID      = in[i].extID;
+    out[i].imageID    = in[i].imageID;
+    out[i].psfQF      = in[i].psfQF;
+    out[i].psfQFperf  = in[i].psfQFperf;
+    out[i].psfChisq   = in[i].psfChisq;
+    out[i].psfNdof    = in[i].psfNdof;
+    out[i].psfNpix    = in[i].psfNpix;
+    out[i].extNsigma  = in[i].extNsigma;
+    out[i].FWx 	      = in[i].FWx;
+    out[i].FWy 	      = in[i].FWy;
+    out[i].theta      = in[i].theta;
+    out[i].Mxx 	      = in[i].Mxx;
+    out[i].Mxy 	      = in[i].Mxy;
+    out[i].Myy 	      = in[i].Myy;
+    out[i].t_msec     = in[i].t_msec;
+    out[i].photcode   = in[i].photcode;
+    out[i].dXccd      = in[i].dXccd;
+    out[i].dYccd      = in[i].dYccd;
+    out[i].dRsys      = in[i].dRsys;
+    out[i].posangle   = in[i].posangle;
+    out[i].pltscale   = in[i].pltscale;
+    out[i].dbFlags    = in[i].dbFlags;
+    out[i].photFlags  = in[i].photFlags;
+    out[i].photFlags2 = in[i].photFlags2;
+  }
+  return (out);
+}
+
+Measure_PS1_V5 *MeasureInternalTo_PS1_V5 (Average *ave, Measure *in, off_t Nvalues) {
+
+  off_t i;
+  Measure_PS1_V5 *out;
+
+  ALLOCATE_ZERO (out, Measure_PS1_V5, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    out[i].R          = in[i].R;
+    out[i].D          = in[i].D;
+    out[i].M          = in[i].M;
+    out[i].dM         = in[i].dM;
+    out[i].Map        = in[i].Map;
+    out[i].dMap       = in[i].dMap;
+    out[i].Mkron      = in[i].Mkron;
+    out[i].dMkron     = in[i].dMkron;
+    out[i].Mcal       = in[i].Mcal;
+    out[i].dMcal      = in[i].dMcal;
+    out[i].dt         = in[i].dt;
+    out[i].FluxPSF    = in[i].FluxPSF;
+    out[i].dFluxPSF   = in[i].dFluxPSF;
+    out[i].FluxKron   = in[i].FluxKron;
+    out[i].dFluxKron  = in[i].dFluxKron;
+    out[i].FluxAp     = in[i].FluxAp;
+    out[i].dFluxAp    = in[i].dFluxAp;
+    out[i].airmass    = in[i].airmass;
+    out[i].az         = in[i].az;
+    out[i].Xccd       = in[i].Xccd;
+    out[i].Yccd       = in[i].Yccd;
+    out[i].Xfix       = in[i].Xfix;
+    out[i].Yfix       = in[i].Yfix;
+    out[i].XoffKH     = in[i].XoffKH;
+    out[i].YoffKH     = in[i].YoffKH;
+    out[i].XoffDCR    = in[i].XoffDCR;
+    out[i].YoffDCR    = in[i].YoffDCR;
+    out[i].RoffGAL    = in[i].RoffGAL;
+    out[i].DoffGAL    = in[i].DoffGAL;
+    out[i].Sky        = in[i].Sky;
+    out[i].dSky       = in[i].dSky;
+    out[i].t          = in[i].t;
+    out[i].averef     = in[i].averef;
+    out[i].detID      = in[i].detID;
+    out[i].objID      = in[i].objID;
+    out[i].catID      = in[i].catID;
+    out[i].extID      = in[i].extID;
+    out[i].imageID    = in[i].imageID;
+    out[i].psfQF      = in[i].psfQF;
+    out[i].psfQFperf  = in[i].psfQFperf;
+    out[i].psfChisq   = in[i].psfChisq;
+    out[i].psfNdof    = in[i].psfNdof;
+    out[i].psfNpix    = in[i].psfNpix;
+    out[i].extNsigma  = in[i].extNsigma;
+    out[i].FWx 	      = in[i].FWx;
+    out[i].FWy 	      = in[i].FWy;
+    out[i].theta      = in[i].theta;
+    out[i].Mxx 	      = in[i].Mxx;
+    out[i].Mxy 	      = in[i].Mxy;
+    out[i].Myy 	      = in[i].Myy;
+    out[i].t_msec     = in[i].t_msec;
+    out[i].photcode   = in[i].photcode;
+    out[i].dXccd      = in[i].dXccd;
+    out[i].dYccd      = in[i].dYccd;
+    out[i].dRsys      = in[i].dRsys;
+    out[i].posangle   = in[i].posangle;
+    out[i].pltscale   = in[i].pltscale;
+    out[i].dbFlags    = in[i].dbFlags;
+    out[i].photFlags  = in[i].photFlags;
+    out[i].photFlags2 = in[i].photFlags2;
+  }
+  return (out);
+}
+
+// 'primary' is needed to conform with the API for Loneos and Elixir, but is not used
+Average *Average_PS1_V5_ToInternal (Average_PS1_V5 *in, off_t Nvalues, SecFilt **primary) {
+
+  off_t i;
+  Average *out;
+
+  ALLOCATE_ZERO (out, Average, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    dvo_average_init (&out[i]);
+
+    out[i].R        	 = in[i].R;      
+    out[i].D        	 = in[i].D;      
+    out[i].dR       	 = in[i].dR;
+    out[i].dD       	 = in[i].dD;
+    out[i].uR       	 = in[i].uR;
+    out[i].uD       	 = in[i].uD;
+    out[i].duR      	 = in[i].duR;
+    out[i].duD      	 = in[i].duD;
+    out[i].P        	 = in[i].P;
+    out[i].dP       	 = in[i].dP;
+
+    out[i].Rstk        	 = in[i].Rstk;      
+    out[i].Dstk        	 = in[i].Dstk;      
+    out[i].dRstk       	 = in[i].dRstk;
+    out[i].dDstk       	 = in[i].dDstk;
+
+    out[i].ChiSqAve    	 = in[i].ChiSqAve;     
+    out[i].ChiSqPM    	 = in[i].ChiSqPM;     
+    out[i].ChiSqPar    	 = in[i].ChiSqPar;     
+    out[i].Tmean    	 = in[i].Tmean;     
+    out[i].Trange   	 = in[i].Trange;     
+
+    out[i].psfQF         = in[i].psfQF;
+    out[i].psfQFperf     = in[i].psfQFperf;
+    out[i].stargal     	 = in[i].stargal;     
+    out[i].Npos       	 = in[i].Npos;     
+
+    out[i].Nmeasure      = in[i].Nmeasure;     
+    out[i].Nmissing      = in[i].Nmissing;     
+    out[i].Nlensing      = in[i].Nlensing;     
+    out[i].Nlensobj      = in[i].Nlensobj;     
+    out[i].Nextend       = in[i].Nextend;     
+
+    out[i].measureOffset = in[i].measureOffset; 
+    out[i].missingOffset = in[i].missingOffset;
+    out[i].lensingOffset = in[i].lensingOffset;
+    out[i].lensobjOffset = in[i].lensobjOffset;
+    out[i].extendOffset  = in[i].extendOffset;
+    out[i].paramsOffset  = in[i].paramsOffset;
+
+    out[i].refColorBlue  = in[i].refColorBlue;
+    out[i].refColorRed   = in[i].refColorRed;
+
+    out[i].tessID        = in[i].tessID;
+    out[i].skycellID     = in[i].skycellID;
+    out[i].projectionID  = in[i].projectionID;
+
+    out[i].flags     	 = in[i].flags;   
+    out[i].photFlagsUpper = in[i].photFlagsUpper;   
+    out[i].photFlagsLower = in[i].photFlagsLower;   
+    out[i].objID 	 = in[i].objID;
+    out[i].catID 	 = in[i].catID;
+    out[i].extID 	 = in[i].extID;
+    out[i].extIDgc 	 = in[i].extIDgc;
+  }
+  return (out);
+}
+
+// 'primary' is needed to conform with the API for Loneos and Elixir, but is not used
+Average_PS1_V5 *AverageInternalTo_PS1_V5 (Average *in, off_t Nvalues, SecFilt *primary) {
+
+  off_t i;
+  Average_PS1_V5 *out;
+
+  ALLOCATE_ZERO (out, Average_PS1_V5, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    out[i].R        	  = in[i].R;      
+    out[i].D        	  = in[i].D;      
+    out[i].dR       	  = in[i].dR;
+    out[i].dD       	  = in[i].dD;
+    out[i].uR       	  = in[i].uR;
+    out[i].uD       	  = in[i].uD;
+    out[i].duR      	  = in[i].duR;
+    out[i].duD      	  = in[i].duD;
+    out[i].P        	  = in[i].P;
+    out[i].dP       	  = in[i].dP;
+			  
+    out[i].Rstk        	  = in[i].Rstk;      
+    out[i].Dstk        	  = in[i].Dstk;      
+    out[i].dRstk       	  = in[i].dRstk;
+    out[i].dDstk       	  = in[i].dDstk;
+			  
+    out[i].ChiSqAve    	  = in[i].ChiSqAve;     
+    out[i].ChiSqPM     	  = in[i].ChiSqPM;     
+    out[i].ChiSqPar   	  = in[i].ChiSqPar;     
+    out[i].Tmean    	  = in[i].Tmean;     
+    out[i].Trange   	  = in[i].Trange;     
+			  
+    out[i].psfQF          = in[i].psfQF;
+    out[i].psfQFperf      = in[i].psfQFperf;
+    out[i].stargal     	  = in[i].stargal;     
+    out[i].Npos       	  = in[i].Npos;     
+			  
+    out[i].Nmeasure       = in[i].Nmeasure;     
+    out[i].Nmissing       = in[i].Nmissing;     
+    out[i].Nlensing       = in[i].Nlensing;     
+    out[i].Nlensobj       = in[i].Nlensobj;     
+    out[i].Nextend        = in[i].Nextend;     
+			  
+    out[i].measureOffset  = in[i].measureOffset; 
+    out[i].missingOffset  = in[i].missingOffset;
+    out[i].lensingOffset  = in[i].lensingOffset;
+    out[i].lensobjOffset  = in[i].lensobjOffset;
+    out[i].extendOffset   = in[i].extendOffset;
+    out[i].paramsOffset   = in[i].paramsOffset;
+			  
+    out[i].refColorBlue   = in[i].refColorBlue;
+    out[i].refColorRed    = in[i].refColorRed;
+			  
+    out[i].tessID         = in[i].tessID;
+    out[i].skycellID      = in[i].skycellID;
+    out[i].projectionID   = in[i].projectionID;
+			  
+    out[i].flags     	  = in[i].flags;   
+    out[i].photFlagsUpper = in[i].photFlagsUpper;   
+    out[i].photFlagsLower = in[i].photFlagsLower;   
+    out[i].objID 	  = in[i].objID;
+    out[i].catID 	  = in[i].catID;
+    out[i].extID 	  = in[i].extID;
+    out[i].extIDgc 	  = in[i].extIDgc;
+  }
+  return (out);
+}
+
+SecFilt *SecFilt_PS1_V5_ToInternal (SecFilt_PS1_V5 *in, off_t Nvalues) {
+
+  off_t i;
+  SecFilt *out;
+
+  ALLOCATE_ZERO (out, SecFilt, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    dvo_secfilt_init (&out[i]);
+
+    out[i].M             = in[i].M;      
+    out[i].dM            = in[i].dM;      
+    out[i].Map           = in[i].Map;      
+    out[i].dMap          = in[i].dMap;      
+    out[i].sMap          = in[i].sMap;      
+    out[i].Mkron         = in[i].Mkron;      
+    out[i].dMkron        = in[i].dMkron;      
+    out[i].sMkron        = in[i].sMkron;      
+
+    out[i].psfQfMax      = in[i].psfQfMax;      
+    out[i].psfQfPerfMax  = in[i].psfQfPerfMax;      
+
+    out[i].Mstdev        = in[i].Mstdev;      
+    out[i].Mmin          = in[i].Mmin;      
+    out[i].Mmax          = in[i].Mmax;      
+    out[i].Mchisq        = in[i].Mchisq;     
+
+    out[i].Ncode         = in[i].Ncode;
+    out[i].Nused         = in[i].Nused;
+    out[i].NusedKron     = in[i].NusedKron;
+    out[i].NusedAp       = in[i].NusedAp;
+
+    out[i].flags         = in[i].flags;     
+
+    out[i].MpsfStk       = in[i].MpsfStk;
+    out[i].FpsfStk       = in[i].FpsfStk;
+    out[i].dFpsfStk      = in[i].dFpsfStk;
+
+    out[i].MkronStk      = in[i].MkronStk;
+    out[i].FkronStk      = in[i].FkronStk;
+    out[i].dFkronStk     = in[i].dFkronStk;
+
+    out[i].MapStk        = in[i].MapStk;
+    out[i].FapStk        = in[i].FapStk;
+    out[i].dFapStk       = in[i].dFapStk;
+
+    out[i].Nstack        = in[i].Nstack;      
+    out[i].NstackDet     = in[i].NstackDet;      
+
+    out[i].stackPrmryOff = in[i].stackPrmryOff;      
+    out[i].stackBestOff  = in[i].stackBestOff;      
+
+    out[i].MpsfWrp       = in[i].MpsfWrp;
+    out[i].FpsfWrp       = in[i].FpsfWrp;
+    out[i].dFpsfWrp      = in[i].dFpsfWrp;
+    out[i].sFpsfWrp      = in[i].sFpsfWrp;
+
+    out[i].MkronWrp      = in[i].MkronWrp;
+    out[i].FkronWrp      = in[i].FkronWrp;
+    out[i].dFkronWrp     = in[i].dFkronWrp;
+    out[i].sFkronWrp     = in[i].sFkronWrp;
+
+    out[i].MapWrp        = in[i].MapWrp;
+    out[i].FapWrp        = in[i].FapWrp;
+    out[i].dFapWrp       = in[i].dFapWrp;
+    out[i].sFapWrp       = in[i].sFapWrp;
+
+    out[i].NusedWrp      = in[i].NusedWrp;
+    out[i].NusedKronWrp  = in[i].NusedKronWrp;
+    out[i].NusedApWrp    = in[i].NusedApWrp;
+
+    out[i].Nwarp         = in[i].Nwarp;      
+    out[i].NwarpGood     = in[i].NwarpGood;      
+
+    out[i].ubercalDist   = in[i].ubercalDist;      
+  }
+  return (out);
+}
+
+SecFilt_PS1_V5 *SecFiltInternalTo_PS1_V5 (SecFilt *in, off_t Nvalues) {
+
+  off_t i;
+  SecFilt_PS1_V5 *out;
+
+  ALLOCATE_ZERO (out, SecFilt_PS1_V5, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+
+    out[i].M             = in[i].M;      
+    out[i].dM            = in[i].dM;      
+    out[i].Map           = in[i].Map;      
+    out[i].dMap          = in[i].dMap;      
+    out[i].sMap          = in[i].sMap;      
+    out[i].Mkron         = in[i].Mkron;      
+    out[i].dMkron        = in[i].dMkron;      
+    out[i].sMkron        = in[i].sMkron;      
+
+    out[i].psfQfMax      = in[i].psfQfMax;      
+    out[i].psfQfPerfMax  = in[i].psfQfPerfMax;      
+
+    out[i].Mstdev        = in[i].Mstdev;      
+    out[i].Mmin          = in[i].Mmin;      
+    out[i].Mmax          = in[i].Mmax;      
+    out[i].Mchisq        = in[i].Mchisq;     
+
+    out[i].Ncode         = in[i].Ncode;
+    out[i].Nused         = in[i].Nused;
+    out[i].NusedKron     = in[i].NusedKron;
+    out[i].NusedAp       = in[i].NusedAp;
+
+    out[i].flags         = in[i].flags;     
+
+    out[i].MpsfStk       = in[i].MpsfStk;
+    out[i].FpsfStk       = in[i].FpsfStk;
+    out[i].dFpsfStk      = in[i].dFpsfStk;
+
+    out[i].MkronStk      = in[i].MkronStk;
+    out[i].FkronStk      = in[i].FkronStk;
+    out[i].dFkronStk     = in[i].dFkronStk;
+
+    out[i].MapStk        = in[i].MapStk;
+    out[i].FapStk        = in[i].FapStk;
+    out[i].dFapStk       = in[i].dFapStk;
+
+    out[i].Nstack        = in[i].Nstack;      
+    out[i].NstackDet     = in[i].NstackDet;      
+
+    out[i].stackPrmryOff = in[i].stackPrmryOff;      
+    out[i].stackBestOff  = in[i].stackBestOff;      
+
+    out[i].MpsfWrp       = in[i].MpsfWrp;
+    out[i].FpsfWrp       = in[i].FpsfWrp;
+    out[i].dFpsfWrp      = in[i].dFpsfWrp;
+    out[i].sFpsfWrp      = in[i].sFpsfWrp;
+
+    out[i].MkronWrp      = in[i].MkronWrp;
+    out[i].FkronWrp      = in[i].FkronWrp;
+    out[i].dFkronWrp     = in[i].dFkronWrp;
+    out[i].sFkronWrp     = in[i].sFkronWrp;
+
+    out[i].MapWrp        = in[i].MapWrp;
+    out[i].FapWrp        = in[i].FapWrp;
+    out[i].dFapWrp       = in[i].dFapWrp;
+    out[i].sFapWrp       = in[i].sFapWrp;
+
+    out[i].NusedWrp      = in[i].NusedWrp;
+    out[i].NusedKronWrp  = in[i].NusedKronWrp;
+    out[i].NusedApWrp    = in[i].NusedApWrp;
+
+    out[i].Nwarp         = in[i].Nwarp;      
+    out[i].NwarpGood     = in[i].NwarpGood;      
+
+    out[i].ubercalDist   = in[i].ubercalDist;      
+  }
+  return (out);
+}
+
+Lensing *Lensing_PS1_V5_ToInternal (Lensing_PS1_V5 *in, off_t Nvalues) {
+
+  off_t i;
+  Lensing *out;
+
+  ALLOCATE_ZERO (out, Lensing, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    dvo_lensing_init (&out[i]);
+
+    out[i].X11_sm_obj  = in[i].X11_sm_obj;      
+    out[i].X12_sm_obj  = in[i].X12_sm_obj;      
+    out[i].X22_sm_obj  = in[i].X22_sm_obj;      
+    out[i].E1_sm_obj   = in[i].E1_sm_obj;      
+    out[i].E2_sm_obj   = in[i].E2_sm_obj;      
+	             	                 
+    out[i].X11_sh_obj  = in[i].X11_sh_obj;      
+    out[i].X12_sh_obj  = in[i].X12_sh_obj;      
+    out[i].X22_sh_obj  = in[i].X22_sh_obj;      
+    out[i].E1_sh_obj   = in[i].E1_sh_obj;      
+    out[i].E2_sh_obj   = in[i].E2_sh_obj;     
+	             	                 
+    out[i].X11_sm_psf  = in[i].X11_sm_psf;
+    out[i].X12_sm_psf  = in[i].X12_sm_psf;
+    out[i].X22_sm_psf  = in[i].X22_sm_psf;
+    out[i].E1_sm_psf   = in[i].E1_sm_psf;
+    out[i].E2_sm_psf   = in[i].E2_sm_psf;     
+	             	                 
+    out[i].X11_sh_psf  = in[i].X11_sh_psf;
+    out[i].X12_sh_psf  = in[i].X12_sh_psf;
+    out[i].X22_sh_psf  = in[i].X22_sh_psf;
+    out[i].E1_sh_psf   = in[i].E1_sh_psf;
+    out[i].E2_sh_psf   = in[i].E2_sh_psf;
+
+    out[i].F_ApR5      = in[i].F_ApR5;
+    out[i].dF_ApR5     = in[i].dF_ApR5;
+    out[i].sF_ApR5     = in[i].sF_ApR5;
+    out[i].fF_ApR5     = in[i].fF_ApR5;
+	               	            
+    out[i].F_ApR6      = in[i].F_ApR6;
+    out[i].dF_ApR6     = in[i].dF_ApR6;
+    out[i].sF_ApR6     = in[i].sF_ApR6;
+    out[i].fF_ApR6     = in[i].fF_ApR6;
+	          	            
+    out[i].detID       = in[i].detID;
+    out[i].objID       = in[i].objID;
+    out[i].catID       = in[i].catID;
+
+    out[i].averef      = in[i].averef;
+
+    out[i].imageID     = in[i].imageID;
+  }
+  return (out);
+}
+
+Lensing_PS1_V5 *LensingInternalTo_PS1_V5 (Lensing *in, off_t Nvalues) {
+
+  off_t i;
+  Lensing_PS1_V5 *out;
+
+  ALLOCATE_ZERO (out, Lensing_PS1_V5, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+
+    out[i].X11_sm_obj  = in[i].X11_sm_obj;      
+    out[i].X12_sm_obj  = in[i].X12_sm_obj;      
+    out[i].X22_sm_obj  = in[i].X22_sm_obj;      
+    out[i].E1_sm_obj   = in[i].E1_sm_obj;      
+    out[i].E2_sm_obj   = in[i].E2_sm_obj;      
+	             	                 
+    out[i].X11_sh_obj  = in[i].X11_sh_obj;      
+    out[i].X12_sh_obj  = in[i].X12_sh_obj;      
+    out[i].X22_sh_obj  = in[i].X22_sh_obj;      
+    out[i].E1_sh_obj   = in[i].E1_sh_obj;      
+    out[i].E2_sh_obj   = in[i].E2_sh_obj;     
+	             	                 
+    out[i].X11_sm_psf  = in[i].X11_sm_psf;
+    out[i].X12_sm_psf  = in[i].X12_sm_psf;
+    out[i].X22_sm_psf  = in[i].X22_sm_psf;
+    out[i].E1_sm_psf   = in[i].E1_sm_psf;
+    out[i].E2_sm_psf   = in[i].E2_sm_psf;     
+	             	                 
+    out[i].X11_sh_psf  = in[i].X11_sh_psf;
+    out[i].X12_sh_psf  = in[i].X12_sh_psf;
+    out[i].X22_sh_psf  = in[i].X22_sh_psf;
+    out[i].E1_sh_psf   = in[i].E1_sh_psf;
+    out[i].E2_sh_psf   = in[i].E2_sh_psf;
+
+    out[i].F_ApR5      = in[i].F_ApR5;
+    out[i].dF_ApR5     = in[i].dF_ApR5;
+    out[i].sF_ApR5     = in[i].sF_ApR5;
+    out[i].fF_ApR5     = in[i].fF_ApR5;
+	               	            
+    out[i].F_ApR6      = in[i].F_ApR6;
+    out[i].dF_ApR6     = in[i].dF_ApR6;
+    out[i].sF_ApR6     = in[i].sF_ApR6;
+    out[i].fF_ApR6     = in[i].fF_ApR6;
+	          	            
+    out[i].detID       = in[i].detID;
+    out[i].objID       = in[i].objID;
+    out[i].catID       = in[i].catID;
+
+    out[i].averef      = in[i].averef;
+    out[i].imageID     = in[i].imageID;
+  }
+  return (out);
+}
+
+Lensobj *Lensobj_PS1_V5_ToInternal (Lensobj_PS1_V5 *in, off_t Nvalues) {
+
+  off_t i;
+  Lensobj *out;
+
+  ALLOCATE_ZERO (out, Lensobj, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    dvo_lensobj_init (&out[i], FALSE);
+
+    out[i].X11_sm_obj  = in[i].X11_sm_obj;      
+    out[i].X12_sm_obj  = in[i].X12_sm_obj;      
+    out[i].X22_sm_obj  = in[i].X22_sm_obj;      
+    out[i].E1_sm_obj   = in[i].E1_sm_obj;      
+    out[i].E2_sm_obj   = in[i].E2_sm_obj;      
+	             	                 
+    out[i].X11_sh_obj  = in[i].X11_sh_obj;      
+    out[i].X12_sh_obj  = in[i].X12_sh_obj;      
+    out[i].X22_sh_obj  = in[i].X22_sh_obj;      
+    out[i].E1_sh_obj   = in[i].E1_sh_obj;      
+    out[i].E2_sh_obj   = in[i].E2_sh_obj;     
+	             	                 
+    out[i].X11_sm_psf  = in[i].X11_sm_psf;
+    out[i].X12_sm_psf  = in[i].X12_sm_psf;
+    out[i].X22_sm_psf  = in[i].X22_sm_psf;
+    out[i].E1_sm_psf   = in[i].E1_sm_psf;
+    out[i].E2_sm_psf   = in[i].E2_sm_psf;     
+	             	                 
+    out[i].X11_sh_psf  = in[i].X11_sh_psf;
+    out[i].X12_sh_psf  = in[i].X12_sh_psf;
+    out[i].X22_sh_psf  = in[i].X22_sh_psf;
+    out[i].E1_sh_psf   = in[i].E1_sh_psf;
+    out[i].E2_sh_psf   = in[i].E2_sh_psf;
+
+    out[i].F_ApR5      = in[i].F_ApR5;
+    out[i].dF_ApR5     = in[i].dF_ApR5;
+    out[i].sF_ApR5     = in[i].sF_ApR5;
+    out[i].fF_ApR5     = in[i].fF_ApR5;
+	               	            
+    out[i].F_ApR6      = in[i].F_ApR6;
+    out[i].dF_ApR6     = in[i].dF_ApR6;
+    out[i].sF_ApR6     = in[i].sF_ApR6;
+    out[i].fF_ApR6     = in[i].fF_ApR6;
+	          	            
+    out[i].gamma       = in[i].gamma;
+    out[i].E1          = in[i].E1;
+    out[i].E2          = in[i].E2;
+
+    out[i].objID       = in[i].objID;
+    out[i].catID       = in[i].catID;
+
+    out[i].photcode    = in[i].photcode;
+    out[i].Nmeas       = in[i].Nmeas;
+  }
+  return (out);
+}
+
+Lensobj_PS1_V5 *LensobjInternalTo_PS1_V5 (Lensobj *in, off_t Nvalues) {
+
+  off_t i;
+  Lensobj_PS1_V5 *out;
+
+  ALLOCATE_ZERO (out, Lensobj_PS1_V5, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+
+    out[i].X11_sm_obj  = in[i].X11_sm_obj;      
+    out[i].X12_sm_obj  = in[i].X12_sm_obj;      
+    out[i].X22_sm_obj  = in[i].X22_sm_obj;      
+    out[i].E1_sm_obj   = in[i].E1_sm_obj;      
+    out[i].E2_sm_obj   = in[i].E2_sm_obj;      
+	             	                 
+    out[i].X11_sh_obj  = in[i].X11_sh_obj;      
+    out[i].X12_sh_obj  = in[i].X12_sh_obj;      
+    out[i].X22_sh_obj  = in[i].X22_sh_obj;      
+    out[i].E1_sh_obj   = in[i].E1_sh_obj;      
+    out[i].E2_sh_obj   = in[i].E2_sh_obj;     
+	             	                 
+    out[i].X11_sm_psf  = in[i].X11_sm_psf;
+    out[i].X12_sm_psf  = in[i].X12_sm_psf;
+    out[i].X22_sm_psf  = in[i].X22_sm_psf;
+    out[i].E1_sm_psf   = in[i].E1_sm_psf;
+    out[i].E2_sm_psf   = in[i].E2_sm_psf;     
+	             	                 
+    out[i].X11_sh_psf  = in[i].X11_sh_psf;
+    out[i].X12_sh_psf  = in[i].X12_sh_psf;
+    out[i].X22_sh_psf  = in[i].X22_sh_psf;
+    out[i].E1_sh_psf   = in[i].E1_sh_psf;
+    out[i].E2_sh_psf   = in[i].E2_sh_psf;
+
+    out[i].F_ApR5      = in[i].F_ApR5;
+    out[i].dF_ApR5     = in[i].dF_ApR5;
+    out[i].sF_ApR5     = in[i].sF_ApR5;
+    out[i].fF_ApR5     = in[i].fF_ApR5;
+	               	            
+    out[i].F_ApR6      = in[i].F_ApR6;
+    out[i].dF_ApR6     = in[i].dF_ApR6;
+    out[i].sF_ApR6     = in[i].sF_ApR6;
+    out[i].fF_ApR6     = in[i].fF_ApR6;
+	          	            
+    out[i].gamma       = in[i].gamma;
+    out[i].E1          = in[i].E1;
+    out[i].E2          = in[i].E2;
+
+    out[i].objID       = in[i].objID;
+    out[i].catID       = in[i].catID;
+
+    out[i].photcode    = in[i].photcode;
+    out[i].Nmeas       = in[i].Nmeas;
+  }
+  return (out);
+}
+
+# define RAW_IMAGE_NAME_LEN 117
+
+Image *Image_PS1_V5_ToInternal (Image_PS1_V5 *in, off_t Nvalues, off_t Nalloc) {
+
+  off_t i;
+  Image *out;
+
+  char *buffer;
+  ALLOCATE_ZERO (buffer, char, Nalloc);
+  out = (Image *) buffer;
+  // ALLOCATE_ZERO (out, Image, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
+
+    // RAW_IMAGE_NAME_LEN == DVO_IMAGE_NAME_LEN
+    strncpy (out[i].name, in[i].name, RAW_IMAGE_NAME_LEN - 1);
+    out[i].name[RAW_IMAGE_NAME_LEN - 1] = 0; // force termination
+
+    out[i].tzero    	    = in[i].tzero;
+    out[i].nstar    	    = in[i].nstar;
+    out[i].secz	    	    = in[i].secz;
+    out[i].NX	    	    = in[i].NX;
+    out[i].NY	    	    = in[i].NY;
+    out[i].apmifit  	    = in[i].apmifit;
+    out[i].dapmifit 	    = in[i].dapmifit;
+    out[i].Mcal	    	    = in[i].Mcal;
+    out[i].dMcal    	    = in[i].dMcal;
+    out[i].Xm	    	    = in[i].Xm;
+    out[i].photcode   	    = in[i].photcode;
+    out[i].exptime  	    = in[i].exptime;
+    out[i].sidtime  	    = in[i].sidtime;
+    out[i].latitude  	    = in[i].latitude;
+
+    out[i].RAo  	    = in[i].RAo;
+    out[i].DECo  	    = in[i].DECo;
+    out[i].Radius  	    = in[i].Radius;
+    out[i].refColorBlue	    = in[i].refColorBlue;
+    out[i].refColorRed 	    = in[i].refColorRed;
+
+    out[i].detection_limit  = in[i].detection_limit;
+    out[i].saturation_limit = in[i].saturation_limit;
+    out[i].cerror	    = in[i].cerror;
+    out[i].fwhm_x	    = in[i].fwhm_x;
+    out[i].fwhm_y	    = in[i].fwhm_y;
+    out[i].trate	    = in[i].trate;
+    out[i].ccdnum	    = in[i].ccdnum;
+    out[i].flags	    = in[i].flags;
+    out[i].imageID	    = in[i].imageID;
+    out[i].parentID	    = in[i].parentID;
+    out[i].externID	    = in[i].externID;
+    out[i].sourceID	    = in[i].sourceID;
+
+    // as of 2011.02.03, the old Mx,My,..., Mxxxx,Myyyy have been deprecated and replaced
+    // with the following.  (no real databases used those values -- see
+    // libdvo/doc/dvo-images.txt)
+    out[i].nLinkAstrom	    = in[i].nLinkAstrom;
+    out[i].nLinkPhotom	    = in[i].nLinkPhotom;
+    out[i].ubercalDist	    = in[i].ubercalDist;
+    out[i].dXpixSys	    = in[i].dXpixSys;
+    out[i].dYpixSys	    = in[i].dYpixSys;
+    out[i].dMagSys	    = in[i].dMagSys;
+    out[i].nFitAstrom       = in[i].nFitAstrom;
+    out[i].nFitPhotom       = in[i].nFitPhotom;
+    out[i].photom_map_id    = in[i].photom_map_id;
+    out[i].astrom_map_id    = in[i].astrom_map_id;
+  }
+  return (out);
+}
+
+Image_PS1_V5 *ImageInternalTo_PS1_V5 (Image *in, off_t Nvalues) {
+
+  off_t i;
+  Image_PS1_V5 *out;
+
+  ALLOCATE_ZERO (out, Image_PS1_V5, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
+
+    // RAW_IMAGE_NAME_LEN == DVO_IMAGE_NAME_LEN
+    strncpy (out[i].name, in[i].name, RAW_IMAGE_NAME_LEN - 1);
+    out[i].name[RAW_IMAGE_NAME_LEN - 1] = 0; // force termination
+
+    out[i].tzero    	    = in[i].tzero;
+    out[i].nstar    	    = in[i].nstar;
+    out[i].secz	    	    = in[i].secz;
+    out[i].NX	    	    = in[i].NX;
+    out[i].NY	    	    = in[i].NY;
+    out[i].apmifit  	    = in[i].apmifit;
+    out[i].dapmifit 	    = in[i].dapmifit;
+    out[i].Mcal	    	    = in[i].Mcal;
+    out[i].dMcal    	    = in[i].dMcal;
+    out[i].Xm	    	    = in[i].Xm;
+    out[i].photcode   	    = in[i].photcode;
+    out[i].exptime  	    = in[i].exptime;
+    out[i].sidtime  	    = in[i].sidtime;
+    out[i].latitude  	    = in[i].latitude;
+
+    out[i].RAo  	    = in[i].RAo;
+    out[i].DECo  	    = in[i].DECo;
+    out[i].Radius  	    = in[i].Radius;
+    out[i].refColorBlue	    = in[i].refColorBlue;
+    out[i].refColorRed 	    = in[i].refColorRed;
+
+    out[i].detection_limit  = in[i].detection_limit;
+    out[i].saturation_limit = in[i].saturation_limit;
+    out[i].cerror	    = in[i].cerror;
+    out[i].fwhm_x	    = in[i].fwhm_x;
+    out[i].fwhm_y	    = in[i].fwhm_y;
+    out[i].trate	    = in[i].trate;
+    out[i].ccdnum	    = in[i].ccdnum;
+    out[i].flags	    = in[i].flags;
+    out[i].imageID	    = in[i].imageID;
+    out[i].parentID	    = in[i].parentID;
+    out[i].externID	    = in[i].externID;
+    out[i].sourceID	    = in[i].sourceID;
+
+    // as of 2011.02.03, the old Mx,My,..., Mxxxx,Myyyy have been deprecated and replaced
+    // with the following.  (no real databases used those values -- see
+    // libdvo/doc/dvo-images.txt)
+    out[i].nLinkAstrom	    = in[i].nLinkAstrom;
+    out[i].nLinkPhotom	    = in[i].nLinkPhotom;
+    out[i].ubercalDist	    = in[i].ubercalDist;
+    out[i].dXpixSys	    = in[i].dXpixSys;
+    out[i].dYpixSys	    = in[i].dYpixSys;
+    out[i].dMagSys	    = in[i].dMagSys;
+    out[i].nFitAstrom       = in[i].nFitAstrom;
+    out[i].nFitPhotom       = in[i].nFitPhotom;
+    out[i].photom_map_id    = in[i].photom_map_id;
+    out[i].astrom_map_id    = in[i].astrom_map_id;
+  }
+  return (out);
+}
+
+PhotCode *PhotCode_PS1_V5_To_Internal (PhotCode_PS1_V5 *in, off_t Nvalues) {
+
+  off_t i;
+  PhotCode *out;
+
+  ALLOCATE_ZERO (out, PhotCode, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    strncpy (out[i].name, in[i].name, 31); // out[32], in[32]
+    out[i].name[31] = 0; // force termination
+
+    out[i].code  = in[i].code;         
+    out[i].type  = in[i].type;         
+    out[i].C     = in[i].C;            
+    out[i].dC 	 = in[i].dC;           
+    out[i].dX 	 = in[i].dX;           
+    out[i].K  	 = in[i].K;            
+    out[i].c1 	 = in[i].c1;           
+    out[i].c2 	 = in[i].c2;           
+    out[i].equiv = in[i].equiv;        
+    out[i].Nc    = in[i].Nc;           
+    memcpy (out[i].X, in[i].X, 4*sizeof(float));            
+
+    out[i].astromErrSys      = in[i].astromErrSys;
+    out[i].astromErrScale    = in[i].astromErrScale;
+    out[i].astromErrMagScale = in[i].astromErrMagScale;
+    out[i].photomErrSys      = in[i].photomErrSys;
+
+    out[i].photomPoorMask      = in[i].photomPoorMask;
+    out[i].photomBadMask       = in[i].photomBadMask;
+    out[i].astromPoorMask      = in[i].astromPoorMask;
+    out[i].astromBadMask       = in[i].astromBadMask;
+  }
+  return (out);
+}
+
+PhotCode_PS1_V5 *PhotCode_Internal_To_PS1_V5 (PhotCode *in, off_t Nvalues) {
+
+  off_t i;
+  PhotCode_PS1_V5 *out;
+
+  ALLOCATE_ZERO (out, PhotCode_PS1_V5, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    strncpy (out[i].name, in[i].name, 31); // out[32], in[32]
+    out[i].name[31] = 0; // force termination
+
+    out[i].code  = in[i].code;         
+    out[i].type  = in[i].type;         
+    out[i].C     = in[i].C;            
+    out[i].dC 	 = in[i].dC;           
+    out[i].dX 	 = in[i].dX;           
+    out[i].K  	 = in[i].K;            
+    out[i].c1 	 = in[i].c1;           
+    out[i].c2 	 = in[i].c2;           
+    out[i].equiv = in[i].equiv;        
+    out[i].Nc    = in[i].Nc;           
+    memcpy (out[i].X, in[i].X, 4*sizeof(float));            
+
+    out[i].astromErrSys      = in[i].astromErrSys;
+    out[i].astromErrScale    = in[i].astromErrScale;
+    out[i].astromErrMagScale = in[i].astromErrMagScale;
+    out[i].photomErrSys      = in[i].photomErrSys;
+
+    out[i].photomPoorMask      = in[i].photomPoorMask;
+    out[i].photomBadMask       = in[i].photomBadMask;
+    out[i].astromPoorMask      = in[i].astromPoorMask;
+    out[i].astromBadMask       = in[i].astromBadMask;
+  }
+  return (out);
+}
+
+/*********************** old / alternate version **********************/
+
+// 'primary' is needed to conform with the API for Loneos and Elixir, but is not used
+Average *Average_PS1_V5alt_ToInternal (Average_PS1_V5alt *in, off_t Nvalues) {
+
+  off_t i;
+  Average *out;
+
+  ALLOCATE_ZERO (out, Average, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    dvo_average_init (&out[i]);
+
+    out[i].R        	  = in[i].R;      
+    out[i].D        	  = in[i].D;      
+    out[i].dR       	  = in[i].dR;
+    out[i].dD       	  = in[i].dD;
+    out[i].uR       	  = in[i].uR;
+    out[i].uD       	  = in[i].uD;
+    out[i].duR      	  = in[i].duR;
+    out[i].duD      	  = in[i].duD;
+    out[i].P        	  = in[i].P;
+    out[i].dP       	  = in[i].dP;
+			  
+    out[i].Rstk        	  = in[i].Rstk;      
+    out[i].Dstk        	  = in[i].Dstk;      
+    out[i].dRstk       	  = in[i].dRstk;
+    out[i].dDstk       	  = in[i].dDstk;
+			  
+    out[i].ChiSqAve    	  = in[i].ChiSqAve;     
+    out[i].ChiSqPM    	  = in[i].ChiSqPM;     
+    out[i].ChiSqPar    	  = in[i].ChiSqPar;     
+    out[i].Tmean    	  = in[i].Tmean;     
+    out[i].Trange   	  = in[i].Trange;     
+			  
+    out[i].psfQF          = in[i].psfQF;
+    out[i].psfQFperf      = in[i].psfQFperf;
+    out[i].stargal     	  = in[i].stargal;     
+    out[i].Npos       	  = in[i].Npos;     
+			  
+    out[i].Nmeasure       = in[i].Nmeasure;     
+    out[i].Nmissing       = in[i].Nmissing;     
+    out[i].Nlensing       = in[i].Nlensing;     
+    out[i].Nlensobj       = in[i].Nlensobj;     
+    out[i].Nextend        = in[i].Nextend;     
+			  
+    out[i].measureOffset  = in[i].measureOffset; 
+    out[i].missingOffset  = in[i].missingOffset;
+    out[i].lensingOffset  = in[i].lensingOffset;
+    out[i].lensobjOffset  = in[i].lensobjOffset;
+    out[i].extendOffset   = in[i].extendOffset;
+    out[i].paramsOffset   = in[i].paramsOffset;
+			  
+    out[i].refColorBlue   = in[i].refColorBlue;
+    out[i].refColorRed    = in[i].refColorRed;
+			  
+    out[i].flags     	  = in[i].flags;   
+    out[i].photFlagsUpper = in[i].photFlagsUpper;   
+    out[i].photFlagsLower = in[i].photFlagsLower;   
+    out[i].objID 	  = in[i].objID;
+    out[i].catID 	  = in[i].catID;
+    out[i].extID 	  = in[i].extID;
+    out[i].extIDgc 	  = in[i].extIDgc;
+  }
+  return (out);
+}
+
+int gfits_convert_Average_PS1_V5alt (Average_PS1_V5alt *data, off_t size, off_t nitems) {
+
+  off_t i;
+  unsigned char *byte, tmp;
+
+  if (size != 184) { 
+    fprintf (stderr, "WARNING: mismatch in data types Average_PS1_V5alt: "OFF_T_FMT" vs %d\n",  size,  184);
+    return (FALSE);
+  }
+
+  /* provide initial values to avoid compiler warnings for non-BYTE_SWAP arch */
+  i = tmp = 0;
+  byte = NULL;
+
+# ifdef BYTE_SWAP
+  byte = (unsigned char *) data;
+  for (i = 0; i < nitems; i++, byte += 184) {
+    /** BYTE SWAP **/
+    SWAP_DBLE (0); // RA
+    SWAP_DBLE (8); // DEC
+    SWAP_WORD (16); // RA_ERR
+    SWAP_WORD (20); // DEC_ERR
+    SWAP_WORD (24); // U_RA
+    SWAP_WORD (28); // U_DEC
+    SWAP_WORD (32); // V_RA_ERR
+    SWAP_WORD (36); // V_DEC_ERR
+    SWAP_WORD (40); // PAR
+    SWAP_WORD (44); // PAR_ERR
+    SWAP_DBLE (48); // RA_STK
+    SWAP_DBLE (56); // DEC_STK
+    SWAP_WORD (64); // RA_STK_ERR
+    SWAP_WORD (68); // DEC_STK_ERR
+    SWAP_WORD (72); // CHISQ_POS
+    SWAP_WORD (76); // CHISQ_PM
+    SWAP_WORD (80); // CHISQ_PAP
+    SWAP_WORD (84); // MEAN_EPOCH
+    SWAP_WORD (88); // TIME_RANGE
+    SWAP_WORD (92); // PSF_QF
+    SWAP_WORD (96); // PSF_QF_PERF
+    SWAP_WORD (100); // STARGAL_SEP
+    SWAP_BYTE (104); // NUMBER_POS
+    SWAP_BYTE (106); // NMEASURE
+    SWAP_BYTE (108); // NMISSING
+    SWAP_BYTE (110); // NLENSING
+    SWAP_BYTE (112); // NLENSOBJ
+    SWAP_BYTE (114); // NEXTEND
+    SWAP_WORD (116); // OFF_MEASURE
+    SWAP_WORD (120); // OFF_MISSING
+    SWAP_WORD (124); // OFF_LENSING
+    SWAP_WORD (128); // OFF_LENSOBJ
+    SWAP_WORD (132); // OFF_EXTEND
+    SWAP_WORD (136); // OFF_PARAMS
+    SWAP_WORD (140); // REF_COLOR_BLUE
+    SWAP_WORD (144); // REF_COLOR_RED
+    SWAP_WORD (148); // FLAGS
+    SWAP_WORD (152); // PHOTFLAGS_U
+    SWAP_WORD (156); // PHOTFLAGS_L
+    SWAP_WORD (160); // OBJ_ID
+    SWAP_WORD (164); // CAT_ID
+    SWAP_DBLE (168); // EXT_ID
+    SWAP_DBLE (176); // EXT_ID_GC
+  }
+# endif  
+
+  return (TRUE);
+} 
+
+/*** add test of EXTNAME and header-defined columns? ***/
+/* return internal structure representation */
+Average_PS1_V5alt *gfits_table_get_Average_PS1_V5alt (FTable *ftable, off_t *Ndata, char *swapped) {
+
+  int Ncols;
+  Average_PS1_V5alt *data;
+
+  Ncols = ftable[0].header[0].Naxis[0];
+  if (Ncols != 184) {
+    fprintf (stderr, "ERROR: mis-match in table size: width is %d but should be %d bytes\n", Ncols, 184);
+    return NULL;
+  }
+
+  *Ndata = ftable[0].header[0].Naxis[1];
+  data = (Average_PS1_V5alt *) ftable[0].buffer;
+  if ((swapped == NULL) || (*swapped == FALSE)) {
+    if (!gfits_convert_Average_PS1_V5alt (data, sizeof (Average_PS1_V5alt), *Ndata)) {
+      return NULL;
+    }
+    gfits_table_scale_data (ftable);
+    if (swapped != NULL) *swapped = TRUE;
+  }
+  return (data);
+}
+
+/****** alt secfilt **********/
+
+SecFilt *SecFilt_PS1_V5alt_ToInternal (SecFilt_PS1_V5alt *in, off_t Nvalues) {
+
+  off_t i;
+  SecFilt *out;
+
+  ALLOCATE_ZERO (out, SecFilt, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    dvo_secfilt_init (&out[i]);
+
+    out[i].M             = in[i].M;      
+    out[i].dM            = in[i].dM;      
+    out[i].Map           = in[i].Map;      
+    out[i].dMap          = in[i].dMap;      
+    out[i].sMap          = in[i].sMap;      
+    out[i].Mkron         = in[i].Mkron;      
+    out[i].dMkron        = in[i].dMkron;      
+
+    out[i].Mstdev        = in[i].Mstdev;      
+    out[i].Mmin          = in[i].Mmin;      
+    out[i].Mmax          = in[i].Mmax;      
+    out[i].Mchisq        = in[i].Mchisq;     
+
+    out[i].Ncode         = in[i].Ncode;
+    out[i].Nused         = in[i].Nused;
+    out[i].NusedKron     = in[i].NusedKron;
+    out[i].NusedAp       = in[i].NusedAp;
+
+    out[i].flags         = in[i].flags;     
+
+    out[i].MpsfStk       = in[i].MpsfStk;
+    out[i].FpsfStk       = in[i].FpsfStk;
+    out[i].dFpsfStk      = in[i].dFpsfStk;
+
+    out[i].MkronStk      = in[i].MkronStk;
+    out[i].FkronStk      = in[i].FkronStk;
+    out[i].dFkronStk     = in[i].dFkronStk;
+
+    out[i].MapStk        = in[i].MapStk;
+    out[i].FapStk        = in[i].FapStk;
+    out[i].dFapStk       = in[i].dFapStk;
+
+    out[i].stackPrmryOff = in[i].stackPrmryOff;      
+    out[i].stackBestOff  = in[i].stackBestOff;      
+
+    out[i].MpsfWrp       = in[i].MpsfWrp;
+    out[i].FpsfWrp       = in[i].FpsfWrp;
+    out[i].dFpsfWrp      = in[i].dFpsfWrp;
+    out[i].sFpsfWrp      = in[i].sFpsfWrp;
+
+    out[i].MkronWrp      = in[i].MkronWrp;
+    out[i].FkronWrp      = in[i].FkronWrp;
+    out[i].dFkronWrp     = in[i].dFkronWrp;
+    out[i].sFkronWrp     = in[i].sFkronWrp;
+
+    out[i].MapWrp        = in[i].MapWrp;
+    out[i].FapWrp        = in[i].FapWrp;
+    out[i].dFapWrp       = in[i].dFapWrp;
+    out[i].sFapWrp       = in[i].sFapWrp;
+
+    out[i].NusedWrp      = in[i].NusedWrp;
+    out[i].NusedKronWrp  = in[i].NusedKronWrp;
+    out[i].NusedApWrp    = in[i].NusedApWrp;
+
+    out[i].ubercalDist   = in[i].ubercalDist;      
+  }
+  return (out);
+}
+
+int gfits_convert_SecFilt_PS1_V5alt (SecFilt_PS1_V5alt *data, off_t size, off_t nitems) {
+
+  off_t i;
+  unsigned char *byte, tmp;
+
+  if (size != 160) { 
+    fprintf (stderr, "WARNING: mismatch in data types SecFilt_PS1_V5alt: "OFF_T_FMT" vs %d\n",  size,  160);
+    return (FALSE);
+  }
+
+  /* provide initial values to avoid compiler warnings for non-BYTE_SWAP arch */
+  i = tmp = 0;
+  byte = NULL;
+
+# ifdef BYTE_SWAP
+  byte = (unsigned char *) data;
+  for (i = 0; i < nitems; i++, byte += 160) {
+    /** BYTE SWAP **/
+    SWAP_WORD (0); // MAG
+    SWAP_WORD (4); // MAG_ERR
+    SWAP_WORD (8); // MAG_AP
+    SWAP_WORD (12); // MAG_AP_ERR
+    SWAP_WORD (16); // MAG_AP_STDEV
+    SWAP_WORD (20); // MAG_KRON
+    SWAP_WORD (24); // MAG_KRON_ERR
+    SWAP_WORD (28); // MAG_KRON_STDEV
+    SWAP_WORD (32); // MAG_STDEV
+    SWAP_WORD (36); // MAG_MIN
+    SWAP_WORD (40); // MAG_MAX
+    SWAP_WORD (44); // MAG_CHI
+    SWAP_BYTE (48); // NCODE
+    SWAP_BYTE (50); // NUSED
+    SWAP_BYTE (52); // NUSED_KRON
+    SWAP_BYTE (54); // NUSED_AP
+    SWAP_WORD (56); // FLAGS
+    SWAP_WORD (60); // MAG_PSF_STK
+    SWAP_WORD (64); // FLUX_PSF_STK
+    SWAP_WORD (68); // FLUX_PSF_STK_ERR
+    SWAP_WORD (72); // MAG_KRON_STK
+    SWAP_WORD (76); // FLUX_KRON_STK
+    SWAP_WORD (80); // FLUX_KRON_STK_ERR
+    SWAP_WORD (84); // MAG_AP_STK
+    SWAP_WORD (88); // FLUX_AP_STK
+    SWAP_WORD (92); // FLUX_AP_STK_ERR
+    SWAP_WORD (96); // STACK_PRIMARY_OFF
+    SWAP_WORD (100); // STACK_BEST_OFF
+    SWAP_WORD (104); // MAG_PSF_WRP
+    SWAP_WORD (108); // FLUX_PSF_WRP
+    SWAP_WORD (112); // FLUX_PSF_WRP_ERR
+    SWAP_WORD (116); // FLUX_PSF_WRP_STD
+    SWAP_WORD (120); // MAG_KRON_WRP
+    SWAP_WORD (124); // FLUX_KRON_WRP
+    SWAP_WORD (128); // FLUX_KRON_WRP_ERR
+    SWAP_WORD (132); // FLUX_KRON_WRP_STD
+    SWAP_WORD (136); // MAG_AP_WRP
+    SWAP_WORD (140); // FLUX_AP_WRP
+    SWAP_WORD (144); // FLUX_AP_WRP_ERR
+    SWAP_WORD (148); // FLUX_AP_WRP_STD
+    SWAP_BYTE (152); // NUSED_WRP
+    SWAP_BYTE (154); // NUSED_KRON_WRP
+    SWAP_BYTE (156); // NUSED_AP_WRP
+    SWAP_BYTE (158); // UBERCAL_DIST
+  }
+# endif  
+
+  return (TRUE);
+} 
+
+/*** add test of EXTNAME and header-defined columns? ***/
+/* return internal structure representation */
+SecFilt_PS1_V5alt *gfits_table_get_SecFilt_PS1_V5alt (FTable *ftable, off_t *Ndata, char *swapped) {
+
+  int Ncols;
+  SecFilt_PS1_V5alt *data;
+
+  Ncols = ftable[0].header[0].Naxis[0];
+  if (Ncols != 160) {
+    fprintf (stderr, "ERROR: mis-match in table size: width is %d but should be %d bytes\n", Ncols, 160);
+    return NULL;
+  }
+
+  *Ndata = ftable[0].header[0].Naxis[1];
+  data = (SecFilt_PS1_V5alt *) ftable[0].buffer;
+  if ((swapped == NULL) || (*swapped == FALSE)) {
+    if (!gfits_convert_SecFilt_PS1_V5alt (data, sizeof (SecFilt_PS1_V5alt), *Ndata)) {
+      return NULL;
+    }
+    gfits_table_scale_data (ftable);
+    if (swapped != NULL) *swapped = TRUE;
+  }
+  return (data);
+}
+
+
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert_elixir.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert_elixir.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert_elixir.c	(revision 37403)
@@ -2,5 +2,5 @@
 
 /* convert elixir-format measures to internal measures */
-Measure *Measure_Elixir_ToInternal (Measure_Elixir *in, off_t Nvalues) {
+Measure *Measure_Elixir_ToInternal (Average *ave, Measure_Elixir *in, off_t Nvalues) {
 
   off_t i;
@@ -15,7 +15,10 @@
     out[i].averef   = in[i].averef;
 
+    // changed for PS1_V5
+    int averef = out[i].averef;
+    out[i].R          = (in[i].dR == NAN_S_SHORT) ? NAN : ave[averef].R - 0.01 * in[i].dR / 3600.0;
+    out[i].D          = (in[i].dD == NAN_S_SHORT) ? NAN : ave[averef].D - 0.01 * in[i].dD / 3600.0;
+
     // changed for PANSTARRS_DEV_0
-    out[i].dR       = (in[i].dR      == NAN_S_SHORT) ? NAN : in[i].dR     * 0.01;
-    out[i].dD       = (in[i].dD      == NAN_S_SHORT) ? NAN : in[i].dD     * 0.01;
     out[i].M        = (in[i].M       == NAN_S_SHORT) ? NAN : in[i].M      * 0.001;
     out[i].dM       = (in[i].dM      == NAN_U_CHAR)  ? NAN : in[i].dM     * 0.001;
@@ -47,5 +50,5 @@
 
 /* convert internal measures to elixir-format measures */
-Measure_Elixir *MeasureInternalTo_Elixir (Measure *in, off_t Nvalues) {
+Measure_Elixir *MeasureInternalTo_Elixir (Average *ave, Measure *in, off_t Nvalues) {
 
   off_t i;
@@ -59,7 +62,11 @@
     out[i].averef  = in[i].averef;
 
+    // changed for PS1_V5
+    int averef = in[i].averef;
+    int isBad = isnan(in[i].R) || isnan(in[i].D);
+    out[i].dR     = isBad ? NAN_S_SHORT : 100.0*3600.0*(ave[averef].R - in[i].R);
+    out[i].dD     = isBad ? NAN_S_SHORT : 100.0*3600.0*(ave[averef].D - in[i].D);
+
     // changed for PANSTARRS_DEV_0
-    out[i].dR       = isnan(in[i].dR     ) ? NAN_S_SHORT : in[i].dR      *  100.0;
-    out[i].dD       = isnan(in[i].dD     ) ? NAN_S_SHORT : in[i].dD      *  100.0;
     out[i].M        = isnan(in[i].M      ) ? NAN_S_SHORT : in[i].M       * 1000.0;
     out[i].dM       = isnan(in[i].dM     ) ? NAN_U_CHAR  : in[i].dM      * 1000.0;
@@ -104,5 +111,5 @@
     primary[0][i].M     = (in[i].M  == NAN_S_SHORT) ? NAN : in[i].M  * 0.001;      
     primary[0][i].dM    = (in[i].dM == NAN_S_SHORT) ? NAN : in[i].dM * 0.001;      
-    primary[0][i].Xm    = in[i].Xm;     
+    primary[0][i].Mchisq= pow (10.0, 0.01*in[i].Xm);     
 
     // added for PANSTARRS_DEV_0
@@ -137,5 +144,5 @@
     out[i].M       = isnan(primary[i].M)  ? NAN_S_SHORT : primary[i].M   * 1000.0;
     out[i].dM      = isnan(primary[i].dM) ? NAN_S_SHORT : primary[i].dM  * 1000.0;
-    out[i].Xm      = primary[i].Xm;     
+    out[i].Xm      = 100.0*log10(primary[i].Mchisq);     
 
     // changed or added for PS1_DEV_2
@@ -162,5 +169,5 @@
     dvo_secfilt_init (&out[i]);
 
-    out[i].Xm    = in[i].Xm;     
+    out[i].Mchisq = pow (10.0, 0.01*in[i].Xm);     
 
     // added or changed for PANSTARRS_DEV_0
@@ -180,5 +187,5 @@
 
   for (i = 0; i < Nvalues; i++) {
-    out[i].Xm    = in[i].Xm;     
+    out[i].Xm    = 100.0*log10(in[i].Mchisq);     
 
     // added or changed for PANSTARRS_DEV_0
@@ -188,4 +195,6 @@
   return (out);
 }
+
+# define RAW_IMAGE_NAME_LEN 32
 
 /* convert elixir-format images to internal images */
@@ -203,6 +212,7 @@
     memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
 
-    strncpy (out[i].name, in[i].name, 31); // in[32], out[128]
-    out[i].name[31] = 0; // force termination
+    // RAW_IMAGE_NAME_LEN < DVO_IMAGE_NAME_LEN
+    strncpy (out[i].name, in[i].name, RAW_IMAGE_NAME_LEN - 1);
+    out[i].name[RAW_IMAGE_NAME_LEN - 1] = 0; // force termination
 
     out[i].tzero    	    = in[i].tzero;
@@ -272,6 +282,7 @@
     memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
 
-    strncpy (out[i].name, in[i].name, 31); // out[32], in[128]
-    out[i].name[31] = 0; // force termination
+    // RAW_IMAGE_NAME_LEN < DVO_IMAGE_NAME_LEN
+    strncpy (out[i].name, in[i].name, RAW_IMAGE_NAME_LEN - 1);
+    out[i].name[RAW_IMAGE_NAME_LEN - 1] = 0; // force termination
 
     out[i].tzero    	    = in[i].tzero;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert_loneos.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert_loneos.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert_loneos.c	(revision 37403)
@@ -2,5 +2,5 @@
 
 /* convert loneos-format measures to internal measures */
-Measure *Measure_Loneos_ToInternal (Measure_Loneos *in, off_t Nvalues) {
+Measure *Measure_Loneos_ToInternal (Average *ave, Measure_Loneos *in, off_t Nvalues) {
 
   off_t i;
@@ -18,7 +18,10 @@
     out[i].t         = in[i].t;
 
+    // changed for PS1_V5
+    int averef = out[i].averef;
+    out[i].R          = (in[i].dR == NAN_S_SHORT) ? NAN : ave[averef].R - 0.01 * in[i].dR / 3600.0;
+    out[i].D          = (in[i].dD == NAN_S_SHORT) ? NAN : ave[averef].D - 0.01 * in[i].dD / 3600.0;
+
     // changed for PANSTARRS_DEV_0
-    out[i].dR       = (in[i].dR      == NAN_S_SHORT) ? NAN : in[i].dR     * 0.01;
-    out[i].dD       = (in[i].dD      == NAN_S_SHORT) ? NAN : in[i].dD     * 0.01;
     out[i].M        = (in[i].M       == NAN_S_SHORT) ? NAN : in[i].M      * 0.001;
     out[i].dM       = (in[i].dM      == NAN_U_CHAR)  ? NAN : in[i].dM     * 0.001;
@@ -40,5 +43,5 @@
 
 /* convert internal measures to loneos-format measures */
-Measure_Loneos *MeasureInternalTo_Loneos (Measure *in, off_t Nvalues) {
+Measure_Loneos *MeasureInternalTo_Loneos (Average *ave, Measure *in, off_t Nvalues) {
 
   off_t i;
@@ -48,8 +51,10 @@
 
   for (i = 0; i < Nvalues; i++) {
-
-    // changed for PANSTARRS_DEV_0
-    out[i].dR     = isnan(in[i].dR     ) ? NAN_S_SHORT : in[i].dR      *  100.0;
-    out[i].dD     = isnan(in[i].dD     ) ? NAN_S_SHORT : in[i].dD      *  100.0;
+    // changed for PS1_V5
+    int averef = in[i].averef;
+    int isBad = isnan(in[i].R) || isnan(in[i].D);
+    out[i].dR     = isBad ? NAN_S_SHORT : 100.0*3600.0*(ave[averef].R - in[i].R);
+    out[i].dD     = isBad ? NAN_S_SHORT : 100.0*3600.0*(ave[averef].D - in[i].D);
+
     out[i].M      = isnan(in[i].M      ) ? NAN_S_SHORT : in[i].M       * 1000.0;
     out[i].dM     = isnan(in[i].dM     ) ? NAN_U_CHAR  : in[i].dM      * 1000.0;
@@ -85,5 +90,5 @@
     // changed for PANSTARRS_DEV_0 (moved from Average to Measure)
     primary[0][i].M     = (in[i].M  == NAN_S_SHORT) ? NAN : in[i].M  * 0.001;      
-    primary[0][i].Xm    = in[i].Xm;     
+    primary[0][i].Mchisq= pow (10.0, 0.01*in[i].Xm);     
 
     // added for PANSTARRS_DEV_0
@@ -119,5 +124,5 @@
     // changed for PANSTARRS_DEV_0 (moved from Average to Measure)
     out[i].M       = isnan(primary[i].M)  ? NAN_S_SHORT : primary[i].M   * 1000.0;
-    out[i].Xm      = primary[i].Xm;     
+    out[i].Xm      = 100.0*log10(primary[i].Mchisq);     
 
     // changed or added for PS1_DEV_2
@@ -144,5 +149,5 @@
     dvo_secfilt_init (&out[i]);
 
-    out[i].Xm    = in[i].Xm;      
+    out[i].Mchisq= pow (10.0, 0.01*in[i].Xm);     
 
     // added or changed for PANSTARRS_DEV_0
@@ -161,5 +166,5 @@
 
   for (i = 0; i < Nvalues; i++) {
-    out[i].Xm   = in[i].Xm;      
+    out[i].Xm   = 100.0*log10(in[i].Mchisq);      
 
     // added or changed for PANSTARRS_DEV_0
@@ -168,4 +173,6 @@
   return (out);
 }
+
+# define RAW_IMAGE_NAME_LEN 32
 
 /* convert loneos-format images to internal images */
@@ -183,6 +190,7 @@
     memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
 
-    strncpy (out[i].name, in[i].name, 31); // in[32], out[128]
-    out[i].name[31] = 0; // force termination
+    // RAW_IMAGE_NAME_LEN < DVO_IMAGE_NAME_LEN
+    strncpy (out[i].name, in[i].name, RAW_IMAGE_NAME_LEN - 1);
+    out[i].name[RAW_IMAGE_NAME_LEN - 1] = 0; // force termination
 
     out[i].tzero    	    = in[i].tzero;
@@ -253,6 +261,7 @@
     memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
 
-    strncpy (out[i].name, in[i].name, 31); // out[32], in[128]
-    out[i].name[31] = 0; // force termination
+    // RAW_IMAGE_NAME_LEN < DVO_IMAGE_NAME_LEN
+    strncpy (out[i].name, in[i].name, RAW_IMAGE_NAME_LEN - 1);
+    out[i].name[RAW_IMAGE_NAME_LEN - 1] = 0; // force termination
 
     out[i].tzero    	    = in[i].tzero;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert_panstarrs_DEV_0.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert_panstarrs_DEV_0.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert_panstarrs_DEV_0.c	(revision 37403)
@@ -2,5 +2,5 @@
 
 /* convert panstarrs-format measures to internal measures */
-Measure *Measure_Panstarrs_DEV_0_ToInternal (Measure_Panstarrs_DEV_0 *in, off_t Nvalues) {
+Measure *Measure_Panstarrs_DEV_0_ToInternal (Average *ave, Measure_Panstarrs_DEV_0 *in, off_t Nvalues) {
 
   off_t i;
@@ -11,6 +11,8 @@
   for (i = 0; i < Nvalues; i++) {
     dvo_measure_init (&out[i]);
-    out[i].dR         = in[i].dR;
-    out[i].dD         = in[i].dD;
+
+    int averef = in[i].averef;
+    out[i].R          = ave[averef].R - in[i].dR / 3600.0;
+    out[i].D          = ave[averef].D - in[i].dD / 3600.0;
     out[i].M          = in[i].M;
     out[i].dM         = in[i].dM;
@@ -52,5 +54,5 @@
 
 /* convert internal measures to panstarrs-format measures */
-Measure_Panstarrs_DEV_0 *MeasureInternalTo_Panstarrs_DEV_0 (Measure *in, off_t Nvalues) {
+Measure_Panstarrs_DEV_0 *MeasureInternalTo_Panstarrs_DEV_0 (Average *ave, Measure *in, off_t Nvalues) {
 
   off_t i;
@@ -60,6 +62,8 @@
 
   for (i = 0; i < Nvalues; i++) {
-    out[i].dR         = in[i].dR;
-    out[i].dD         = in[i].dD;
+    int averef = in[i].averef;
+
+    out[i].dR         = 3600.0*(ave[averef].R - in[i].R);
+    out[i].dD         = 3600.0*(ave[averef].D - in[i].D);
     out[i].M          = in[i].M;
     out[i].dM         = in[i].dM;
@@ -184,5 +188,5 @@
     out[i].M     = in[i].M;      
     out[i].dM    = in[i].dM;      
-    out[i].Xm    = in[i].Xm;     
+    out[i].Mchisq= pow (10.0, 0.01*in[i].Xm);     
     out[i].Ncode = in[i].Ncode;
     out[i].Nused = in[i].Nused;
@@ -202,5 +206,5 @@
     out[i].M     = in[i].M;      
     out[i].dM    = in[i].dM;      
-    out[i].Xm    = in[i].Xm;     
+    out[i].Xm    = 100.0*log10(in[i].Mchisq);     
     out[i].Ncode = in[i].Ncode;
     out[i].Nused = in[i].Nused;
@@ -208,4 +212,6 @@
   return (out);
 }
+
+# define RAW_IMAGE_NAME_LEN 32
 
 /* convert panstarrs-format images to internal images */
@@ -223,6 +229,7 @@
     memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
 
-    strncpy (out[i].name, in[i].name, 31); // out[128], in[32]
-    out[i].name[31] = 0; // force termination
+    // RAW_IMAGE_NAME_LEN < DVO_IMAGE_NAME_LEN
+    strncpy (out[i].name, in[i].name, RAW_IMAGE_NAME_LEN - 1);
+    out[i].name[RAW_IMAGE_NAME_LEN - 1] = 0; // force termination
 
     out[i].tzero    	    = in[i].tzero;
@@ -292,6 +299,7 @@
     memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
 
-    strncpy (out[i].name, in[i].name, 31); // out[32], in[128]
-    out[i].name[31] = 0; // force termination
+    // RAW_IMAGE_NAME_LEN < DVO_IMAGE_NAME_LEN
+    strncpy (out[i].name, in[i].name, RAW_IMAGE_NAME_LEN - 1);
+    out[i].name[RAW_IMAGE_NAME_LEN - 1] = 0; // force termination
 
     out[i].tzero    	    = in[i].tzero;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert_panstarrs_DEV_1.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert_panstarrs_DEV_1.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_convert_panstarrs_DEV_1.c	(revision 37403)
@@ -2,5 +2,5 @@
 
 /* convert panstarrs-format measures to internal measures */
-Measure *Measure_Panstarrs_DEV_1_ToInternal (Measure_Panstarrs_DEV_1 *in, off_t Nvalues) {
+Measure *Measure_Panstarrs_DEV_1_ToInternal (Average *ave, Measure_Panstarrs_DEV_1 *in, off_t Nvalues) {
 
   off_t i;
@@ -11,6 +11,8 @@
   for (i = 0; i < Nvalues; i++) {
     dvo_measure_init (&out[i]);
-    out[i].dR         = in[i].dR;
-    out[i].dD         = in[i].dD;
+
+    int averef = in[i].averef;
+    out[i].R          = ave[averef].R - in[i].dR / 3600.0;
+    out[i].D          = ave[averef].D - in[i].dD / 3600.0;
     out[i].M          = in[i].M;
     out[i].dM         = in[i].dM;
@@ -52,5 +54,5 @@
 
 /* convert internal measures to panstarrs-format measures */
-Measure_Panstarrs_DEV_1 *MeasureInternalTo_Panstarrs_DEV_1 (Measure *in, off_t Nvalues) {
+Measure_Panstarrs_DEV_1 *MeasureInternalTo_Panstarrs_DEV_1 (Average *ave, Measure *in, off_t Nvalues) {
 
   off_t i;
@@ -60,6 +62,8 @@
 
   for (i = 0; i < Nvalues; i++) {
-    out[i].dR         = in[i].dR;
-    out[i].dD         = in[i].dD;
+    int averef = in[i].averef;
+
+    out[i].dR         = 3600.0*(ave[averef].R - in[i].R);
+    out[i].dD         = 3600.0*(ave[averef].D - in[i].D);
     out[i].M          = in[i].M;
     out[i].dM         = in[i].dM;
@@ -184,5 +188,5 @@
     out[i].M     = in[i].M;      
     out[i].dM    = in[i].dM;      
-    out[i].Xm    = in[i].Xm;     
+    out[i].Mchisq= pow (10.0, 0.01*in[i].Xm);     
     out[i].Ncode = in[i].Ncode;
     out[i].Nused = in[i].Nused;
@@ -202,5 +206,5 @@
     out[i].M     = in[i].M;      
     out[i].dM    = in[i].dM;      
-    out[i].Xm    = in[i].Xm;     
+    out[i].Xm    = 100.0*log10(in[i].Mchisq);     
     out[i].Ncode = in[i].Ncode;
     out[i].Nused = in[i].Nused;
@@ -208,4 +212,6 @@
   return (out);
 }
+
+# define RAW_IMAGE_NAME_LEN 64
 
 /* convert panstarrs-format images to internal images */
@@ -223,6 +229,7 @@
     memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
 
-    strncpy (out[i].name, in[i].name, 63); // in[64], out[128]
-    out[i].name[63] = 0; // force termination
+    // RAW_IMAGE_NAME_LEN < DVO_IMAGE_NAME_LEN
+    strncpy (out[i].name, in[i].name, RAW_IMAGE_NAME_LEN - 1);
+    out[i].name[RAW_IMAGE_NAME_LEN - 1] = 0; // force termination
 
     out[i].tzero    	    = in[i].tzero;
@@ -292,6 +299,7 @@
     memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
 
-    strncpy (out[i].name, in[i].name, 63); // in[128], out[64]
-    out[i].name[63] = 0; // force termination
+    // RAW_IMAGE_NAME_LEN < DVO_IMAGE_NAME_LEN
+    strncpy (out[i].name, in[i].name, RAW_IMAGE_NAME_LEN - 1);
+    out[i].name[RAW_IMAGE_NAME_LEN - 1] = 0; // force termination
 
     out[i].tzero    	    = in[i].tzero;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_image.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_image.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_image.c	(revision 37403)
@@ -219,4 +219,5 @@
   if (db[0].format == DVO_FORMAT_PS1_V3)          gfits_modify (&db[0].header, "FORMAT", "%s", 1, "PS1_V3");
   if (db[0].format == DVO_FORMAT_PS1_V4)          gfits_modify (&db[0].header, "FORMAT", "%s", 1, "PS1_V4");
+  if (db[0].format == DVO_FORMAT_PS1_V5)          gfits_modify (&db[0].header, "FORMAT", "%s", 1, "PS1_V5");
   if (db[0].format == DVO_FORMAT_PS1_REF)         gfits_modify (&db[0].header, "FORMAT", "%s", 1, "PS1_REF");
   
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_image_raw.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_image_raw.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_image_raw.c	(revision 37403)
@@ -59,4 +59,5 @@
   if (db[0].format == DVO_FORMAT_PS1_V3)          ImageSize = sizeof(Image_PS1_V3);
   if (db[0].format == DVO_FORMAT_PS1_V4)          ImageSize = sizeof(Image_PS1_V4);
+  if (db[0].format == DVO_FORMAT_PS1_V5)          ImageSize = sizeof(Image_PS1_V5);
   if (db[0].format == DVO_FORMAT_PS1_REF)         ImageSize = sizeof(Image_PS1_REF);
 
@@ -89,4 +90,5 @@
   if (db[0].format == DVO_FORMAT_PS1_V3)          gfits_table_mkheader_Image_PS1_V3 (&db[0].theader);
   if (db[0].format == DVO_FORMAT_PS1_V4)          gfits_table_mkheader_Image_PS1_V4 (&db[0].theader);
+  if (db[0].format == DVO_FORMAT_PS1_V5)          gfits_table_mkheader_Image_PS1_V5 (&db[0].theader);
   if (db[0].format == DVO_FORMAT_PS1_REF)         gfits_table_mkheader_Image_PS1_REF (&db[0].theader);
     
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_photcode_ops.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_photcode_ops.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_photcode_ops.c	(revision 37403)
@@ -18,4 +18,6 @@
 
 static PhotCodeData *photcodes = NULL;
+static PhotCode *genericCodeMag = NULL;
+static PhotCode *genericCodeFlux = NULL;
 
 PhotCodeData *GetPhotcodeTable () {
@@ -26,4 +28,16 @@
     photcodes[0].code = NULL;
   }
+  if (genericCodeMag == NULL) {
+    ALLOCATE (genericCodeMag, PhotCode, 1);
+    genericCodeMag->code = 0;
+    strcpy (genericCodeMag->name, "MAG");
+    genericCodeMag->type = PHOT_MAG;
+  }
+  if (genericCodeFlux == NULL) {
+    ALLOCATE (genericCodeFlux, PhotCode, 1);
+    genericCodeFlux->code = 0;
+    strcpy (genericCodeFlux->name, "MAG");
+    genericCodeFlux->type = PHOT_MAG;
+  }
   return photcodes;
 }
@@ -57,4 +71,14 @@
   if (name == NULL) return (NULL);
   
+  // "MAG" is a special word, not allowed for a photcode name
+  if (!strcasecmp (name, "MAG")) {
+    return genericCodeMag;
+  }
+
+  // "FLUX" is a special word, not allowed for a photcode name
+  if (!strcasecmp (name, "FLUX")) {
+    return genericCodeFlux;
+  }
+
   for (i = 0; i < photcodes[0].Ncode; i++) {
     if (!strcmp (photcodes[0].code[i].name, name)) {
@@ -70,4 +94,13 @@
   
   if (name == NULL) return (0);
+
+  // "MAG" is a special photcode name for internal use
+  if (!strcasecmp (name, "MAG")) {
+    return genericCodeMag->code;
+  }
+  // "FLUX" is a special photcode name for internal use
+  if (!strcasecmp (name, "FLUX")) {
+    return genericCodeFlux->code;
+  }
 
   for (i = 0; i < photcodes[0].Ncode; i++) {
@@ -222,546 +255,362 @@
 
 /******** photometry conversion functions *********/
-float PhotInst (Measure *measure) {
-
-  int Np;
-  float M;
-
-  Np = photcodes[0].hashcode[measure[0].photcode];
+float PhotInst (Measure *measure, dvoMagClassType class) {
+
+  int Np = photcodes[0].hashcode[measure[0].photcode];
   if (Np == -1) return (NAN);
-
-  if (photcodes[0].code[Np].type == PHOT_REF) {
-    M = measure[0].M;
-    return (M);
-  }
-
-  M = measure[0].M - measure[0].dt - ZERO_POINT;
-	  
-  return (M);
-
-}
-
-float PhotCat (Measure *measure) {
-
-  int Np;
-  float Mcat;
-  PhotCode *code;
-
-  Np = photcodes[0].hashcode[measure[0].photcode];
+  PhotCode *code = &photcodes[0].code[Np];
+
+  float Mraw = NAN;
+  switch (class) {
+    case MAG_CLASS_PSF:
+      Mraw = measure[0].M;
+      break;
+    case MAG_CLASS_KRON:
+      Mraw = measure[0].Mkron;
+      break;
+    case MAG_CLASS_APER:
+      Mraw = measure[0].Map;
+      break;
+    default:
+      break;
+  }
+  if (code->type == PHOT_REF) {
+    return (Mraw);
+  }
+  float Minst = Mraw - measure[0].dt - ZERO_POINT;
+
+  return (Minst);
+}
+
+float PhotCat (Measure *measure, dvoMagClassType class) {
+
+  int Np = photcodes[0].hashcode[measure[0].photcode];
   if (Np == -1) return (NAN);
-
-  if (photcodes[0].code[Np].type == PHOT_REF) {
-    Mcat = measure[0].M;
-    return (Mcat);
-  }
-  code = &photcodes[0].code[Np];
-  Mcat = measure[0].M - ZERO_POINT + code[0].K*(measure[0].airmass - 1.000) + SCALE*code[0].C;
+  PhotCode *code = &photcodes[0].code[Np];
+
+  float Mraw = NAN;
+  switch (class) {
+    case MAG_CLASS_PSF:
+      Mraw = measure[0].M;
+      break;
+    case MAG_CLASS_KRON:
+      Mraw = measure[0].Mkron;
+      break;
+    case MAG_CLASS_APER:
+      Mraw = measure[0].Map;
+      break;
+    default:
+      break;
+  }
+  if (code->type == PHOT_REF) {
+    return (Mraw);
+  }
+
+  float Mcat = Mraw - ZERO_POINT + code[0].K*(measure[0].airmass - 1.000) + SCALE*code[0].C;
   
   return (Mcat);
 }
 
-float PhotSys (Measure *measure, Average *average, SecFilt *secfilt) {
-
-  int i, Np;
-  float Mcat, Mcol, Msys, mc, Mc;
-  PhotCode *code;
-
-  Np = photcodes[0].hashcode[measure[0].photcode];
+float PhotSys (Measure *measure, Average *average, SecFilt *secfilt, dvoMagClassType class) {
+
+  int Np = photcodes[0].hashcode[measure[0].photcode];
   if (Np == -1) return (NAN);
-
-  if (photcodes[0].code[Np].type == PHOT_REF) {
-    Msys = measure[0].M;
-    return (Msys);
-  }
-  code = &photcodes[0].code[Np];
-  Mcat = measure[0].M - ZERO_POINT + code[0].K*(measure[0].airmass - 1.000) + SCALE*code[0].C;
+  PhotCode *code = &photcodes[0].code[Np];
+
+  float Mraw = NAN;
+  switch (class) {
+    case MAG_CLASS_PSF:
+      Mraw = measure[0].M;
+      break;
+    case MAG_CLASS_KRON:
+      Mraw = measure[0].Mkron;
+      break;
+    case MAG_CLASS_APER:
+      Mraw = measure[0].Map;
+      break;
+    default:
+      break;
+  }
+  if (code->type == PHOT_REF) {
+    return (Mraw);
+  }
+  float Mcat = Mraw - ZERO_POINT + code[0].K*(measure[0].airmass - 1.000) + SCALE*code[0].C;
 
   /* for DEP, color must be made of PRI/SEC */
-  mc = PhotColorForCode (average, secfilt, NULL, code);
+  float mc = PhotColorForCode (average, secfilt, NULL, code);
   if (isnan(mc)) return (Mcat);
-  mc = mc - SCALE*code[0].dX;
-
-  Mc = mc;
-  Mcol = 0;
+  mc -= SCALE*code[0].dX;
+
+  int i = 0;
+  double Mc = mc;
+  float Mcol = 0;
   for (i = 0; i < code[0].Nc; i++) {
     Mcol += code[0].X[i]*Mc;
     Mc *= mc;
   }
-  Msys = Mcat + Mcol;
+  float Msys = Mcat + Mcol;
   return (Msys);
 }
 
-float PhotRel (Measure *measure, Average *average, SecFilt *secfilt) {
-
-  int i, Np;
-  float Mcat, Mcol, Mrel, mc, Mc;
-  PhotCode *code;
-
-  Np = photcodes[0].hashcode[measure[0].photcode];
+float PhotRel (Measure *measure, Average *average, SecFilt *secfilt, dvoMagClassType class) {
+
+  int Np = photcodes[0].hashcode[measure[0].photcode];
   if (Np == -1) return (NAN);
-
-  if (photcodes[0].code[Np].type == PHOT_REF) {
-    Mcat = measure[0].M;
-    return (Mcat);
-  }
-  code = &photcodes[0].code[Np];
-  Mrel = measure[0].M - ZERO_POINT + code[0].K*(measure[0].airmass - 1.000) + SCALE*code[0].C - measure[0].Mcal;
+  PhotCode *code = &photcodes[0].code[Np];
+
+  float Mraw = NAN;
+  switch (class) {
+    case MAG_CLASS_PSF:
+      Mraw = measure[0].M;
+      break;
+    case MAG_CLASS_KRON:
+      Mraw = measure[0].Mkron;
+      break;
+    case MAG_CLASS_APER:
+      Mraw = measure[0].Map;
+      break;
+    default:
+      break;
+  }
+  if (code->type == PHOT_REF) {
+    return (Mraw);
+  }
+  float Mcat = Mraw - ZERO_POINT + code[0].K*(measure[0].airmass - 1.000) + SCALE*code[0].C - measure[0].Mcal;
 
   /* for DEP, color must be made of PRI/SEC */
-  mc = PhotColorForCode (average, secfilt, NULL, code);
-  if (isnan(mc)) return (Mrel);
-  mc = mc - SCALE*code[0].dX;
-
-  Mc = mc;
-  Mcol = 0;
+  float mc = PhotColorForCode (average, secfilt, NULL, code);
+  if (isnan(mc)) return (Mcat);
+  mc -= SCALE*code[0].dX;
+
+  double Mc = mc;
+  float Mcol = 0;
+  int i = 0;
+  for (i = 0; i < code[0].Nc; i++) {
+    Mcol += code[0].X[i]*Mc;
+    Mc *= mc;
+  }
+  float Mrel = Mcat + Mcol;
+  return (Mrel);
+}
+
+/* return calibrated magnitude from measure for given photcode */
+float PhotCal (Measure *thisone, Average *average, SecFilt *secfilt, Measure *measure, PhotCode *code, dvoMagClassType class) {
+
+  int i; 
+
+  if (code == NULL) return NAN;
+
+  /* code must be the matching PRI/SEC code for this measurement or an equivalent ALT */
+  int Np = photcodes[0].hashcode[thisone[0].photcode];
+  if (Np == -1) return (NAN);
+  PhotCode *myCode = &photcodes[0].code[Np];
+
+  if (code->code != myCode->equiv) return (NAN);
+
+  // if we are REF type, just get the right version and return
+  if (myCode->type == PHOT_REF) {
+    float Mraw = NAN;
+    switch (class) {
+      case MAG_CLASS_PSF:
+	Mraw = thisone[0].M;
+	break;
+      case MAG_CLASS_KRON:
+	Mraw = thisone[0].Mkron;
+	break;
+      case MAG_CLASS_APER:
+	Mraw = thisone[0].Map;
+	break;
+      default:
+	break;
+    }
+    return (Mraw);
+  }
+
+  float Mcal = PhotRel (thisone, average, secfilt, class) + SCALE*code[0].C;
+
+  float mc = PhotColorForCode (average, secfilt, measure, code);
+  if (isnan(mc)) return (Mcal);
+  mc -= SCALE*code[0].dX;
+
+  double Mc = mc;
+  float Mcol = 0;
+  for (i = 0; i < code[0].Nc; i++) {
+    Mcol += code[0].X[i]*Mc;
+    Mc *= mc;
+  }
+  Mcal += Mcol;
+  return (Mcal);
+}
+
+/***/
+float PhotAve (PhotCode *code, Average *average, SecFilt *secfilt, dvoMagClassType class, dvoMagSourceType source) {
+
+  if (code == NULL) return NAN;
+
+  int Ns = photcodes[0].hashNsec[code[0].code];
+  if (Ns == -1) return (NAN);
+
+  float Mave = NAN;
+  switch (source) {
+    case MAG_SRC_CHP:
+      switch (class) {
+	case MAG_CLASS_PSF:
+	  Mave = secfilt[Ns].M;
+	  break;
+	case MAG_CLASS_KRON:
+	  Mave = secfilt[Ns].Mkron;
+	  break;
+	case MAG_CLASS_APER:
+	  Mave = secfilt[Ns].Map;
+	  break;
+	default:
+	  break;
+      }
+      break;
+    case MAG_SRC_WRP:
+      switch (class) {
+	case MAG_CLASS_PSF:
+	  Mave = secfilt[Ns].MpsfWrp;
+	  break;
+	case MAG_CLASS_KRON:
+	  Mave = secfilt[Ns].MkronWrp;
+	  break;
+	case MAG_CLASS_APER:
+	  Mave = secfilt[Ns].MapWrp;
+	  break;
+	default:
+	  break;
+      }
+      break;
+    case MAG_SRC_STK:
+      switch (class) {
+	case MAG_CLASS_PSF:
+	  Mave = secfilt[Ns].MpsfStk;
+	  break;
+	case MAG_CLASS_KRON:
+	  Mave = secfilt[Ns].MkronStk;
+	  break;
+	case MAG_CLASS_APER:
+	  Mave = secfilt[Ns].MapStk;
+	  break;
+	default:
+	  break;
+      }
+      break;
+    default:
+      break;
+  }
+  return (Mave);
+}
+
+/* return calibrated magnitude from average/secfilt for given photcode */
+float PhotRef (PhotCode *code, Average *average, SecFilt *secfilt, Measure *measure, dvoMagClassType class, dvoMagSourceType source) {
+
+  int i;
+
+  float Mave = PhotAve (code, average, secfilt, class, source);
+  if (isnan(Mave)) return NAN;
+
+  // correct for relative zero-point
+  float Mref = Mave + SCALE*code[0].C;
+
+  float mc = PhotColorForCode (average, secfilt, measure, code);
+  if (isnan(mc)) return (Mref);
+  mc -= SCALE*code[0].dX;
+
+  // correct for color terms
+  double Mc = mc;
+  float Mcol = 0;
   for (i = 0; i < code[0].Nc; i++) {
     Mcol += code[0].X[i]*Mc;
     Mc *= mc;    /* the 0.001 is needed for higher order terms to keep the units mag = mag^n */
   }
-  Mrel += Mcol;
-  return (Mrel);
-}
-
-/* return calibrated magnitude from measure for given photcode */
-float PhotCal (Measure *thisone, Average *average, SecFilt *secfilt, Measure *measure, PhotCode *code) {
-
-  int i, Np; 
-  float Mcal, Mrel, Mcol, mc, Mc;
-
-  if (code == NULL) return NAN;
-
-  /* code must be the matching PRI/SEC code for this measurement or an equivalent ALT */
-  Np = photcodes[0].hashcode[thisone[0].photcode];
-  if (Np == -1) return (NAN);
-
-  if (photcodes[0].code[Np].type == PHOT_REF) {
-    Mrel = thisone[0].M;
-    return (Mrel);
-  }
-  if (code[0].code != photcodes[0].code[Np].equiv) return (NAN);
-
-  Mcal = PhotRel (thisone, average, secfilt) + SCALE*code[0].C;
-
-  mc = PhotColorForCode (average, secfilt, measure, code);
-  if (isnan(mc)) return (Mcal);
-  mc = mc - SCALE*code[0].dX;
-
-  Mc = mc;
-  Mcol = 0;
-  for (i = 0; i < code[0].Nc; i++) {
-    Mcol += code[0].X[i]*Mc;
-    Mc *= mc;
-  }
-  Mcal += Mcol;
-  return (Mcal);
-}
-
-/***/
-float PhotAve (PhotCode *code, Average *average, SecFilt *secfilt) {
-
-  int Ns;
-  float Mave;
-
-  if (code == NULL) return NAN;
-
-  Ns = photcodes[0].hashNsec[code[0].code];
-  Mave = (Ns == -1) ? NAN : secfilt[Ns].M;
-  return (Mave);
-}
-
-/* return calibrated magnitude from average/secfilt for given photcode */
-float PhotRef (PhotCode *code, Average *average, SecFilt *secfilt, Measure *measure) {
-
-  int i, Ns;
-  float Mave, Mref, Mcol, mc;
-  double Mc;
-
-  if (code == NULL) return NAN;
-
-  Ns = photcodes[0].hashNsec[code[0].code];
-  Mave = (Ns == -1) ? NAN : secfilt[Ns].M;
-  Mref = Mave + SCALE*code[0].C;
-
-  mc = PhotColorForCode (average, secfilt, measure, code);
-  if (isnan(mc)) return (Mref);
-  mc = mc - SCALE*code[0].dX;
-
-  Mc = mc;
-  Mcol = 0;
-  for (i = 0; i < code[0].Nc; i++) {
-    Mcol += code[0].X[i]*Mc;
-    Mc *= mc;    /* the 0.001 is needed for higher order terms to keep the units mag = mag^n */
-  }
   Mref += Mcol;
   return (Mref);
 }
 
-float PhotAveErr (PhotCode *code, Average *average, SecFilt *secfilt) {
-
-  int Ns;
-  float dM;
-
-  if (code == NULL) return NAN;
-
-  Ns = photcodes[0].hashNsec[code[0].code];
-  dM  = (Ns == -1) ? NAN : secfilt[Ns].dM;
-  return (dM);
-}
-
-/************************************** APERTURE-related Magnitudes ***********************************************/
-
-float PhotAperInst (Measure *measure) {
-
-  int Np;
-  float Minst;
-
-  Np = photcodes[0].hashcode[measure[0].photcode];
-  if (Np == -1) return (NAN);
-
-  if (photcodes[0].code[Np].type == PHOT_REF) {
-    Minst = measure[0].Map;
-    return (Minst);
-  }
-  Minst = measure[0].Map - measure[0].dt - ZERO_POINT;
-  
-  return (Minst);
-}
-
-float PhotAperCat (Measure *measure) {
-
-  int Np;
-  float Mcat;
-  PhotCode *code;
-
-  Np = photcodes[0].hashcode[measure[0].photcode];
-  if (Np == -1) return (NAN);
-
-  if (photcodes[0].code[Np].type == PHOT_REF) {
-    Mcat = measure[0].Map;
-    return (Mcat);
-  }
-  code = &photcodes[0].code[Np];
-  Mcat = measure[0].Map - ZERO_POINT + code[0].K*(measure[0].airmass - 1.000) + SCALE*code[0].C;
-  
-  return (Mcat);
-}
-
-float PhotAperSys (Measure *measure, Average *average, SecFilt *secfilt) {
-
-  int i, Np;
-  float Mcat, Mcol, Msys, mc, Mc;
-  PhotCode *code;
-
-  Np = photcodes[0].hashcode[measure[0].photcode];
-  if (Np == -1) return (NAN);
-
-  if (photcodes[0].code[Np].type == PHOT_REF) {
-    Mcat = measure[0].Map;
-    return (Mcat);
-  }
-  code = &photcodes[0].code[Np];
-  Mcat = measure[0].Map - ZERO_POINT + code[0].K*(measure[0].airmass - 1.000) + SCALE*code[0].C;
-  
-  /* for DEP, color must be made of PRI/SEC */
-  mc = PhotColorForCode (average, secfilt, NULL, code);
-  if (isnan(mc)) return (Mcat);
-  mc = mc - SCALE*code[0].dX;
-
-  Mc = mc;
-  Mcol = 0;
-  for (i = 0; i < code[0].Nc; i++) {
-    Mcol += code[0].X[i]*Mc;
-    Mc *= mc;
-  }
-  Msys = Mcat + Mcol;
-  return (Msys);
-}
-
-float PhotAperRel (Measure *measure, Average *average, SecFilt *secfilt) {
-
-  int i, Np;
-  float Mcat, Mcol, Mrel, mc, Mc;
-  PhotCode *code;
-
-  Np = photcodes[0].hashcode[measure[0].photcode];
-  if (Np == -1) return (NAN);
-
-  if (photcodes[0].code[Np].type == PHOT_REF) {
-    Mcat = measure[0].Map;
-    return (Mcat);
-  }
-  code = &photcodes[0].code[Np];
-  Mrel = measure[0].Map - ZERO_POINT + code[0].K*(measure[0].airmass - 1.000) + SCALE*code[0].C - measure[0].Mcal;
-
-  /* for DEP, color must be made of PRI/SEC */
-  mc = PhotColorForCode (average, secfilt, NULL, code);
-  if (isnan(mc)) return (Mrel);
-  mc = mc - SCALE*code[0].dX;
-
-  Mc = mc;
-  Mcol = 0;
-  for (i = 0; i < code[0].Nc; i++) {
-    Mcol += code[0].X[i]*Mc;
-    Mc *= mc;    /* the 0.001 is needed for higher order terms to keep the units mag = mag^n */
-  }
-  Mrel += Mcol;
-  return (Mrel);
-}
-
-/* return calibrated magnitude from measure for given photcode */
-float PhotAperCal (Measure *thisone, Average *average, SecFilt *secfilt, Measure *measure, PhotCode *code) {
-
-  int i, Np; 
-  float Mcal, Mrel, Mcol, mc, Mc;
-
-  if (code == NULL) return NAN;
-
-  /* code must be the matching PRI/SEC code for this measurement or an equivalent ALT */
-  Np = photcodes[0].hashcode[thisone[0].photcode];
-  if (Np == -1) return (NAN);
-
-  if (photcodes[0].code[Np].type == PHOT_REF) {
-    Mrel = thisone[0].Map;
-    return (Mrel);
-  }
-  if (code[0].code != photcodes[0].code[Np].equiv) return (NAN);
-
-  Mcal = PhotAperRel (thisone, average, secfilt) + SCALE*code[0].C;
-
-  mc = PhotColorForCode (average, secfilt, measure, code);
-  if (isnan(mc)) return (Mcal);
-  mc = mc - SCALE*code[0].dX;
-
-  Mc = mc;
-  Mcol = 0;
-  for (i = 0; i < code[0].Nc; i++) {
-    Mcol += code[0].X[i]*Mc;
-    Mc *= mc;
-  }
-  Mcal += Mcol;
-  return (Mcal);
-}
-
-float PhotAperAve (PhotCode *code, Average *average, SecFilt *secfilt) {
-
-  int Ns;
-  float Maper;
-
-  if (code == NULL) return NAN;
-
-  Ns = photcodes[0].hashNsec[code[0].code];
-  Maper = (Ns == -1) ? NAN : secfilt[Ns].Map;
-  return (Maper);
-}
-
-/* return calibrated magnitude from average/secfilt for given photcode */
-float PhotAperRef (PhotCode *code, Average *average, SecFilt *secfilt, Measure *measure) {
-
-  int i, Ns;
-  float Mave, Mref, Mcol, mc;
-  double Mc;
-
-  if (code == NULL) return NAN;
-
-  Ns = photcodes[0].hashNsec[code[0].code];
-  Mave = (Ns == -1) ? NAN : secfilt[Ns].Map;
-  Mref = Mave + SCALE*code[0].C;
-
-  mc = PhotColorForCode (average, secfilt, measure, code);
-  if (isnan(mc)) return (Mref);
-  mc = mc - SCALE*code[0].dX;
-
-  Mc = mc;
-  Mcol = 0;
-  for (i = 0; i < code[0].Nc; i++) {
-    Mcol += code[0].X[i]*Mc;
-    Mc *= mc;    /* the 0.001 is needed for higher order terms to keep the units mag = mag^n */
-  }
-  Mref += Mcol;
-  return (Mref);
-}
-
-/************************************** KRON-related Magnitudes ***********************************************/
-
-float PhotKronInst (Measure *measure) {
-
-  int Np;
-  float Minst;
-
-  Np = photcodes[0].hashcode[measure[0].photcode];
-  if (Np == -1) return (NAN);
-
-  if (photcodes[0].code[Np].type == PHOT_REF) {
-    Minst = measure[0].Mkron;
-    return (Minst);
-  }
-  Minst = measure[0].Mkron - measure[0].dt - ZERO_POINT;
-  
-  return (Minst);
-}
-
-float PhotKronCat (Measure *measure) {
-
-  int Np;
-  float Mcat;
-  PhotCode *code;
-
-  Np = photcodes[0].hashcode[measure[0].photcode];
-  if (Np == -1) return (NAN);
-
-  if (photcodes[0].code[Np].type == PHOT_REF) {
-    Mcat = measure[0].Mkron;
-    return (Mcat);
-  }
-  code = &photcodes[0].code[Np];
-  Mcat = measure[0].Mkron - ZERO_POINT + code[0].K*(measure[0].airmass - 1.000) + SCALE*code[0].C;
-  
-  return (Mcat);
-}
-
-float PhotKronSys (Measure *measure, Average *average, SecFilt *secfilt) {
-
-  int i, Np;
-  float Mcat, Mcol, Msys, mc, Mc;
-  PhotCode *code;
-
-  Np = photcodes[0].hashcode[measure[0].photcode];
-  if (Np == -1) return (NAN);
-
-  if (photcodes[0].code[Np].type == PHOT_REF) {
-    Msys = measure[0].Mkron;
-    return (Msys);
-  }
-  code = &photcodes[0].code[Np];
-  Mcat = measure[0].Mkron - ZERO_POINT + code[0].K*(measure[0].airmass - 1.000) + SCALE*code[0].C;
-
-  /* for DEP, color must be made of PRI/SEC */
-  mc = PhotColorForCode (average, secfilt, NULL, code);
-  if (isnan(mc)) return (Mcat);
-  mc = mc - SCALE*code[0].dX;
-
-  Mc = mc;
-  Mcol = 0;
-  for (i = 0; i < code[0].Nc; i++) {
-    Mcol += code[0].X[i]*Mc;
-    Mc *= mc;
-  }
-  Msys = Mcat + Mcol;
-  return (Msys);
-}
-
-float PhotKronRel (Measure *measure, Average *average, SecFilt *secfilt) {
-
-  int i, Np;
-  float Mcat, Mcol, Mrel, mc, Mc;
-  PhotCode *code;
-
-  Np = photcodes[0].hashcode[measure[0].photcode];
-  if (Np == -1) return (NAN);
-
-  if (photcodes[0].code[Np].type == PHOT_REF) {
-    Mcat = measure[0].Mkron;
-    return (Mcat);
-  }
-  code = &photcodes[0].code[Np];
-  Mrel = measure[0].Mkron - ZERO_POINT + code[0].K*(measure[0].airmass - 1.000) + SCALE*code[0].C - measure[0].Mcal;
-
-  /* for DEP, color must be made of PRI/SEC */
-  mc = PhotColorForCode (average, secfilt, NULL, code);
-  if (isnan(mc)) return (Mrel);
-  mc = mc - SCALE*code[0].dX;
-
-  Mc = mc;
-  Mcol = 0;
-  for (i = 0; i < code[0].Nc; i++) {
-    Mcol += code[0].X[i]*Mc;
-    Mc *= mc;    /* the 0.001 is needed for higher order terms to keep the units mag = mag^n */
-  }
-  Mrel += Mcol;
-  return (Mrel);
-}
-
-/* return calibrated magnitude from measure for given photcode */
-float PhotKronCal (Measure *thisone, Average *average, SecFilt *secfilt, Measure *measure, PhotCode *code) {
-
-  int i, Np; 
-  float Mcal, Mrel, Mcol, mc, Mc;
-
-  if (code == NULL) return NAN;
-
-  /* code must be the matching PRI/SEC code for this measurement or an equivalent ALT */
-  Np = photcodes[0].hashcode[thisone[0].photcode];
-  if (Np == -1) return (NAN);
-
-  if (photcodes[0].code[Np].type == PHOT_REF) {
-    Mrel = thisone[0].Mkron;
-    return (Mrel);
-  }
-  if (code[0].code != photcodes[0].code[Np].equiv) return (NAN);
-
-  Mcal = PhotKronRel (thisone, average, secfilt) + SCALE*code[0].C;
-
-  mc = PhotColorForCode (average, secfilt, measure, code);
-  if (isnan(mc)) return (Mcal);
-  mc = mc - SCALE*code[0].dX;
-
-  Mc = mc;
-  Mcol = 0;
-  for (i = 0; i < code[0].Nc; i++) {
-    Mcol += code[0].X[i]*Mc;
-    Mc *= mc;
-  }
-  Mcal += Mcol;
-  return (Mcal);
-}
-
-float PhotKronAve (PhotCode *code, Average *average, SecFilt *secfilt) {
-
-  int Ns;
-  float Mkron;
-
-  if (code == NULL) return NAN;
-
-  Ns = photcodes[0].hashNsec[code[0].code];
-  Mkron = (Ns == -1) ? NAN : secfilt[Ns].Mkron;
-  return (Mkron);
-}
-
-/* return calibrated magnitude from average/secfilt for given photcode */
-float PhotKronRef (PhotCode *code, Average *average, SecFilt *secfilt, Measure *measure) {
-
-  int i, Ns;
-  float Mave, Mref, Mcol, mc;
-  double Mc;
-
-  if (code == NULL) return NAN;
-
-  Ns = photcodes[0].hashNsec[code[0].code];
-  Mave = (Ns == -1) ? NAN : secfilt[Ns].Mkron;
-  Mref = Mave + SCALE*code[0].C;
-
-  mc = PhotColorForCode (average, secfilt, measure, code);
-  if (isnan(mc)) return (Mref);
-  mc = mc - SCALE*code[0].dX;
-
-  Mc = mc;
-  Mcol = 0;
-  for (i = 0; i < code[0].Nc; i++) {
-    Mcol += code[0].X[i]*Mc;
-    Mc *= mc;    /* the 0.001 is needed for higher order terms to keep the units mag = mag^n */
-  }
-  Mref += Mcol;
-  return (Mref);
-}
-
-float PhotKronAveErr (PhotCode *code, Average *average, SecFilt *secfilt) {
-
-  int Ns;
-  float dMkron;
-
-  if (code == NULL) return NAN;
-
-  Ns = photcodes[0].hashNsec[code[0].code];
-  dMkron = (Ns == -1) ? NAN : secfilt[Ns].dMkron;
-  return (dMkron);
+float PhotErr (Measure *measure, dvoMagClassType class) {
+
+  float dMraw = NAN;
+  switch (class) {
+    case MAG_CLASS_PSF:
+      dMraw = measure[0].dM;
+      break;
+    case MAG_CLASS_KRON:
+      dMraw = measure[0].dMkron;
+      break;
+    case MAG_CLASS_APER:
+      dMraw = measure[0].dMap;
+      break;
+    default:
+      break;
+  }
+  return (dMraw);
+}
+
+float PhotCalErr (Measure *measure, dvoMagClassType class) {
+
+  float dMcal = measure[0].dMcal;
+  return (dMcal);
+}
+
+float PhotAveErr (PhotCode *code, Average *average, SecFilt *secfilt, dvoMagClassType class, dvoMagSourceType source) {
+
+  if (code == NULL) return NAN;
+
+  int Ns = photcodes[0].hashNsec[code[0].code];
+  if (Ns == -1) return (NAN);
+
+  float dMave = NAN;
+  switch (source) {
+    case MAG_SRC_CHP:
+      switch (class) {
+	case MAG_CLASS_PSF:
+	  dMave = secfilt[Ns].dM;
+	  break;
+	case MAG_CLASS_KRON:
+	  dMave = secfilt[Ns].dMkron;
+	  break;
+	case MAG_CLASS_APER:
+	  dMave = secfilt[Ns].dMap;
+	  break;
+	default:
+	  break;
+      }
+      break;
+    case MAG_SRC_WRP:
+      switch (class) {
+	case MAG_CLASS_PSF:
+	  dMave = secfilt[Ns].dFpsfWrp / secfilt[Ns].FpsfWrp;
+	  break;
+	case MAG_CLASS_KRON:
+	  dMave = secfilt[Ns].dFkronWrp / secfilt[Ns].FkronWrp;
+	  break;
+	case MAG_CLASS_APER:
+	  dMave = secfilt[Ns].dFapWrp / secfilt[Ns].FapWrp;
+	  break;
+	default:
+	  break;
+      }
+      break;
+    case MAG_SRC_STK:
+      switch (class) {
+	case MAG_CLASS_PSF:
+	  dMave = secfilt[Ns].dFpsfStk / secfilt[Ns].FpsfStk;
+	  break;
+	case MAG_CLASS_KRON:
+	  dMave = secfilt[Ns].dFkronStk / secfilt[Ns].FkronStk;
+	  break;
+	case MAG_CLASS_APER:
+	  dMave = secfilt[Ns].dFapStk / secfilt[Ns].FapStk;
+	  break;
+	default:
+	  break;
+      }
+      break;
+    default:
+      break;
+  }
+  return (dMave);
 }
 
@@ -788,4 +637,5 @@
 
 /* color term may not use DEP magnitude */
+// currently only returns the PSF color
 float PhotColorForCode (Average *average, SecFilt *secfilt, Measure *measure, PhotCode *code) {
 
@@ -837,14 +687,94 @@
 }
 
-float PhotMstdev (PhotCode *code, Average *average, SecFilt *secfilt) {
-
-  int Ns;
-  float Mstdev;
-
-  if (code == NULL) return NAN;
-
-  Ns = photcodes[0].hashNsec[code[0].code];
-  Mstdev  = (Ns == -1) ? NAN : 0.001*secfilt[Ns].Mstdev;
+float PhotMstdev (PhotCode *code, Average *average, SecFilt *secfilt, dvoMagClassType class, dvoMagSourceType source) {
+
+  if (code == NULL) return NAN;
+
+  int Ns = photcodes[0].hashNsec[code[0].code];
+  if (Ns == -1) return (NAN);
+
+  float Mstdev = NAN;
+  switch (source) {
+    case MAG_SRC_CHP:
+      switch (class) {
+	case MAG_CLASS_PSF:
+	  Mstdev = secfilt[Ns].Mstdev;
+	  break;
+	case MAG_CLASS_KRON:
+	  Mstdev = secfilt[Ns].sMkron;
+	  break;
+	case MAG_CLASS_APER:
+	  Mstdev = secfilt[Ns].sMap;
+	  break;
+	default:
+	  break;
+      }
+      break;
+    case MAG_SRC_WRP:
+      switch (class) {
+	case MAG_CLASS_PSF:
+	  Mstdev = secfilt[Ns].sFpsfWrp;
+	  break;
+	case MAG_CLASS_KRON:
+	  Mstdev = secfilt[Ns].sFkronWrp;
+	  break;
+	case MAG_CLASS_APER:
+	  Mstdev = secfilt[Ns].sFapWrp;
+	  break;
+	default:
+	  break;
+      }
+      break;
+    case MAG_SRC_STK:
+    default:
+      break;
+  }
   return (Mstdev);
+}
+
+int PhotNphot (PhotCode *code, Average *average, SecFilt *secfilt, dvoMagClassType class, dvoMagSourceType source) {
+
+  if (code == NULL) return 0;
+
+  int Ns = photcodes[0].hashNsec[code[0].code];
+  if (Ns == -1) return 0;
+
+  int Nphot = 0;
+  switch (source) {
+    case MAG_SRC_CHP:
+      switch (class) {
+	case MAG_CLASS_PSF:
+	  Nphot = secfilt[Ns].Nused;
+	  break;
+	case MAG_CLASS_KRON:
+	  Nphot = secfilt[Ns].NusedKron;
+	  break;
+	case MAG_CLASS_APER:
+	  Nphot = secfilt[Ns].NusedAp;
+	  break;
+	default:
+	  break;
+      }
+      break;
+    case MAG_SRC_WRP:
+      switch (class) {
+	case MAG_CLASS_PSF:
+	  Nphot = secfilt[Ns].NusedWrp;
+	  break;
+	case MAG_CLASS_KRON:
+	  Nphot = secfilt[Ns].NusedKronWrp;
+	  break;
+	case MAG_CLASS_APER:
+	  Nphot = secfilt[Ns].NusedApWrp;
+	  break;
+	default:
+	  break;
+      }
+      break;
+    case MAG_SRC_STK:
+    default:
+      break;
+  }
+  return (Nphot);
 }
 
@@ -857,5 +787,5 @@
 
   Ns = photcodes[0].hashNsec[code[0].code];
-  Fpsf = (Ns == -1) ? NAN : secfilt[Ns].FluxPSF;
+  Fpsf = (Ns == -1) ? NAN : secfilt[Ns].FpsfStk;
   return (Fpsf);
 }
@@ -869,5 +799,5 @@
 
   Ns = photcodes[0].hashNsec[code[0].code];
-  dFpsf = (Ns == -1) ? NAN : secfilt[Ns].dFluxPSF;
+  dFpsf = (Ns == -1) ? NAN : secfilt[Ns].dFpsfStk;
   return (dFpsf);
 }
@@ -881,5 +811,5 @@
 
   Ns = photcodes[0].hashNsec[code[0].code];
-  Fkron = (Ns == -1) ? NAN : secfilt[Ns].FluxKron;
+  Fkron = (Ns == -1) ? NAN : secfilt[Ns].FkronStk;
   return (Fkron);
 }
@@ -893,30 +823,30 @@
 
   Ns = photcodes[0].hashNsec[code[0].code];
-  dFkron = (Ns == -1) ? NAN : secfilt[Ns].dFluxKron;
+  dFkron = (Ns == -1) ? NAN : secfilt[Ns].dFkronStk;
   return (dFkron);
 }
 
-float PhotM20 (PhotCode *code, Average *average, SecFilt *secfilt) {
+float PhotMmin (PhotCode *code, Average *average, SecFilt *secfilt) {
 
   int Ns;
-  float M20;
+  float Mmin;
 
   if (code == NULL) return NAN;
 
   Ns = photcodes[0].hashNsec[code[0].code];
-  M20  = (Ns == -1) ? NAN : 0.001*secfilt[Ns].M_20;
-  return (M20);
-}
-
-float PhotM80 (PhotCode *code, Average *average, SecFilt *secfilt) {
+  Mmin  = (Ns == -1) ? NAN : secfilt[Ns].Mmin;
+  return (Mmin);
+}
+
+float PhotMmax (PhotCode *code, Average *average, SecFilt *secfilt) {
 
   int Ns;
-  float M80;
+  float Mmax;
 
   if (code == NULL) return NAN;
 
   Ns = photcodes[0].hashNsec[code[0].code];
-  M80  = (Ns == -1) ? NAN : 0.001*secfilt[Ns].M_80;
-  return (M80);
+  Mmax  = (Ns == -1) ? NAN : secfilt[Ns].Mmax;
+  return (Mmax);
 }
 
@@ -933,28 +863,26 @@
 }
 
-unsigned int PhotStackID (PhotCode *code, Average *average, SecFilt *secfilt) {
+// XX unsigned int PhotStackID (PhotCode *code, Average *average, SecFilt *secfilt) {
+// XX 
+// XX   int Ns;
+// XX   unsigned int ID;
+// XX 
+// XX   if (code == NULL) return 0;
+// XX 
+// XX   Ns = photcodes[0].hashNsec[code[0].code];
+// XX   ID = (Ns == -1) ? 0 : secfilt[Ns].stackDetectID;
+// XX   return (ID);
+// XX }
+
+// Xm is now (2014.07.03) stored as the chisq except in dvo formats which use as short
+float PhotXm (PhotCode *code, Average *average, SecFilt *secfilt) {
 
   int Ns;
-  unsigned int ID;
-
-  if (code == NULL) return 0;
+  float Xm;
+
+  if (code == NULL) return NAN;
 
   Ns = photcodes[0].hashNsec[code[0].code];
-  ID = (Ns == -1) ? 0 : secfilt[Ns].stackDetectID;
-  return (ID);
-}
-
-// XXX return NAN or NAN_S_SHORT? (secfilt->Xm is short)
-float PhotXm (PhotCode *code, Average *average, SecFilt *secfilt) {
-
-  int Ns;
-  short Mi;
-  float Xm;
-
-  if (code == NULL) return NAN;
-
-  Ns = photcodes[0].hashNsec[code[0].code];
-  Mi = (Ns == -1) ? NAN : secfilt[Ns].Xm;
-  Xm = (isnan(Mi)) ? -1.0 : pow (10.0, 0.01*Mi);
+  Xm = (Ns == -1) ? NAN : secfilt[Ns].Mchisq;
   return (Xm);
 }
@@ -1006,158 +934,709 @@
 }
 
-/******** alternate photometry conversion functions using MeasureTiny and AverageTiny *********/
-float PhotInstTiny (MeasureTiny *measure) {
-
-  int Np;
-  float M;
-
-  Np = photcodes[0].hashcode[measure[0].photcode];
+float MagToFlux (float Mag) {
+  float Flux = pow(10.0, -0.4*(Mag));
+  return (Flux);
+}
+
+/** flux conversion *******************************************************************/
+float PhotFluxInst (Measure *measure, dvoMagClassType class) {
+
+  float Moff = - measure[0].dt - ZERO_POINT;
+  float Finst = NAN;
+  switch (class) {
+    case MAG_CLASS_PSF:
+      Finst = isnan (measure[0].FluxPSF)  ? MagToFlux(measure[0].M + Moff)     : measure[0].FluxPSF;
+      break;
+    case MAG_CLASS_KRON:
+      Finst = isnan (measure[0].FluxKron) ? MagToFlux(measure[0].Mkron + Moff) : measure[0].FluxKron;
+      break;
+    case MAG_CLASS_APER:
+      Finst = isnan (measure[0].FluxAp)   ? MagToFlux(measure[0].Map + Moff)   : measure[0].FluxAp;
+      break;
+    default:
+      break;
+  }
+  return (Finst);
+}
+
+// returns Jy fluxes assuming mag in AB? (needs an extra AP factor, right?)
+float PhotFluxCat (Measure *measure, dvoMagClassType class) {
+
+  int Np = photcodes[0].hashcode[measure[0].photcode];
   if (Np == -1) return (NAN);
-
-  if (photcodes[0].code[Np].type == PHOT_REF) {
-    M = measure[0].M;
-    return (M);
-  }
-
-  M = measure[0].M - measure[0].dt - ZERO_POINT;
-	  
-  return (M);
-
-}
-
-float PhotCatTiny (MeasureTiny *measure) {
-
-  int Np;
-  float Mcat;
-  PhotCode *code;
-
-  Np = photcodes[0].hashcode[measure[0].photcode];
+  PhotCode *code = &photcodes[0].code[Np];
+
+  // mag_AB = -2.5 log (flux_cgs) - 48.6 (by definition) [~Vega flux in V-band]
+  // flux_Jy = flux_cgs * 10^23
+  // -2.5 log (flux_cgs) = -2.5 log (flux_Jy * 10^-23) = -2.5 log (flux_Jy) + 2.5*23
+
+  // from these we get:
+  // mag_AB = -2.5 log (flux_Jy) + 8.9
+  // log (flux_Jy) = -0.4*mag_AB + 3.56
+
+  // mag_AB = mag_inst + ZP
+
+  // log(flux_Jy) = -0.4*mag_inst -0.4*ZP + 3.56
+  // mag_inst = -2.5 log (flux_Jy) - ZP + 8.9
+
+  // log (flux_Jy) = -0.4*(mag_inst + ZP - 8.9)
+
+  // -2.5 log (flux_inst) = -2.5 log (flux_Jy) - ZP + 8.9
+  // log (flux_inst) = log (flux_Jy) + 0.4 ZP - 3.56
+  // flux_inst = flux_Jy * 10^(0.4*ZP - 3.56)
+  // flux_Jy = flux_inst * 10^(3.56 - 0.4*ZP) = flux_inst * zpFactor
+  // flux_Jy = flux_inst * 3630.8 * 10^(-0.4*ZP)
+
+  // measure.M has the static ZERO_POINT (25.0) applied, but not measure.Flux
+  float Mcal = code[0].K*(measure[0].airmass - 1.000) + SCALE*code[0].C;
+  float Moff = Mcal - ZERO_POINT + 8.9;
+  float Foff = 3630.8 * MagToFlux(Mcal);
+  float Fcat = NAN;
+  switch (class) {
+    case MAG_CLASS_PSF:
+      Fcat = isnan (measure[0].FluxPSF)  ? MagToFlux(measure[0].M + Moff)     : measure[0].FluxPSF * Foff;
+      break;
+    case MAG_CLASS_KRON:
+      Fcat = isnan (measure[0].FluxKron) ? MagToFlux(measure[0].Mkron + Moff) : measure[0].FluxKron * Foff;
+      break;
+    case MAG_CLASS_APER:
+      Fcat = isnan (measure[0].FluxAp)   ? MagToFlux(measure[0].Map + Moff)   : measure[0].FluxAp * Foff;
+      break;
+    default:
+      break;
+  }
+  return (Fcat);
+}
+
+// corrected for color trends
+float PhotFluxSys (Measure *measure, Average *average, SecFilt *secfilt, dvoMagClassType class) {
+
+  int Np = photcodes[0].hashcode[measure[0].photcode];
   if (Np == -1) return (NAN);
-
-  if (photcodes[0].code[Np].type == PHOT_REF) {
-    Mcat = measure[0].M;
-    return (Mcat);
-  }
-  code = &photcodes[0].code[Np];
-  Mcat = measure[0].M - ZERO_POINT + code[0].K*(measure[0].airmass - 1.000) + SCALE*code[0].C;
-  
-  return (Mcat);
-}
-
-# if (0)
-float PhotAperTiny (MeasureTiny *measure) {
-
-  int Np;
-  float Mcat;
-  PhotCode *code;
-
-  Np = photcodes[0].hashcode[measure[0].photcode];
-  if (Np == -1) return (NAN);
-
-  if (photcodes[0].code[Np].type == PHOT_REF) {
-    Mcat = measure[0].Map;
-    return (Mcat);
-  }
-  code = &photcodes[0].code[Np];
-  Mcat = measure[0].Map - ZERO_POINT + code[0].K*(measure[0].airmass - 1.000) + SCALE*code[0].C;
-  
-  return (Mcat);
-}
-# endif
-
-float PhotSysTiny (MeasureTiny *measure, AverageTiny *average, SecFilt *secfilt) {
-
-  int i, Np;
-  float Mcat, Mcol, Msys, mc, Mc;
-  PhotCode *code;
-
-  Np = photcodes[0].hashcode[measure[0].photcode];
-  if (Np == -1) return (NAN);
-
-  if (photcodes[0].code[Np].type == PHOT_REF) {
-    Msys = measure[0].M;
-    return (Msys);
-  }
-  code = &photcodes[0].code[Np];
-  Mcat = measure[0].M - ZERO_POINT + code[0].K*(measure[0].airmass - 1.000) + SCALE*code[0].C;
-
-  /* for DEP, color must be made of PRI/SEC */
-  mc = PhotColorForCodeTiny (average, secfilt, NULL, code);
-  if (isnan(mc)) return (Mcat);
-  mc = mc - SCALE*code[0].dX;
-
-  Mc = mc;
-  Mcol = 0;
+  PhotCode *code = &photcodes[0].code[Np];
+
+  // measure.M has the static ZERO_POINT (25.0) applied, but not measure.Flux
+  float Mcal = code[0].K*(measure[0].airmass - 1.000) + SCALE*code[0].C;
+  float Moff = Mcal - ZERO_POINT + 8.9;
+  float Foff = 3630.8 * MagToFlux(Mcal);
+  float Fcat = NAN;
+  switch (class) {
+    case MAG_CLASS_PSF:
+      Fcat = isnan (measure[0].FluxPSF)  ? MagToFlux(measure[0].M + Moff)     : measure[0].FluxPSF * Foff;
+      break;
+    case MAG_CLASS_KRON:
+      Fcat = isnan (measure[0].FluxKron) ? MagToFlux(measure[0].Mkron + Moff) : measure[0].FluxKron * Foff;
+      break;
+    case MAG_CLASS_APER:
+      Fcat = isnan (measure[0].FluxAp)   ? MagToFlux(measure[0].Map + Moff)   : measure[0].FluxAp * Foff;
+      break;
+    default:
+      break;
+  }
+  if (isnan(Fcat)) return (NAN);
+
+  // find the relevant color 
+  float mc = PhotColorForCode (average, secfilt, NULL, code);
+  if (isnan(mc)) return (Fcat);
+  mc -= SCALE*code[0].dX;
+
+  // find the color correction in mags
+  int i = 0;
+  double Mc = mc;
+  float Mcol = 0;
   for (i = 0; i < code[0].Nc; i++) {
     Mcol += code[0].X[i]*Mc;
     Mc *= mc;
   }
-  Msys = Mcat + Mcol;
-  return (Msys);
-}
-
-float PhotRelTiny (MeasureTiny *measure, AverageTiny *average, SecFilt *secfilt) {
-
-  int i, Np;
-  float Mcat, Mcol, Mrel, mc, Mc;
-  PhotCode *code;
-
-  Np = photcodes[0].hashcode[measure[0].photcode];
+  float Fcol = MagToFlux (Mcol);
+
+  float Fsys = Fcat * Fcol;
+  return (Fsys);
+}
+
+float PhotFluxRel (Measure *measure, Average *average, SecFilt *secfilt, dvoMagClassType class) {
+
+  int Np = photcodes[0].hashcode[measure[0].photcode];
   if (Np == -1) return (NAN);
-
-  if (photcodes[0].code[Np].type == PHOT_REF) {
-    Mcat = measure[0].M;
-    return (Mcat);
-  }
-  code = &photcodes[0].code[Np];
-  Mrel = measure[0].M - ZERO_POINT + code[0].K*(measure[0].airmass - 1.000) + SCALE*code[0].C - measure[0].Mcal;
+  PhotCode *code = &photcodes[0].code[Np];
+
+  // measure.M has the static ZERO_POINT (25.0) applied, but not measure.Flux
+  float Mcal = code[0].K*(measure[0].airmass - 1.000) + SCALE*code[0].C - measure[0].Mcal;
+  float Moff = Mcal - ZERO_POINT + 8.9;
+  float Foff = 3630.8 * MagToFlux(Mcal);
+  float Fcat = NAN;
+  switch (class) {
+    case MAG_CLASS_PSF:
+      Fcat = isnan (measure[0].FluxPSF)  ? MagToFlux(measure[0].M + Moff)     : measure[0].FluxPSF * Foff;
+      break;
+    case MAG_CLASS_KRON:
+      Fcat = isnan (measure[0].FluxKron) ? MagToFlux(measure[0].Mkron + Moff) : measure[0].FluxKron * Foff;
+      break;
+    case MAG_CLASS_APER:
+      Fcat = isnan (measure[0].FluxAp)   ? MagToFlux(measure[0].Map + Moff)   : measure[0].FluxAp * Foff;
+      break;
+    default:
+      break;
+  }
+  if (isnan(Fcat)) return (NAN);
 
   /* for DEP, color must be made of PRI/SEC */
-  mc = PhotColorForCodeTiny (average, secfilt, NULL, code);
-  if (isnan(mc)) return (Mrel);
-  mc = mc - SCALE*code[0].dX;
-
-  Mc = mc;
-  Mcol = 0;
+  float mc = PhotColorForCode (average, secfilt, NULL, code);
+  if (isnan(mc)) return (Fcat);
+  mc -= SCALE*code[0].dX;
+
+  double Mc = mc;
+  float Mcol = 0;
+  int i = 0;
+  for (i = 0; i < code[0].Nc; i++) {
+    Mcol += code[0].X[i]*Mc;
+    Mc *= mc;
+  }
+  float Fcol = MagToFlux (Mcol);
+
+  float Frel = Fcat * Fcol;
+  return (Frel);
+}
+
+/* return calibrated magnitude from measure for given photcode */
+float PhotFluxCal (Measure *thisone, Average *average, SecFilt *secfilt, Measure *measure, PhotCode *code, dvoMagClassType class) {
+
+  int i; 
+
+  if (code == NULL) return NAN;
+
+  /* code must be the matching PRI/SEC code for this measurement or an equivalent ALT */
+  int Np = photcodes[0].hashcode[thisone[0].photcode];
+  if (Np == -1) return (NAN);
+  PhotCode *myCode = &photcodes[0].code[Np];
+
+  if (code->code != myCode->equiv) return (NAN);
+
+  float Frel = PhotFluxRel (thisone, average, secfilt, class) + SCALE*code[0].C;
+
+  // get the relevant color term
+  float mc = PhotColorForCode (average, secfilt, measure, code);
+  if (isnan(mc)) return (Frel);
+  mc -= SCALE*code[0].dX;
+
+  // get the corresponding color correction in mags, convert to flux
+  double Mc = mc;
+  float Mcol = 0;
+  for (i = 0; i < code[0].Nc; i++) {
+    Mcol += code[0].X[i]*Mc;
+    Mc *= mc;
+  }
+  float Fcol = MagToFlux (Mcol);
+
+  float Fcal = Frel * Fcol;
+  return (Fcal);
+}
+
+/***/
+float PhotFluxAve (PhotCode *code, Average *average, SecFilt *secfilt, dvoMagClassType class, dvoMagSourceType source) {
+
+  if (code == NULL) return NAN;
+
+  int Ns = photcodes[0].hashNsec[code[0].code];
+  if (Ns == -1) return (NAN);
+
+  float Fave = NAN;
+  switch (source) {
+    case MAG_SRC_CHP:
+      switch (class) {
+	case MAG_CLASS_PSF:
+	  Fave = MagToFlux(secfilt[Ns].M);
+	  break;
+	case MAG_CLASS_KRON:
+	  Fave = MagToFlux(secfilt[Ns].Mkron);
+	  break;
+	case MAG_CLASS_APER:
+	  Fave = MagToFlux(secfilt[Ns].Map);
+	  break;
+	default:
+	  break;
+      }
+      break;
+    case MAG_SRC_WRP:
+      switch (class) {
+	case MAG_CLASS_PSF:
+	  Fave = isnan (secfilt[Ns].FpsfWrp)  ? MagToFlux(secfilt[Ns].MpsfWrp)  : secfilt[Ns].FpsfWrp;
+	  break;
+	case MAG_CLASS_KRON:
+	  Fave = isnan (secfilt[Ns].FkronWrp) ? MagToFlux(secfilt[Ns].MkronWrp) : secfilt[Ns].FkronWrp;
+	  break;
+	case MAG_CLASS_APER:
+	  Fave = isnan (secfilt[Ns].FapWrp)   ? MagToFlux(secfilt[Ns].MapWrp)   : secfilt[Ns].FapWrp;
+	  break;
+	default:
+	  break;
+      }
+      break;
+    case MAG_SRC_STK:
+      switch (class) {
+	case MAG_CLASS_PSF:
+	  Fave = isnan (secfilt[Ns].FpsfStk)  ? MagToFlux(secfilt[Ns].MpsfStk)  : secfilt[Ns].FpsfStk;
+	  break;
+	case MAG_CLASS_KRON:
+	  Fave = isnan (secfilt[Ns].FkronStk) ? MagToFlux(secfilt[Ns].MkronStk) : secfilt[Ns].FkronStk;
+	  break;
+	case MAG_CLASS_APER:
+	  Fave = isnan (secfilt[Ns].FapStk)   ? MagToFlux(secfilt[Ns].MapStk)   : secfilt[Ns].FapStk;
+	  break;
+	default:
+	  break;
+      }
+      break;
+    default:
+      break;
+  }
+  return (Fave);
+}
+
+float PhotFluxAveErr (PhotCode *code, Average *average, SecFilt *secfilt, dvoMagClassType class, dvoMagSourceType source) {
+
+  if (code == NULL) return NAN;
+
+  int Ns = photcodes[0].hashNsec[code[0].code];
+  if (Ns == -1) return (NAN);
+
+  float dFave = NAN;
+  switch (source) {
+    case MAG_SRC_CHP:
+      switch (class) {
+	case MAG_CLASS_PSF:
+	  dFave = secfilt[Ns].dM * MagToFlux(secfilt[Ns].M);
+	  break;
+	case MAG_CLASS_KRON:
+	  dFave = secfilt[Ns].dMkron * MagToFlux(secfilt[Ns].Mkron);
+	  break;
+	case MAG_CLASS_APER:
+	  dFave = secfilt[Ns].dMap * MagToFlux(secfilt[Ns].Map);
+	  break;
+	default:
+	  break;
+      }
+      break;
+    case MAG_SRC_WRP:
+      switch (class) {
+	case MAG_CLASS_PSF:
+	  dFave = secfilt[Ns].dFpsfWrp;
+	  break;
+	case MAG_CLASS_KRON:
+	  dFave = secfilt[Ns].dFkronWrp;
+	  break;
+	case MAG_CLASS_APER:
+	  dFave = secfilt[Ns].dFapWrp;
+	  break;
+	default:
+	  break;
+      }
+      break;
+    case MAG_SRC_STK:
+      switch (class) {
+	case MAG_CLASS_PSF:
+	  dFave = secfilt[Ns].dFpsfStk;
+	  break;
+	case MAG_CLASS_KRON:
+	  dFave = secfilt[Ns].dFkronStk;
+	  break;
+	case MAG_CLASS_APER:
+	  dFave = secfilt[Ns].dFapStk;
+	  break;
+	default:
+	  break;
+      }
+      break;
+    default:
+      break;
+  }
+  return (dFave);
+}
+
+/* return calibrated magnitude from average/secfilt for given photcode */
+float PhotFluxRef (PhotCode *code, Average *average, SecFilt *secfilt, Measure *measure, dvoMagClassType class, dvoMagSourceType source) {
+
+  int i;
+
+  float Fave = PhotFluxAve (code, average, secfilt, class, source);
+  if (isnan(Fave)) return NAN;
+
+  // correct for relative zero-point
+  float Moff = SCALE*code[0].C;
+
+  float mc = PhotColorForCode (average, secfilt, measure, code);
+  if (isnan(mc)) return (Fave * MagToFlux(Moff));
+  mc -= SCALE*code[0].dX;
+
+  // correct for color terms
+  double Mc = mc;
+  float Mcol = 0;
   for (i = 0; i < code[0].Nc; i++) {
     Mcol += code[0].X[i]*Mc;
     Mc *= mc;    /* the 0.001 is needed for higher order terms to keep the units mag = mag^n */
   }
-  Mrel += Mcol;
-  return (Mrel);
-}
-
-/* return calibrated magnitude from measure for given photcode */
-float PhotCalTiny (MeasureTiny *thisone, AverageTiny *average, SecFilt *secfilt, MeasureTiny *measure, PhotCode *code) {
-
-  int i, Np; 
-  float Mcal, Mrel, Mcol, mc, Mc;
-
-  if (code == NULL) return NAN;
-
-  /* code must be the matching PRI/SEC code for this measurement or an equivalent ALT */
-  Np = photcodes[0].hashcode[thisone[0].photcode];
+  float Foff = MagToFlux(Mcol);
+  return (Fave * Foff);
+}
+
+float PhotFluxInstErr (Measure *measure, dvoMagClassType class) {
+
+  float Moff = - measure[0].dt - ZERO_POINT;
+
+  // use dFlux if we can, but use dMag if we must:
+  // dFlux = Flux * dMag
+
+  float dFinst = NAN;
+  switch (class) {
+    case MAG_CLASS_PSF:
+      if (isnan (measure[0].dFluxPSF)) {
+	float Finst = MagToFlux(measure[0].M + Moff);
+	dFinst = measure[0].dM * Finst;
+      } else {
+	dFinst = measure[0].dFluxPSF;
+      }
+      break;
+    case MAG_CLASS_KRON:
+      if (isnan (measure[0].dFluxKron)) {
+	float Finst = MagToFlux(measure[0].Mkron + Moff);
+	dFinst = measure[0].dMkron * Finst;
+      } else {
+	dFinst = measure[0].dFluxKron;
+      }
+      break;
+    case MAG_CLASS_APER:
+      if (isnan (measure[0].dFluxAp)) {
+	float Finst = MagToFlux(measure[0].Map + Moff);
+	dFinst = measure[0].dMap * Finst;
+      } else {
+	dFinst = measure[0].dFluxAp;
+      }
+      break;
+    default:
+      break;
+  }
+  return (dFinst);
+}
+
+float PhotFluxCatErr (Measure *measure, dvoMagClassType class) {
+
+  int Np = photcodes[0].hashcode[measure[0].photcode];
   if (Np == -1) return (NAN);
-
-  if (photcodes[0].code[Np].type == PHOT_REF) {
-    Mrel = thisone[0].M;
-    return (Mrel);
-  }
-  if (code[0].code != photcodes[0].code[Np].equiv) return (NAN);
-
-  Mcal = PhotRelTiny (thisone, average, secfilt) + SCALE*code[0].C;
-
-  mc = PhotColorForCodeTiny (average, secfilt, measure, code);
-  if (isnan(mc)) return (Mcal);
-  mc = mc - SCALE*code[0].dX;
-
-  Mc = mc;
-  Mcol = 0;
+  PhotCode *code = &photcodes[0].code[Np];
+
+  // measure.M has the static ZERO_POINT (25.0) applied, but not measure.Flux
+  float Mcal = code[0].K*(measure[0].airmass - 1.000) + SCALE*code[0].C;
+  float Moff = Mcal - ZERO_POINT + 8.9;
+  float Foff = 3630.8 * MagToFlux(Mcal);
+
+  // use dFlux if we can, but use dMag if we must:
+  // dFlux = Flux * dMag
+
+  float dFcat = NAN;
+  switch (class) {
+    case MAG_CLASS_PSF:
+      if (isnan (measure[0].dFluxPSF)) {
+	float Finst = MagToFlux(measure[0].M + Moff);
+	dFcat = measure[0].dM * Finst;
+      } else {
+	dFcat = measure[0].dFluxPSF * Foff;
+      }
+      break;
+    case MAG_CLASS_KRON:
+      if (isnan (measure[0].dFluxKron)) {
+	float Finst = MagToFlux(measure[0].Mkron + Moff);
+	dFcat = measure[0].dMkron * Finst;
+      } else {
+	dFcat = measure[0].dFluxKron * Foff;
+      }
+      break;
+    case MAG_CLASS_APER:
+      if (isnan (measure[0].dFluxAp)) {
+	float Finst = MagToFlux(measure[0].Map + Moff);
+	dFcat = measure[0].dMap * Finst;
+      } else {
+	dFcat = measure[0].dFluxAp * Foff;
+      }
+      break;
+    default:
+      break;
+  }
+  return (dFcat);
+}
+
+/******** alternate photometry conversion functions using MeasureTiny and AverageTiny *********/
+float PhotInstTiny (MeasureTiny *measure, dvoMagClassType class) {
+
+  int Np = photcodes[0].hashcode[measure[0].photcode];
+  if (Np == -1) return (NAN);
+  PhotCode *code = &photcodes[0].code[Np];
+
+  float Mraw = NAN;
+  switch (class) {
+    case MAG_CLASS_PSF:
+      Mraw = measure[0].M;
+      break;
+    case MAG_CLASS_KRON:
+      // Mraw = measure[0].Mkron;
+      break;
+    case MAG_CLASS_APER:
+      // Mraw = measure[0].Map;
+      break;
+    default:
+      break;
+  }
+  if (code->type == PHOT_REF) {
+    return (Mraw);
+  }
+  float Minst = Mraw - measure[0].dt - ZERO_POINT;
+
+  return (Minst);
+}
+
+float PhotCatTiny (MeasureTiny *measure, dvoMagClassType class) {
+
+  int Np = photcodes[0].hashcode[measure[0].photcode];
+  if (Np == -1) return (NAN);
+  PhotCode *code = &photcodes[0].code[Np];
+
+  float Mraw = NAN;
+  switch (class) {
+    case MAG_CLASS_PSF:
+      Mraw = measure[0].M;
+      break;
+    case MAG_CLASS_KRON:
+      // Mraw = measure[0].Mkron;
+      break;
+    case MAG_CLASS_APER:
+      // Mraw = measure[0].Map;
+      break;
+    default:
+      break;
+  }
+  if (code->type == PHOT_REF) {
+    return (Mraw);
+  }
+
+  float Mcat = Mraw - ZERO_POINT + code[0].K*(measure[0].airmass - 1.000) + SCALE*code[0].C;
+  
+  return (Mcat);
+}
+
+float PhotSysTiny (MeasureTiny *measure, AverageTiny *average, SecFilt *secfilt, dvoMagClassType class) {
+
+  int Np = photcodes[0].hashcode[measure[0].photcode];
+  if (Np == -1) return (NAN);
+  PhotCode *code = &photcodes[0].code[Np];
+
+  float Mraw = NAN;
+  switch (class) {
+    case MAG_CLASS_PSF:
+      Mraw = measure[0].M;
+      break;
+    case MAG_CLASS_KRON:
+      // Mraw = measure[0].Mkron;
+      break;
+    case MAG_CLASS_APER:
+      // Mraw = measure[0].Map;
+      break;
+    default:
+      break;
+  }
+  if (code->type == PHOT_REF) {
+    return (Mraw);
+  }
+  float Mcat = Mraw - ZERO_POINT + code[0].K*(measure[0].airmass - 1.000) + SCALE*code[0].C;
+
+  /* for DEP, color must be made of PRI/SEC */
+  float mc = PhotColorForCodeTiny (average, secfilt, NULL, code);
+  if (isnan(mc)) return (Mcat);
+  mc -= SCALE*code[0].dX;
+
+  int i = 0;
+  double Mc = mc;
+  float Mcol = 0;
   for (i = 0; i < code[0].Nc; i++) {
     Mcol += code[0].X[i]*Mc;
     Mc *= mc;
   }
+  float Msys = Mcat + Mcol;
+  return (Msys);
+}
+
+float PhotRelTiny (MeasureTiny *measure, AverageTiny *average, SecFilt *secfilt, dvoMagClassType class) {
+
+  int Np = photcodes[0].hashcode[measure[0].photcode];
+  if (Np == -1) return (NAN);
+  PhotCode *code = &photcodes[0].code[Np];
+
+  float Mraw = NAN;
+  switch (class) {
+    case MAG_CLASS_PSF:
+      Mraw = measure[0].M;
+      break;
+    case MAG_CLASS_KRON:
+      // Mraw = measure[0].Mkron;
+      break;
+    case MAG_CLASS_APER:
+      // Mraw = measure[0].Map;
+      break;
+    default:
+      break;
+  }
+  if (code->type == PHOT_REF) {
+    return (Mraw);
+  }
+  float Mcat = Mraw - ZERO_POINT + code[0].K*(measure[0].airmass - 1.000) + SCALE*code[0].C - measure[0].Mcal;
+
+  /* for DEP, color must be made of PRI/SEC */
+  float mc = PhotColorForCodeTiny (average, secfilt, NULL, code);
+  if (isnan(mc)) return (Mcat);
+  mc -= SCALE*code[0].dX;
+
+  double Mc = mc;
+  float Mcol = 0;
+  int i = 0;
+  for (i = 0; i < code[0].Nc; i++) {
+    Mcol += code[0].X[i]*Mc;
+    Mc *= mc;
+  }
+  float Mrel = Mcat + Mcol;
+  return (Mrel);
+}
+
+/* return calibrated magnitude from measure for given photcode */
+float PhotCalTiny (MeasureTiny *thisone, AverageTiny *average, SecFilt *secfilt, MeasureTiny *measure, PhotCode *code, dvoMagClassType class) {
+
+  int i; 
+
+  if (code == NULL) return NAN;
+
+  /* code must be the matching PRI/SEC code for this measurement or an equivalent ALT */
+  int Np = photcodes[0].hashcode[thisone[0].photcode];
+  if (Np == -1) return (NAN);
+  PhotCode *myCode = &photcodes[0].code[Np];
+
+  if (code->code != myCode->equiv) return (NAN);
+
+  // if we are REF type, just get the right version and return
+  if (myCode->type == PHOT_REF) {
+    float Mraw = NAN;
+    switch (class) {
+      case MAG_CLASS_PSF:
+	Mraw = thisone[0].M;
+	break;
+      case MAG_CLASS_KRON:
+	// Mraw = thisone[0].Mkron;
+	break;
+      case MAG_CLASS_APER:
+	// Mraw = thisone[0].Map;
+	break;
+      default:
+	break;
+    }
+    return (Mraw);
+  }
+
+  float Mcal = PhotRelTiny (thisone, average, secfilt, class) + SCALE*code[0].C;
+
+  float mc = PhotColorForCodeTiny (average, secfilt, measure, code);
+  if (isnan(mc)) return (Mcal);
+  mc -= SCALE*code[0].dX;
+
+  double Mc = mc;
+  float Mcol = 0;
+  for (i = 0; i < code[0].Nc; i++) {
+    Mcol += code[0].X[i]*Mc;
+    Mc *= mc;
+  }
   Mcal += Mcol;
   return (Mcal);
+}
+
+/***/
+float PhotAveTiny (PhotCode *code, AverageTiny *average, SecFilt *secfilt, dvoMagClassType class, dvoMagSourceType source) {
+
+  if (code == NULL) return NAN;
+
+  int Ns = photcodes[0].hashNsec[code[0].code];
+  if (Ns == -1) return (NAN);
+
+  float Mave = NAN;
+  switch (source) {
+    case MAG_SRC_CHP:
+      switch (class) {
+	case MAG_CLASS_PSF:
+	  Mave = secfilt[Ns].M;
+	  break;
+	case MAG_CLASS_KRON:
+	  Mave = secfilt[Ns].Mkron;
+	  break;
+	case MAG_CLASS_APER:
+	  Mave = secfilt[Ns].Map;
+	  break;
+	default:
+	  break;
+      }
+      break;
+    case MAG_SRC_WRP:
+      switch (class) {
+	case MAG_CLASS_PSF:
+	  Mave = secfilt[Ns].MpsfWrp;
+	  break;
+	case MAG_CLASS_KRON:
+	  Mave = secfilt[Ns].MkronWrp;
+	  break;
+	case MAG_CLASS_APER:
+	  Mave = secfilt[Ns].MapWrp;
+	  break;
+	default:
+	  break;
+      }
+      break;
+    case MAG_SRC_STK:
+      switch (class) {
+	case MAG_CLASS_PSF:
+	  Mave = secfilt[Ns].MpsfStk;
+	  break;
+	case MAG_CLASS_KRON:
+	  Mave = secfilt[Ns].MkronStk;
+	  break;
+	case MAG_CLASS_APER:
+	  Mave = secfilt[Ns].MapStk;
+	  break;
+	default:
+	  break;
+      }
+      break;
+    default:
+      break;
+  }
+  return (Mave);
+}
+
+/* return calibrated magnitude from average/secfilt for given photcode */
+float PhotRefTiny (PhotCode *code, AverageTiny *average, SecFilt *secfilt, MeasureTiny *measure, dvoMagClassType class, dvoMagSourceType source) {
+
+  int i;
+
+  float Mave = PhotAveTiny (code, average, secfilt, class, source);
+  if (isnan(Mave)) return NAN;
+
+  // correct for relative zero-point
+  float Mref = Mave + SCALE*code[0].C;
+
+  float mc = PhotColorForCodeTiny (average, secfilt, measure, code);
+  if (isnan(mc)) return (Mref);
+  mc -= SCALE*code[0].dX;
+
+  // correct for color terms
+  double Mc = mc;
+  float Mcol = 0;
+  for (i = 0; i < code[0].Nc; i++) {
+    Mcol += code[0].X[i]*Mc;
+    Mc *= mc;    /* the 0.001 is needed for higher order terms to keep the units mag = mag^n */
+  }
+  Mref += Mcol;
+  return (Mref);
 }
 
@@ -1212,44 +1691,4 @@
 }
 
-/* return calibrated magnitude from average/secfilt for given photcode */
-float PhotRefTiny (PhotCode *code, AverageTiny *average, SecFilt *secfilt, MeasureTiny *measure) {
-
-  int i, Ns;
-  float Mave, Mref, Mcol, mc;
-  double Mc;
-
-  if (code == NULL) return NAN;
-
-  Ns = photcodes[0].hashNsec[code[0].code];
-  Mave = (Ns == -1) ? NAN : secfilt[Ns].M;
-  Mref = Mave + SCALE*code[0].C;
-
-  mc = PhotColorForCodeTiny (average, secfilt, measure, code);
-  if (isnan(mc)) return (Mref);
-  mc = mc - SCALE*code[0].dX;
-
-  Mc = mc;
-  Mcol = 0;
-  for (i = 0; i < code[0].Nc; i++) {
-    Mcol += code[0].X[i]*Mc;
-    Mc *= mc;    /* the 0.001 is needed for higher order terms to keep the units mag = mag^n */
-  }
-  Mref += Mcol;
-  return (Mref);
-}
-
-/***/
-float PhotAveTiny (PhotCode *code, AverageTiny *average, SecFilt *secfilt) {
-
-  int Ns;
-  float Mave;
-
-  if (code == NULL) return NAN;
-
-  Ns = photcodes[0].hashNsec[code[0].code];
-  Mave = (Ns == -1) ? NAN : secfilt[Ns].M;
-  return (Mave);
-}
-
 float PhotdMTiny (PhotCode *code, AverageTiny *average, SecFilt *secfilt) {
 
@@ -1264,9 +1703,8 @@
 }
 
-// XXX return NAN or NAN_S_SHORT? (secfilt->Xm is short)
+// Xm is now (2014.07.03) stored as the chisq except in dvo formats which use as short
 float PhotXmTiny (PhotCode *code, AverageTiny *average, SecFilt *secfilt) {
 
   int Ns;
-  short Mi;
   float Xm;
 
@@ -1274,6 +1712,5 @@
 
   Ns = photcodes[0].hashNsec[code[0].code];
-  Mi = (Ns == -1) ? NAN : secfilt[Ns].Xm;
-  Xm = (isnan(Mi)) ? -1.0 : pow (10.0, 0.01*Mi);
+  Xm = (Ns == -1) ? NAN : secfilt[Ns].Mchisq;
   return (Xm);
 }
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_tiny_values.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_tiny_values.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/dvo_tiny_values.c	(revision 37403)
@@ -14,6 +14,6 @@
 
 void CopyMeasureToTiny (MeasureTiny *measureT, Measure *measure) {
-  measureT[0].dR         = measure[0].dR;
-  measureT[0].dD         = measure[0].dD;
+  measureT[0].R          = measure[0].R;
+  measureT[0].D          = measure[0].D;
   measureT[0].M          = measure[0].M;
   measureT[0].Mcal       = measure[0].Mcal;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/skyregion_io.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/skyregion_io.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libdvo/src/skyregion_io.c	(revision 37403)
@@ -78,4 +78,5 @@
   gfits_free_matrix (&matrix);
   gfits_free_header (&theader);
+  fclose (f);
 
   return (skytable);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libfits/include/gfitsio.h
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libfits/include/gfitsio.h	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libfits/include/gfitsio.h	(revision 37403)
@@ -27,6 +27,8 @@
 # define FT_RECORD_SIZE        2880  /* FITS block size */
 
+# define FT_BZERO_INT8 -1.0*0x80
 # define FT_BZERO_INT16 1.0*0x8000	  
 # define FT_BZERO_INT32 1.0*0x80000000
+# define FT_BZERO_INT64 1.0*0x8000000000000000
 
 /* this structure defines the buffer which contains a header
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libfits/matrix/F_compress_M.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libfits/matrix/F_compress_M.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libfits/matrix/F_compress_M.c	(revision 37403)
@@ -58,4 +58,5 @@
 
   // is ZIMAGE present?
+  // NOTE target of %t must be int length
   status = gfits_scan_alt (ftable->header, "ZIMAGE", "%t", 1, &zimage);
   if (!status || !zimage) ESCAPE;
@@ -125,4 +126,5 @@
   int have_ztension;
 
+  // NOTE target of %t must be int length
   have_zsimple  = gfits_scan_alt (header, "ZSIMPLE", "%t", 1, &zsimple);
   have_ztension = gfits_scan (header, "ZTENSION", "%s", 1, exttype);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libfits/table/F_get_column.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libfits/table/F_get_column.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libfits/table/F_get_column.c	(revision 37403)
@@ -75,4 +75,9 @@
   Pout = array;
   if (!strcmp (type, "char")) {
+    for (i = 0; i < Nval*Ny; i++, Pin+=Nbytes, Pout+=Nbytes) {
+      *(char *)Pout = *(char *)Pin*Bscale + Bzero;
+    }
+  }
+  if (!strcmp (type, "byte")) {
     for (i = 0; i < Nval*Ny; i++, Pin+=Nbytes, Pout+=Nbytes) {
       *(char *)Pout = *(char *)Pin*Bscale + Bzero;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libfits/table/F_set_column.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libfits/table/F_set_column.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libfits/table/F_set_column.c	(revision 37403)
@@ -81,5 +81,11 @@
   Pin = data;
   Pout = array;
+  // does it makes sense to scale 'char' data?
   if (!strcmp (type, "char")) {
+    for (i = 0; i < Nval*Nrow; i++, Pin+=Nbytes, Pout+=Nbytes) {
+      *(char *)Pout = (*(char *)Pin - Bzero) / Bscale;
+    }
+  }
+  if (!strcmp (type, "byte")) {
     for (i = 0; i < Nval*Nrow; i++, Pin+=Nbytes, Pout+=Nbytes) {
       *(char *)Pout = (*(char *)Pin - Bzero) / Bscale;
@@ -221,4 +227,7 @@
   Pout = array;
 
+  // # define ASSIGN_DATA(ITYPE,INAME,ISIZE,OTYPE,ONAME)
+  // if (!strcmp (intype, #ITYPE)) {
+
   /** input == char **/
   if (!strcmp (outtype, "char") && !strcmp (intype, "char")) {
@@ -228,4 +237,10 @@
     }
   }
+  if (!strcmp (outtype, "byte") && !strcmp (intype, "char")) {
+    int NbytesIn = 1;
+    for (i = 0; i < Nval*Nrow; i++, Pin+=NbytesIn, Pout+=NbytesOut) {
+      *(char *)Pout = (*(char *)Pin - Bzero) / Bscale;
+    }
+  }
   if (!strcmp (outtype, "short") && !strcmp (intype, "char")) {
     int NbytesIn = 1;
@@ -265,4 +280,63 @@
   }
   if (!strcmp (outtype, "double") && !strcmp (intype, "char")) {
+    int NbytesIn = 1;
+    for (i = 0; i < Nval*Nrow; i++, Pin += NbytesIn, Pout += NbytesOut) {
+      *(double *)Pout = (*(char *)Pin - Bzero) / Bscale;
+# ifdef BYTE_SWAP
+      SWAP_DBLE;
+# endif
+    }
+  }
+
+  /** input == byte **/
+  if (!strcmp (outtype, "char") && !strcmp (intype, "byte")) {
+    int NbytesIn = 1;
+    for (i = 0; i < Nval*Nrow; i++, Pin+=NbytesIn, Pout+=NbytesOut) {
+      *(char *)Pout = (*(char *)Pin - Bzero) / Bscale;
+    }
+  }
+  if (!strcmp (outtype, "byte") && !strcmp (intype, "byte")) {
+    int NbytesIn = 1;
+    for (i = 0; i < Nval*Nrow; i++, Pin+=NbytesIn, Pout+=NbytesOut) {
+      *(char *)Pout = (*(char *)Pin - Bzero) / Bscale;
+    }
+  }
+  if (!strcmp (outtype, "short") && !strcmp (intype, "byte")) {
+    int NbytesIn = 1;
+    for (i = 0; i < Nval*Nrow; i++, Pin += NbytesIn, Pout += NbytesOut) {
+      *(short *)Pout = (*(char *)Pin - Bzero) / Bscale;
+# ifdef BYTE_SWAP
+      SWAP_BYTE;
+# endif
+    }  
+  }
+  if (!strcmp (outtype, "int") && !strcmp (intype, "byte")) {
+    int NbytesIn = 1;
+    for (i = 0; i < Nval*Nrow; i++, Pin += NbytesIn, Pout += NbytesOut) {
+      *(int *)Pout = (*(char *)Pin - Bzero) / Bscale;
+# ifdef BYTE_SWAP
+      SWAP_WORD;
+# endif
+    }
+  }
+  if (!strcmp (outtype, "int64_t") && !strcmp (intype, "byte")) {
+    int NbytesIn = 1;
+    for (i = 0; i < Nval*Nrow; i++, Pin += NbytesIn, Pout += NbytesOut) {
+      *(int64_t *)Pout = (*(char *)Pin - Bzero) / Bscale;
+# ifdef BYTE_SWAP
+      SWAP_DBLE;
+# endif
+    }
+  }
+  if (!strcmp (outtype, "float") && !strcmp (intype, "byte")) {
+    int NbytesIn = 1;
+    for (i = 0; i < Nval*Nrow; i++, Pin += NbytesIn, Pout += NbytesOut) {
+      *(float *)Pout = (*(char *)Pin - Bzero) / Bscale;
+# ifdef BYTE_SWAP
+      SWAP_WORD;
+# endif
+    }
+  }
+  if (!strcmp (outtype, "double") && !strcmp (intype, "byte")) {
     int NbytesIn = 1;
     for (i = 0; i < Nval*Nrow; i++, Pin += NbytesIn, Pout += NbytesOut) {
@@ -281,4 +355,10 @@
     }
   }
+  if (!strcmp (outtype, "byte") && !strcmp (intype, "short")) {
+    int NbytesIn = 2;
+    for (i = 0; i < Nval*Nrow; i++, Pin += NbytesIn, Pout += NbytesOut) {
+      *(char *)Pout = (*(short *)Pin - Bzero) / Bscale;
+    }
+  }
   if (!strcmp (outtype, "short") && !strcmp (intype, "short")) {
     int NbytesIn = 2;
@@ -334,4 +414,10 @@
     }
   }
+  if (!strcmp (outtype, "byte") && !strcmp (intype, "int")) {
+    int NbytesIn = 4;
+    for (i = 0; i < Nval*Nrow; i++, Pin += NbytesIn, Pout += NbytesOut) {
+      *(char *)Pout = (*(int *)Pin - Bzero) / Bscale;
+    }
+  }
   if (!strcmp (outtype, "short") && !strcmp (intype, "int")) {
     int NbytesIn = 4;
@@ -387,4 +473,10 @@
     }
   }
+  if (!strcmp (outtype, "byte") && !strcmp (intype, "int64_t")) {
+    int NbytesIn = 8;
+    for (i = 0; i < Nval*Nrow; i++, Pin += NbytesIn, Pout += NbytesOut) {
+      *(char *)Pout = (*(int64_t *)Pin - Bzero) / Bscale;
+    }
+  }
   if (!strcmp (outtype, "short") && !strcmp (intype, "int64_t")) {
     int NbytesIn = 8;
@@ -440,4 +532,10 @@
     }
   }
+  if (!strcmp (outtype, "byte") && !strcmp (intype, "float")) {
+    int NbytesIn = 4;
+    for (i = 0; i < Nval*Nrow; i++, Pin += NbytesIn, Pout += NbytesOut) {
+      *(char *)Pout = (*(float *)Pin - Bzero) / Bscale;
+    }
+  }
   if (!strcmp (outtype, "short") && !strcmp (intype, "float")) {
     int NbytesIn = 4;
@@ -488,4 +586,10 @@
   /** input == double **/
   if (!strcmp (outtype, "char") && !strcmp (intype, "double")) {
+    int NbytesIn = 8;
+    for (i = 0; i < Nval*Nrow; i++, Pin += NbytesIn, Pout += NbytesOut) {
+      *(char *)Pout = (*(double *)Pin - Bzero) / Bscale;
+    }
+  }
+  if (!strcmp (outtype, "byte") && !strcmp (intype, "double")) {
     int NbytesIn = 8;
     for (i = 0; i < Nval*Nrow; i++, Pin += NbytesIn, Pout += NbytesOut) {
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libfits/table/F_table_format.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libfits/table/F_table_format.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libfits/table/F_table_format.c	(revision 37403)
@@ -19,11 +19,14 @@
   if ((Nv == 0) && (Fchar == format)) Nv = 1;
 
+  // NOTE: X, L, B all are stored in 1-byte columns (X by default has at least room for 8 bits)
+  // I report these as type 'byte' as opposed to 'char', which is interpreted as a string
+
   *Nbytes = 0;
   switch (*Fchar) {
   case  'X':
-    { *Nbytes = 1;  strcpy (type, "char");   *Nval = 1 + (int) Nv / 8; }
+    { *Nbytes = 1;  strcpy (type, "byte");   *Nval = 1 + (int) Nv / 8; }
     break;
   case  'L':
-    { *Nbytes = 1;  strcpy (type, "char");   *Nval = Nv;               }
+    { *Nbytes = 1;  strcpy (type, "byte");   *Nval = Nv;               }
     break;
   case  'A':
@@ -31,5 +34,5 @@
     break;
   case  'B':
-    { *Nbytes = 1;  strcpy (type, "char");   *Nval = Nv;               }
+    { *Nbytes = 1;  strcpy (type, "byte");   *Nval = Nv;               }
     break;
   case  'I':
@@ -268,5 +271,14 @@
     }
 
+    // Does it make sense to scale 'char' data (as opposed to 'byte')?
     if (!strcmp (type, "char"))   { 
+      for (j = 0; j < Ny; j++) {
+	for (n = 0; n < Nval; n++) {
+	  tmpChar = (char *)&ftable[0].buffer[j*Nx + n*Nbytes + off];
+	  *tmpChar = *tmpChar * tscale + tzero;
+	}
+      }
+    }
+    if (!strcmp (type, "byte"))   { 
       for (j = 0; j < Ny; j++) {
 	for (n = 0; n < Nval; n++) {
@@ -352,4 +364,5 @@
     }
 
+    // does this make sense? (see note above)
     if (!strcmp (type, "char"))   { 
       for (j = 0; j < Ny; j++) {
@@ -360,4 +373,12 @@
       }
     }
+    if (!strcmp (type, "byte"))   { 
+      for (j = 0; j < Ny; j++) {
+	for (n = 0; n < Nval; n++) {
+	  tmpChar = (char *)&ftable[0].buffer[j*Nx + n*Nbytes + off];
+	  *tmpChar = (*tmpChar - tzero) / tscale;
+	}
+      }
+    }
     if (!strcmp (type, "short"))   { 
       for (j = 0; j < Ny; j++) {
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libkapa/src/KapaOpen.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libkapa/src/KapaOpen.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libkapa/src/KapaOpen.c	(revision 37403)
@@ -1,3 +1,6 @@
 # include "kapa_internal.h"
+
+// kapa connection timeout is N_RETRY * 10000 usec
+# define N_RETRY 2000
 
 # define MY_PORT 2500
@@ -9,5 +12,4 @@
 static int *VALID = NULL;
 
-char *_parse_nextword (char *string);
 int KapaLaunchCommand (char *line);
 
@@ -218,15 +220,33 @@
   // apparently, I can connect on someone else's port (eg GoogleTalkPlugin)
   // do a simple handshake before we set !NONBLOCK:
-  char line[5];
-  int Nout = read (InitSocket, line, 4);
-  if (Nout != 4) {
-    if (DEBUG) fprintf (stderr, "connection failed\n");
-    close (InitSocket);
-    return (-1);
-  }
-  if (strncmp (line, "KAPA", 4)) {
-    if (DEBUG) fprintf (stderr, "connection to the wrong server\n");
-    close (InitSocket);
-    return (-1);
+
+  // ensure the socket is NONBLOCK first...
+  fcntl (InitSocket, F_SETFL, O_NONBLOCK);
+
+  int Ntry = 0;
+retry_message:
+  { 
+    char line[5];
+    int Nout = read (InitSocket, line, 4);
+    if ((Nout == -1) && (errno == EAGAIN)) {
+      Ntry ++;
+      if (Ntry > 500) {
+	if (DEBUG) fprintf (stderr, "handshake failure\n");
+	close (InitSocket);
+	return (-1);
+      }
+      usleep (10000);
+      goto retry_message;
+    }
+    if (Nout != 4) {
+      if (DEBUG) fprintf (stderr, "connection failed\n");
+      close (InitSocket);
+      return (-1);
+    }
+    if (strncmp (line, "KAPA", 4)) {
+      if (DEBUG) fprintf (stderr, "connection to the wrong server\n");
+      close (InitSocket);
+      return (-1);
+    }
   }
 
@@ -265,11 +285,14 @@
   }
 
-# define NTRY 500
+  INITTIME;
+
   Ntry = 0;
-  while (Ntry < NTRY) {
+  while (Ntry < N_RETRY) {
     sock = KapaClientSocket ("localhost");
     if (sock != -1) break;
-    // if (errno != EAGAIN) break;
-    if (errno != ECONNREFUSED) break;
+    if (errno != ECONNREFUSED) {
+      perror ("KapaOpen");
+      break;
+    }
     // no connection yet. try again, but first check 
     // if the kapa job has exited
@@ -288,5 +311,23 @@
   }
 
-  if (sock < 0) return (-1);
+  if (sock < 0) {
+    MARKTIME ("failed to connect to kapa after %f seconds\n", dtime);
+    int killStatus = kill (pid, SIGKILL);
+    if (killStatus) {
+      perror ("failed to kill process");
+    }
+    int waitStatus = waitpid (pid, NULL, 0);
+    if (waitStatus == pid) {
+      fprintf (stderr, "harvested process %d\n", pid);
+    } else if (waitStatus < 0) {
+      fprintf (stderr, "failed to harvest process %d\n", pid);
+    } else if (waitStatus == 0) {
+      fprintf (stderr, "process not exited: %d\n", pid);
+    } else {
+      fprintf (stderr, "odd exit status: %d vs pid %d\n", waitStatus, pid);
+    }
+    return (-1);
+  }
+
   return (sock);
 }
@@ -330,7 +371,8 @@
   fcntl (InitSocket, F_SETFL, O_NONBLOCK);
 
-# define NTRY 500
+  INITTIME;
+
   Ntry = 0;
-  while (Ntry < NTRY) {
+  while (Ntry < N_RETRY) {
     fd = accept (InitSocket, (struct sockaddr *)&Address, &AddressLength);
     if (fd != -1) break;
@@ -352,5 +394,10 @@
   }
 
-  if (fd < 0) return (-1);
+  if (fd < 0) {
+    MARKTIME ("failed to connect to kapa after %f seconds\n", dtime);
+    kill (pid, SIGKILL);
+    waitpid (pid, NULL, WNOHANG);
+    return (-1);
+  }
 
   // the client uses a BLOCKing socket by default
@@ -394,5 +441,5 @@
   done = FALSE;
   while (!done) {
-    q = _parse_nextword (p);
+    q = parse_nextword (p);
     if (q && *q) {
       argv[i] = strncreate (p, q - p);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libohana/include/ohana.h
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libohana/include/ohana.h	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libohana/include/ohana.h	(revision 37403)
@@ -71,4 +71,13 @@
 # endif
 
+# define MARKTIME(MSG,...) {			\
+    gettimeofday (&stopTimer, (void *) NULL);	\
+    float dtime = DTIME (stopTimer, startTimer);	\
+    fprintf (stderr, MSG, __VA_ARGS__); }
+
+# define INITTIME \
+  struct timeval startTimer, stopTimer; \
+  gettimeofday (&startTimer, (void *) NULL);
+
 #ifdef __GNUC__
 #define OHANA_FORMAT(style, fmt, varargs) __attribute__((format(style, fmt, varargs)))
@@ -183,5 +192,5 @@
 
 # ifndef isfinite
-# define isfinite(A) (!isnan(A))
+# define isfinite(A) (!isnan(A) && !isinf(A))
 # endif
 
@@ -252,8 +261,13 @@
 int     scan_line              PROTO((FILE *f, char *line)); 
 int     scan_line_maxlen       PROTO((FILE *f, char *line, int maxlen)); 
+char   *parse_nextword         PROTO((char *string));
+char   *parse_nextword_csv     PROTO((char *string));
 int     dparse                 PROTO((double *X, int NX, char *line));
 int     dparse_csv             PROTO((double *X, int NX, char *line));
 int     iparse                 PROTO((int *X, int NX, char *line));
 int     iparse_csv             PROTO((int *X, int NX, char *line));
+int     charparse_csv          PROTO((char *X, int NX, char *line));
+char   *ptrparse               PROTO((int NX, char *line));
+char   *ptrparse_csv           PROTO((int NX, char *line));
 int     charparse_csv          PROTO((char *X, int NX, char *line));
 int     charparse              PROTO((char *X, int NX, char *line));
@@ -266,4 +280,7 @@
 char   *strip_version          PROTO((char *input));
 char   *strsubs                PROTO((char *string, char *match, char *with));
+
+char   *getword                PROTO((char *string));
+char   *skipword               PROTO((char *string));
 
 /* in findexec.c */
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/libohana/src/string.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/libohana/src/string.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/libohana/src/string.c	(revision 37403)
@@ -167,5 +167,5 @@
 }
 
-char *_parse_nextword (char *string) {
+char *parse_nextword (char *string) {
 
   if (string == (char *) NULL) return ((char *) NULL);
@@ -182,5 +182,5 @@
 // ,,, : go from , to , to , to 0
 
-char *_parse_nextword_csv (char *string) {
+char *parse_nextword_csv (char *string) {
 
   if (string == (char *) NULL) return ((char *) NULL);
@@ -199,5 +199,5 @@
   word = line;
   for (i = 0; i < NX - 1; i++)
-    word = _parse_nextword (word);
+    word = parse_nextword (word);
 
   *X = strtod (word, &ptr);
@@ -215,5 +215,5 @@
   word = line;
   for (i = 0; i < NX - 1; i++)
-    word = _parse_nextword_csv (word);
+    word = parse_nextword_csv (word);
   
   if (word[0] == '"') word[0] = ' ';
@@ -237,5 +237,5 @@
   word = line;
   for (i = 0; i < NX - 1; i++)
-    word = _parse_nextword (word);
+    word = parse_nextword (word);
 
   *X = strtol (word, &ptr, 0);
@@ -253,5 +253,5 @@
   word = line;
   for (i = 0; i < NX - 1; i++)
-    word = _parse_nextword_csv (word);
+    word = parse_nextword_csv (word);
   
   if (word[0] == '"') word[0] = ' ';
@@ -274,5 +274,5 @@
   word = line;
   for (i = 0; i < NX - 1; i++)
-    word = _parse_nextword (word);
+    word = parse_nextword (word);
 
   *X = word[0];
@@ -287,5 +287,5 @@
   word = line;
   for (i = 0; i < NX - 1; i++)
-    word = _parse_nextword_csv (word);
+    word = parse_nextword_csv (word);
   
   if (word[0] == '"') word[0] = word[1];
@@ -299,4 +299,31 @@
 }
 
+// return a pointer to the start of the desired field
+char *ptrparse (int NX, char *line) {
+
+  int i;
+  char *word;
+
+  word = line;
+  for (i = 0; i < NX - 1; i++) {
+    word = parse_nextword (word);
+  }
+  return word;
+}
+
+char *ptrparse_csv (int NX, char *line) {
+
+  int i;
+  char *word;
+
+  word = line;
+  for (i = 0; i < NX - 1; i++)
+    word = parse_nextword_csv (word);
+  
+  if (word[0] == '"') word ++;
+  if (word[0] == ',') return NULL;
+  return word;
+}
+
 int tparse (time_t *X, int NX, char *line) {
 
@@ -306,5 +333,5 @@
   word = line;
   for (i = 0; i < NX - 1; i++)
-    word = _parse_nextword (word);
+    word = parse_nextword (word);
 
   status = ohana_str_to_time (word, X);
@@ -320,5 +347,5 @@
   word = line;
   for (i = 0; i < NX - 1; i++)
-    word = _parse_nextword_csv (word);
+    word = parse_nextword_csv (word);
   
   if (word[0] == '"') word[0] = ' ';
@@ -341,5 +368,5 @@
   word = line;
   for (i = 0; i < NX - 1; i++)
-    word = _parse_nextword (word);
+    word = parse_nextword (word);
 
   *X = strtod (word, &ptr);
@@ -402,2 +429,41 @@
   return (q);
 }
+
+// return a newly allocated string containing the first complete set of non-whitespace
+char *getword (char *string) {
+
+  int i, j;
+  char *word;
+
+  if (!string) return (NULL);
+
+  // find the end of the whitespace (is there any non-whitespace?)
+  for (i = 0; OHANA_WHITESPACE (string[i]); i++);
+  if (!string[i]) return (NULL);
+
+  for (j = i; string[j] && !OHANA_WHITESPACE(string[j]); j++);
+  word = strncreate (&string[i], j - i);
+  return (word);
+}
+
+// returns a pointer to the next word, or NULL if there is not a next word
+char *skipword (char *string) {
+
+  int i;
+
+  if (!string) return (NULL);
+
+  // find the end of the whitespace (is there any non-whitespace?)
+  for (i = 0; OHANA_WHITESPACE (string[i]); i++);
+  if (!string[i]) return (NULL);
+
+  // find the end of the non-whitespace (this word)
+  while (string[i] && !OHANA_WHITESPACE(string[i])) i++;
+
+  // find the end of the following whitespace
+  while (string[i] &&  OHANA_WHITESPACE(string[i])) i++;
+  if (!string[i]) return (NULL);
+
+  return (&string[i]);
+}
+
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/cmd.astro/cplot.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/cmd.astro/cplot.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/cmd.astro/cplot.c	(revision 37403)
@@ -4,5 +4,5 @@
   
   double ra_prev = 0;
-  int i, kapa, Npts, status, leftside;
+  int i, kapa, Npts, status, leftside, valid, size;
   opihi_flt *x, *y, *r, *d, Rmin, Rmax, Rmid;
   Vector Xvec, Yvec, *xvec, *yvec;
@@ -11,6 +11,9 @@
   if (!style_args (&graphmode, &argc, argv, &kapa)) return FALSE;
 
-  if (argc != 3) {
+  valid  = (argc == 3);
+  valid |= (argc > 4) && !strcmp (argv[3], "where");
+  if (!valid) {
     gprint (GP_ERR, "USAGE: cplot <ra> <dec> [style]\n");
+    gprint (GP_ERR, "   OR: cplot <ra> <dec> [style] where (condition)\n");
     return (FALSE);
   }
@@ -32,4 +35,26 @@
   }
 
+  // tvec is used for logical test (truth vector)
+  Vector *tvec = NULL;
+  if (argc > 4) {
+    char *out = dvomath (argc - 4, &argv[4], &size, 1);
+    if (out == NULL) {
+      print_error ();
+      return FALSE;
+    }
+    if ((tvec = SelectVector (out, OLDVECTOR, TRUE)) == NULL) {
+      gprint (GP_ERR, " invalid logic result\n");
+      DeleteNamedVector (out);
+      free (out);
+      return (FALSE);
+    }
+  }
+
+  if (tvec && tvec[0].Nelements != yvec[0].Nelements) {
+    gprint (GP_ERR, "logic test vector not the same length as data vectors\n");
+    DeleteVector (tvec);
+    return (FALSE);
+  }
+
   SetVector (&Xvec, OPIHI_FLT, xvec[0].Nelements);
   SetVector (&Yvec, OPIHI_FLT, xvec[0].Nelements);
@@ -42,4 +67,9 @@
   Npts = 0;
   for (i = 0; i < Xvec.Nelements; i++, r++, d++) {
+    if (tvec) {
+      int skip = (tvec->type == OPIHI_FLT) ? (tvec->elements.Flt[i] == 0.0) : (tvec->elements.Int[i] == 0.0);
+      if (skip) continue;
+    }
+
     double ra = ohana_normalize_angle (*r);
     while (ra < Rmin) ra += 360.0;
@@ -88,4 +118,6 @@
   free (Yvec.elements.Ptr);
     
+  if (tvec) DeleteVector (tvec);
+
   return (TRUE);
 }
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/cmd.basic/Makefile
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/cmd.basic/Makefile	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/cmd.basic/Makefile	(revision 37403)
@@ -55,4 +55,5 @@
 $(SRC)/substr.$(ARCH).o     \
 $(SRC)/strhash.$(ARCH).o     \
+$(SRC)/strmatch.$(ARCH).o     \
 $(SRC)/strpop.$(ARCH).o     \
 $(SRC)/strsub.$(ARCH).o     \
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/cmd.basic/init.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/cmd.basic/init.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/cmd.basic/init.c	(revision 37403)
@@ -40,4 +40,5 @@
 int fprintf_opihi   PROTO((int, char **));
 int strlen_func     PROTO((int, char **));
+int strmatch        PROTO((int, char **));
 int substr_func     PROTO((int, char **));
 int strpop          PROTO((int, char **));
@@ -97,4 +98,5 @@
   {1, "strpop",        strpop,             "pop a string"},
   {1, "strsub",        strsub,             "replace instances of a key in a string"},
+  {1, "strmatch",      strmatch,           "string length"},
   {1, "wait",          wait_func,          "wait until return is typed"},
   {1, "which",         which,              "show command *"}
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/cmd.basic/list.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/cmd.basic/list.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/cmd.basic/list.c	(revision 37403)
@@ -2,6 +2,4 @@
 # define D_NLINES 100
 static char prompt[] = ">> ";
-
-static int set_list_varname (char *line, char *base, int N, int excelStyle);
 
 int list (int argc, char **argv) {
@@ -311,32 +309,2 @@
   return (TRUE);
 }
-
-static int set_list_varname (char *line, char *base, int N, int excelStyle) {
-
-  int i;
-    
-  // A-Z correspond to 0 - 25
-
-  if (excelStyle) {
-    float f = log(26.0);
-    float g = (N == 0) ? 0.0 : log(1.0*N);
-    int Ndigit = (int) (g / f) + 1;
-    if (Ndigit > 10) {
-      sprintf (line, "%s:ZZZZZZZZZZ", base);
-      return FALSE;
-    }
-    char name[12];
-    memset (name, 0, 12);
-    for (i = 0; i < Ndigit; i++) {
-      float Npow = Ndigit - i - 1;
-      float g = pow(26.0, Npow);
-      int V = (int) (N / g);
-      name[i] = (Npow == 0.0) ? 'A' + V : 'A' + V - 1;
-      N -= V * g;
-    }
-    sprintf (line, "%s:%s", base, name);
-  } else {
-    sprintf (line, "%s:%d", base, N);
-  }
-  return TRUE;
-}
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/cmd.basic/strmatch.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/cmd.basic/strmatch.c	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/cmd.basic/strmatch.c	(revision 37403)
@@ -0,0 +1,176 @@
+# include "basic.h"
+
+int strmatch (int argc, char **argv) {
+
+  /* returns position of the first given character class */ 
+  int i, N;
+
+  char *startName = NULL;
+  char *lengthName = NULL;
+  if ((N = get_argument (argc, argv, "-output"))) {
+    remove_argument (N, &argc, argv);
+    startName = strcreate (argv[N]);
+    remove_argument (N, &argc, argv);
+    lengthName = strcreate (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  if (argc != 3) {
+    gprint (GP_ERR, "USAGE: strchr (string) (class) [-output start length]\n");
+    return (FALSE);
+  }
+
+  // 'class' may be alpha, float, int, 
+
+  if (!strcasecmp(argv[2], "alpha")) {
+    int myLength = strlen(argv[1]);
+    int found = FALSE;
+    int start = -1;
+    int length = -1;
+    for (i = 0; i < myLength; i++) {
+      int isUpper = (argv[1][i] >= 'A') && (argv[1][i] <= 'Z');
+      int isLower = (argv[1][i] >= 'a') && (argv[1][i] <= 'z');
+      if (!found && (isLower || isUpper)) {
+	start = i;
+	found = TRUE;
+	continue;
+      }
+      if (found && !(isLower || isUpper)) {
+	length = i - start;
+	break;
+      }
+    }
+    if (found && (length < 0)) {
+      length = myLength - start;
+    }
+    if (startName && lengthName) {
+      set_int_variable (startName, start);
+      set_int_variable (lengthName, length);
+    } else {
+      gprint (GP_LOG, "match: %d %d\n", start, length);
+    }
+    return TRUE;
+  }
+
+  if (!strcasecmp(argv[2], "upper")) {
+    int myLength = strlen(argv[1]);
+    int found = FALSE;
+    int start = -1;
+    int length = -1;
+    for (i = 0; i < myLength; i++) {
+      int isUpper = (argv[1][i] >= 'A') && (argv[1][i] <= 'Z');
+      // int isLower = (argv[1][i] >= 'a') && (argv[1][i] <= 'z');
+      if (!found && isUpper) {
+	start = i;
+	found = TRUE;
+	continue;
+      }
+      if (found && !isUpper) {
+	length = i - start;
+	break;
+      }
+    }
+    if (found && (length < 0)) {
+      length = myLength - start;
+    }
+    if (startName && lengthName) {
+      set_int_variable (startName, start);
+      set_int_variable (lengthName, length);
+    } else {
+      gprint (GP_LOG, "match: %d %d\n", start, length);
+    }
+    return TRUE;
+  }
+
+  if (!strcasecmp(argv[2], "lower")) {
+    int myLength = strlen(argv[1]);
+    int found = FALSE;
+    int start = -1;
+    int length = -1;
+    for (i = 0; i < myLength; i++) {
+      // int isUpper = (argv[1][i] >= 'A') && (argv[1][i] <= 'Z');
+      int isLower = (argv[1][i] >= 'a') && (argv[1][i] <= 'z');
+      if (!found && isLower) {
+	start = i;
+	found = TRUE;
+	continue;
+      }
+      if (found && !isLower) {
+	length = i - start;
+	break;
+      }
+    }
+    if (found && (length < 0)) {
+      length = myLength - start;
+    }
+    if (startName && lengthName) {
+      set_int_variable (startName, start);
+      set_int_variable (lengthName, length);
+    } else {
+      gprint (GP_LOG, "match: %d %d\n", start, length);
+    }
+    return TRUE;
+  }
+
+  if (!strcasecmp(argv[2], "float")) {
+    int myLength = strlen(argv[1]);
+    int found = FALSE;
+    int start = -1;
+    int length = -1;
+    for (i = 0; i < myLength; i++) {
+      int isDigit = (argv[1][i] >= '0') && (argv[1][i] <= '9');
+      int isFloat = isDigit || (argv[1][i] == '-') || (argv[1][i] == '.');
+      if (!found && isFloat) {
+	start = i;
+	found = TRUE;
+	continue;
+      }
+      if (found && !isFloat) {
+	length = i - start;
+	break;
+      }
+    }
+    if (found && (length < 0)) {
+      length = myLength - start;
+    }
+    if (startName && lengthName) {
+      set_int_variable (startName, start);
+      set_int_variable (lengthName, length);
+    } else {
+      gprint (GP_LOG, "match: %d %d\n", start, length);
+    }
+    return TRUE;
+  }
+
+  if (!strcasecmp(argv[2], "int")) {
+    int myLength = strlen(argv[1]);
+    int found = FALSE;
+    int start = -1;
+    int length = -1;
+    for (i = 0; i < myLength; i++) {
+      int isDigit = (argv[1][i] >= '0') && (argv[1][i] <= '9');
+      if (!found && isDigit) {
+	start = i;
+	found = TRUE;
+	continue;
+      }
+      if (found && !isDigit) {
+	length = i - start;
+	break;
+      }
+    }
+    if (found && (length < 0)) {
+      length = myLength - start;
+    }
+    if (startName && lengthName) {
+      set_int_variable (startName, start);
+      set_int_variable (lengthName, length);
+    } else {
+      gprint (GP_LOG, "match: %d %d\n", start, length);
+    }
+    return TRUE;
+  }
+
+  gprint (GP_ERR, "unknown character class %s\n", argv[2]);
+  return (TRUE);
+}
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/cmd.data/Makefile
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/cmd.data/Makefile	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/cmd.data/Makefile	(revision 37403)
@@ -98,4 +98,5 @@
 $(SRC)/point.$(ARCH).o		\
 $(SRC)/ps.$(ARCH).o		\
+$(SRC)/print_vectors.$(ARCH).o 	\
 $(SRC)/queuedelete.$(ARCH).o	\
 $(SRC)/queuedrop.$(ARCH).o	\
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/cmd.data/init.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/cmd.data/init.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/cmd.data/init.c	(revision 37403)
@@ -87,4 +87,5 @@
 int point            PROTO((int, char **));
 int ps               PROTO((int, char **));
+int print_vectors    PROTO((int, char **));
 int queuelist        PROTO((int, char **));
 int queueload        PROTO((int, char **));
@@ -250,4 +251,5 @@
   {1, "ppm",          jpeg,             "convert display graphic to PPM"},
   {1, "ps",           ps,               "convert display to PostScript"},
+  {1, "print_vectors", print_vectors,   "print a set of vectors"},
   {1, "queuedelete",  queuedelete,      "delete a queue"},
   {1, "queuedrop",    queuedrop,        "drop values from queue matching a key"},
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/cmd.data/print_vectors.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/cmd.data/print_vectors.c	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/cmd.data/print_vectors.c	(revision 37403)
@@ -0,0 +1,47 @@
+# include "data.h"
+
+int print_vectors (int argc, char **argv) {
+
+  Vector **vec;
+  int i, j;
+
+  if (argc < 2) {
+    gprint (GP_ERR, "USAGE: print_vectors (vector)[,vector,...]\n");
+    return (FALSE);
+  }
+
+  int Nvec = argc - 1;
+  ALLOCATE (vec, Vector *, Nvec);
+  for (i = 1; i < argc; i++) {
+    vec[i-1] = SelectVector (argv[i], OLDVECTOR, FALSE);
+    if (!vec[i-1]) {
+      gprint (GP_ERR, "unknown vector %s\n", argv[i]);
+      free (vec);
+      return FALSE;
+    }
+  }
+
+  int MaxLen = 0;
+  for (i = 0; i < Nvec; i++) {
+    MaxLen = MAX (MaxLen, vec[i][0].Nelements);
+  }
+
+  for (j = 0; j < MaxLen; j++) {
+    for (i = 0; i < Nvec; i++) {
+      if (j >= vec[i][0].Nelements) {
+	gprint (GP_LOG, "NaN ");
+      } else {
+	if (vec[i][0].type == OPIHI_FLT) {
+	  gprint (GP_LOG, "%f ", vec[i][0].elements.Flt[j]);
+	} else {
+	  gprint (GP_LOG, "%d ", vec[i][0].elements.Int[j]);
+	}
+      }
+    }
+    gprint (GP_LOG, "\n");
+  }
+  free (vec);
+
+  return (TRUE);
+}
+
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/cmd.data/read_vectors.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/cmd.data/read_vectors.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/cmd.data/read_vectors.c	(revision 37403)
@@ -3,4 +3,6 @@
 FILE *f = (FILE *) NULL;
 char filename[2048];
+
+void read_vectors_cleanup ();
 
 int datafile (int argc, char **argv) {
@@ -23,5 +25,11 @@
 // vector types
 enum {COLTYPE_NONE, COLTYPE_FLT, COLTYPE_INT, COLTYPE_TIME, COLTYPE_CHAR};
-static int FITS_TRANSPOSE;
+
+static int      Nvec     = 0;
+static Vector **vec      = NULL;
+static char   **listname = NULL;
+static int     *col      = NULL;
+static int     *coltype  = NULL;
+static char    *buffer   = NULL;
 
 int read_vectors (int argc, char **argv) {
@@ -29,16 +37,8 @@
   int TimeFormat;
   time_t TimeReference;
-  int i, j, Nskip, Narg, Nvec, *col, IsCSV, VERBOSE;
-  int Nbytes, Nstart, NELEM, Nelem, nread, *coltype;
+  int i, j, Nskip, Narg, IsCSV, VERBOSE;
+  int Nbytes, Nstart, NELEM, Nelem, nread;
   char *colstr, *c0, *c1, *extname;
-  Vector **vec;
-
-  char *buffer = NULL;
-
-  FITS_TRANSPOSE = FALSE;
-  if ((Narg = get_argument (argc, argv, "-transpose"))) {
-    remove_argument (Narg, &argc, argv);
-    FITS_TRANSPOSE = TRUE;
-  }
+  char varname[1024];  // used as a buffer for the names of string fields
 
   /* auto-sense table type */
@@ -88,7 +88,12 @@
 
   Nvec = (argc - 1) / 2;
+  ALLOCATE (listname, char *, Nvec);
   ALLOCATE (vec, Vector *, Nvec);
   ALLOCATE (col, int, Nvec);
   ALLOCATE (coltype, int, Nvec);
+  for (i = 0; i < Nvec; i++) {
+    listname[i] = NULL;
+    vec[i] = NULL;
+  }
 
   for (i = 0; i < Nvec; i++) {
@@ -115,9 +120,12 @@
     }
 
-    if ((vec[i] = SelectVector (argv[2*i + 1], ANYVECTOR, TRUE)) == NULL) {
-      gprint (GP_ERR, "USAGE: read name N name N ...\n");
-      free (vec);
-      free (col);
-      return (FALSE);    
+    if (coltype[i] == COLTYPE_CHAR) {
+      listname[i] = strcreate (argv[2*i + 1]);
+    } else {
+      if ((vec[i] = SelectVector (argv[2*i + 1], ANYVECTOR, TRUE)) == NULL) {
+	gprint (GP_ERR, "USAGE: read name N name N ...\n");
+	read_vectors_cleanup();
+	return (FALSE);    
+      }
     }
 
@@ -144,6 +152,5 @@
     bad_colname:
       gprint (GP_ERR, "USAGE: read name N name N ...\n");
-      free (vec);
-      free (col);
+      read_vectors_cleanup();
       return (FALSE);    
     }
@@ -153,9 +160,16 @@
   NELEM = 1000;
   for (i = 0; i < Nvec; i++) {
-    if ((coltype[i] == COLTYPE_INT) || (coltype[i] == COLTYPE_CHAR)) {
-      ResetVector (vec[i], OPIHI_INT, NELEM);
-    } else {
-      // note that COLTYPE_TIME is a type of float
-      ResetVector (vec[i], OPIHI_FLT, NELEM);
+    switch (coltype[i]) {
+      case COLTYPE_INT:
+	ResetVector (vec[i], OPIHI_INT, NELEM);
+	break;
+      case COLTYPE_FLT:
+      case COLTYPE_TIME:
+	// note that COLTYPE_TIME is a type of float
+	ResetVector (vec[i], OPIHI_FLT, NELEM);
+	break;
+      case COLTYPE_CHAR:
+      default:
+	break;
     }
   }
@@ -166,6 +180,5 @@
     if (scan_line_maxlen (f, buffer, 0x10000) == EOF) {
       gprint (GP_ERR, "problem reading file %s\n", filename);
-      free (vec);
-      free (col);
+      read_vectors_cleanup();
       return FALSE;
     }
@@ -213,5 +226,4 @@
       for (i = 0; i < Nvec; i++) {
 	int ivalue;
-	char cvalue;
 	double dvalue;
 	time_t tvalue;
@@ -224,7 +236,21 @@
 	    break;
 	  case COLTYPE_CHAR:
-	    readStatus = IsCSV ? charparse_csv (&cvalue, col[i], c0) : charparse (&cvalue, col[i], c0);
-	    vec[i][0].elements.Int[Nelem] = readStatus ? cvalue : 0;
-	    break;
+	    {
+	      // I need to get an isolated word in 'value' with the string value of this field 
+	      char *ptr = IsCSV ? ptrparse_csv (col[i], c0) : ptrparse (col[i], c0);
+	      char *value = NULL;
+	      if (IsCSV) {
+		char *end = parse_nextword_csv (ptr);
+		if (end) {
+		  value = end ? strncreate (ptr, end - ptr) : strcreate (ptr);
+		}
+	      } else {
+		value = thisword(ptr);
+	      }
+	      set_list_varname (varname, listname[i], Nelem, FALSE);
+	      set_str_variable (varname, value);
+	      free (value);
+	      break;
+	    }
 	  case COLTYPE_FLT:
 	    readStatus = IsCSV ? dparse_csv (&dvalue, col[i], c0) : dparse (&dvalue, col[i], c0);
@@ -256,8 +282,15 @@
 	NELEM += 1000;
 	for (i = 0; i < Nvec; i++) {
-	  if (coltype[i] == COLTYPE_INT) {
-	    REALLOCATE (vec[i][0].elements.Int, opihi_int, NELEM);
-	  } else {
-	    REALLOCATE (vec[i][0].elements.Flt, opihi_flt, NELEM);
+	  switch (coltype[i]) {
+	    case COLTYPE_INT:
+	      ResetVector (vec[i], OPIHI_INT, NELEM);
+	      break;
+	    case COLTYPE_FLT:
+	    case COLTYPE_TIME:
+	      ResetVector (vec[i], OPIHI_FLT, NELEM);
+	      break;
+	    case COLTYPE_CHAR:
+	    default:
+	      break;
 	  }
 	}
@@ -266,22 +299,28 @@
     }
   }
+  // set the final vector / list length
   for (i = 0; i < Nvec; i++) {
-    if (coltype[i] == COLTYPE_INT) {
-      REALLOCATE (vec[i][0].elements.Int, opihi_int, MAX (Nelem,1));
-    } else {
-      REALLOCATE (vec[i][0].elements.Flt, opihi_flt, MAX (Nelem,1));
-    }
-    vec[i][0].Nelements = Nelem;
-  }
-  
-  free (vec);
-  free (col);
-  if (buffer) free (buffer);
+    switch (coltype[i]) {
+      case COLTYPE_INT:
+	ResetVector (vec[i], OPIHI_INT, Nelem);
+	break;
+      case COLTYPE_FLT:
+      case COLTYPE_TIME:
+	ResetVector (vec[i], OPIHI_FLT, Nelem);
+	break;
+      case COLTYPE_CHAR:
+	sprintf (varname, "%s:n", listname[i]);
+	set_int_variable (varname, Nelem);
+	break;
+      default:
+	break;
+    }
+  }
+  read_vectors_cleanup();
   return (TRUE);
-
 }
 
-# define ESCAPE(MSG) { \
-  gprint (GP_ERR, "%s\n", MSG); \
+# define ESCAPE(...) {		\
+  gprint (GP_ERR, __VA_ARGS__); \
   if (CCDKeyword != NULL) free (CCDKeyword); \
   gfits_free_table  (&table); \
@@ -292,12 +331,19 @@
 
   off_t Nbytes;
-  int i, j, k, N, Nextend, Ny, Binary, vecType, padIfShort;
+  int i, j, N, Nextend, Ny, Binary, vecType, padIfShort;
   char type[16], ID[80], *CCDKeyword;
   FTable table;
   Header header;
   Vector **vec;
+  int FITS_TRANSPOSE;
 
   table.buffer = NULL;
   header.buffer = NULL;
+
+  FITS_TRANSPOSE = FALSE;
+  if ((N = get_argument (argc, argv, "-transpose"))) {
+    remove_argument (N, &argc, argv);
+    FITS_TRANSPOSE = TRUE;
+  }
 
   CCDKeyword = NULL;
@@ -328,7 +374,7 @@
   // }
 
-  if (argc < 2) ESCAPE ("USAGE: read -fits extension [-extnum] [-keyword key] name name ...");
-
-  if (f == NULL) ESCAPE ("file not found");
+  if (argc < 2) ESCAPE ("USAGE: read -fits extension [-extnum] [-keyword key] name name ...\n");
+
+  if (f == NULL) ESCAPE ("file not found\n");
   fseeko (f, 0LL, SEEK_SET);
   table.header = &header;
@@ -338,5 +384,5 @@
     // first extension is PHU, cannot be a table. 
     // Nextend counts from 0 for first extension
-    if (!gfits_load_header (f, &header)) ESCAPE ("error reading primary header for file");
+    if (!gfits_load_header (f, &header)) ESCAPE ("error reading primary header for file\n");
     Nbytes = gfits_data_size (&header);
     fseeko (f, Nbytes, SEEK_CUR);
@@ -344,5 +390,5 @@
 
     for (i = 0; i < Nextend; i++) {
-      if (!gfits_load_header (f, &header)) ESCAPE ("extension not found");
+      if (!gfits_load_header (f, &header)) ESCAPE ("extension %d not found\n", i);
       Nbytes = gfits_data_size (&header);
       /* skip the prior data buffers */
@@ -350,6 +396,6 @@
       gfits_free_header (&header);
     }
-    if (!gfits_load_header (f, &header)) ESCAPE ("error reading header for extension");
-    if (!gfits_fread_ftable_data (f, &table, padIfShort)) ESCAPE ("error reading table for extension");
+    if (!gfits_load_header (f, &header)) ESCAPE ("error reading header for extension %d\n", Nextend);
+    if (!gfits_fread_ftable_data (f, &table, padIfShort)) ESCAPE ("error reading table for extension %d\n", Nextend);
 
   } else {
@@ -382,5 +428,5 @@
 	continue;
       }
-      if (!gfits_fread_ftable_data (f, &table, padIfShort)) ESCAPE ("error reading table for extension");
+      if (!gfits_fread_ftable_data (f, &table, padIfShort)) ESCAPE ("error reading table for extension\n");
       break;
     }
@@ -391,5 +437,5 @@
   gfits_scan (&header, "XTENSION", "%s", 1, type);
   if (strcmp (type, "BINTABLE") && strcmp (type, "TABLE")) {
-    ESCAPE ("specified extension is not a table\n");
+    ESCAPE ("specified extension %s is not a table\n", type);
   }
   Binary = !strcmp (type, "BINTABLE");
@@ -418,4 +464,26 @@
 	
     if (!FITS_TRANSPOSE) {
+      // read string column into a list rather than a vector
+      if (!strcmp (type, "char")) {
+	char *fieldName = argv[i];
+	char *Ptr = data;
+	char varname[1024];  // used as a buffer for the names of string fields
+	for (j = 0; j < Ny; j++) {
+	  set_list_varname (varname, fieldName, j, FALSE);
+	  char *value = strncreate (&Ptr[j*Nval], Nval);
+	  // replace instances of $ with _
+	  char *p = strchr (value, '$');
+	  while (p) { 
+	    *p = '_';
+	    p = strchr (p, '$');
+	  }
+	  set_str_variable (varname, value);
+	  free (value);
+	}
+	sprintf (varname, "%s:n", fieldName);
+	set_int_variable (varname, Ny);
+	continue;
+      }
+
       // define the multifield vector names (Nval vectors x Ny elements)
       ALLOCATE (vec, Vector *, Nval);
@@ -429,52 +497,6 @@
       }
 
-      if (!strcmp (type, "char")) {
-	char *Ptr = data;
-	for (j = 0; j < Ny; j++) {
-	  for (k = 0; k < Nval; k++, Ptr++) {
-	    vec[k][0].elements.Int[j] = *Ptr;
-	  }
-	}
-      }
-      if (!strcmp (type, "short")) {
-	short *Ptr = data;
-	for (j = 0; j < Ny; j++) {
-	  for (k = 0; k < Nval; k++, Ptr++) {
-	    vec[k][0].elements.Int[j] = *Ptr;
-	  }
-	}
-      }
-      if (!strcmp (type, "int")) {
-	int *Ptr = data;
-	for (j = 0; j < Ny; j++) {
-	  for (k = 0; k < Nval; k++, Ptr++) {
-	    vec[k][0].elements.Int[j] = *Ptr;
-	  }
-	}
-      }
-      if (!strcmp (type, "int64_t")) {
-	int64_t *Ptr = data;
-	for (j = 0; j < Ny; j++) {
-	  for (k = 0; k < Nval; k++, Ptr++) {
-	    vec[k][0].elements.Int[j] = *Ptr;
-	  }
-	}
-      }
-      if (!strcmp (type, "float")) {
-	float *Ptr = data;
-	for (j = 0; j < Ny; j++) {
-	  for (k = 0; k < Nval; k++, Ptr++) {
-	    vec[k][0].elements.Flt[j] = *Ptr;
-	  }
-	}
-      }
-      if (!strcmp (type, "double")) {
-	double *Ptr = data;
-	for (j = 0; j < Ny; j++) {
-	  for (k = 0; k < Nval; k++, Ptr++) {
-	    vec[k][0].elements.Flt[j] = *Ptr;
-	  }
-	}
-      }
+      if (!VectorAssignData (vec, type, data, Ny, Nval)) ESCAPE ("bad column type %s", type);
+
     } else {
       // define the multifield vector names (Ny vectors x Nval elements)
@@ -489,52 +511,5 @@
       }
 
-      if (!strcmp (type, "char")) {
-	char *Ptr = data;
-	for (j = 0; j < Ny; j++) {
-	  for (k = 0; k < Nval; k++, Ptr++) {
-	    vec[j][0].elements.Int[k] = *Ptr;
-	  }
-	}
-      }
-      if (!strcmp (type, "short")) {
-	short *Ptr = data;
-	for (j = 0; j < Ny; j++) {
-	  for (k = 0; k < Nval; k++, Ptr++) {
-	    vec[j][0].elements.Int[k] = *Ptr;
-	  }
-	}
-      }
-      if (!strcmp (type, "int")) {
-	int *Ptr = data;
-	for (j = 0; j < Ny; j++) {
-	  for (k = 0; k < Nval; k++, Ptr++) {
-	    vec[j][0].elements.Int[k] = *Ptr;
-	  }
-	}
-      }
-      if (!strcmp (type, "int64_t")) {
-	int64_t *Ptr = data;
-	for (j = 0; j < Ny; j++) {
-	  for (k = 0; k < Nval; k++, Ptr++) {
-	    vec[j][0].elements.Int[k] = *Ptr;
-	  }
-	}
-      }
-      if (!strcmp (type, "float")) {
-	float *Ptr = data;
-	for (j = 0; j < Ny; j++) {
-	  for (k = 0; k < Nval; k++, Ptr++) {
-	    vec[j][0].elements.Flt[k] = *Ptr;
-	  }
-	}
-      }
-      if (!strcmp (type, "double")) {
-	double *Ptr = data;
-	for (j = 0; j < Ny; j++) {
-	  for (k = 0; k < Nval; k++, Ptr++) {
-	    vec[j][0].elements.Flt[k] = *Ptr;
-	  }
-	}
-      }
+      if (!VectorAssignDataTranspose (vec, type, data, Ny, Nval)) ESCAPE ("bad column type %s", type);
     }
     free (data);
@@ -546,2 +521,18 @@
   return (TRUE);
 }
+
+void read_vectors_cleanup () {
+
+  int i;
+
+  if (col) free (col);
+  if (coltype) free (coltype);
+  if (buffer) free (buffer);
+  if (listname) {
+    for (i = 0; i < Nvec; i++) {
+      if (listname[i]) free (listname[i]);
+    }
+    free (listname);
+  }
+  if (vec) free (vec);
+}
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/Makefile
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/Makefile	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/Makefile	(revision 37403)
@@ -25,6 +25,19 @@
 $(SRC)/dvo_host_utils.$(ARCH).o		\
 $(SRC)/region_list.$(ARCH).o		\
-$(SRC)/find_matches.$(ARCH).o		\
-$(SRC)/photometry.$(ARCH).o             
+$(SRC)/photcode_ops.$(ARCH).o	  	\
+$(SRC)/find_matches.$(ARCH).o           
+
+# $(SRC)/photometry.$(ARCH).o             
+
+broken = \
+$(SRC)/calextract.$(ARCH).o      	\
+$(SRC)/calmextract.$(ARCH).o     	\
+$(SRC)/ccd.$(ARCH).o             	\
+$(SRC)/cmd.$(ARCH).o             	\
+$(SRC)/dmagaves.$(ARCH).o	  	\
+$(SRC)/dmagmeas.$(ARCH).o	  	\
+$(SRC)/dmags.$(ARCH).o		  	\
+$(SRC)/ddmags.$(ARCH).o	  	\
+$(SRC)/fitcolors.$(ARCH).o
 
 cmds = \
@@ -32,21 +45,13 @@
 $(SRC)/avmatch.$(ARCH).o	  	\
 $(SRC)/badimages.$(ARCH).o	  	\
-$(SRC)/calextract.$(ARCH).o      	\
-$(SRC)/calmextract.$(ARCH).o     	\
 $(SRC)/catdir.$(ARCH).o             	\
-$(SRC)/ccd.$(ARCH).o             	\
 $(SRC)/cmatch.$(ARCH).o	  	\
-$(SRC)/cmd.$(ARCH).o             	\
 $(SRC)/cmpload.$(ARCH).o	  	\
 $(SRC)/cmpread.$(ARCH).o	  	\
 $(SRC)/coordimage.$(ARCH).o	  	\
-$(SRC)/ddmags.$(ARCH).o	  	\
+$(SRC)/coordmosaic.$(ARCH).o	  	\
 $(SRC)/detrend.$(ARCH).o	  	\
-$(SRC)/dmagaves.$(ARCH).o	  	\
-$(SRC)/dmagmeas.$(ARCH).o	  	\
-$(SRC)/dmags.$(ARCH).o		  	\
 $(SRC)/dmt.$(ARCH).o		  	\
 $(SRC)/elixir.$(ARCH).o                \
-$(SRC)/fitcolors.$(ARCH).o             \
 $(SRC)/fitsed.$(ARCH).o                \
 $(SRC)/gcat.$(ARCH).o		  	\
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/avextract.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/avextract.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/avextract.c	(revision 37403)
@@ -166,6 +166,5 @@
   needMeasures = FALSE;
   for (i = 0; !needMeasures && (i < Nfields); i++) {
-    if (fields[i].magMode == MAG_NONE) continue;
-    if (fields[i].photcode == NULL) continue; // assert this?
+    if (fields[i].photcode == NULL) continue; // non-measure fields do not have a photcode
     if (fields[i].photcode[0].type == PHOT_REF) needMeasures = TRUE;
     if (fields[i].photcode[0].type == PHOT_DEP) needMeasures = TRUE;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/avmatch.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/avmatch.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/avmatch.c	(revision 37403)
@@ -152,5 +152,4 @@
   int needMeasures = FALSE;
   for (i = 0; !needMeasures && (i < Nfields); i++) {
-    if (fields[i].magMode == MAG_NONE) continue;
     if (fields[i].photcode == NULL) continue; // assert this?
     if (fields[i].photcode[0].type == PHOT_REF) needMeasures = TRUE;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/coordmosaic.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/coordmosaic.c	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/coordmosaic.c	(revision 37403)
@@ -0,0 +1,524 @@
+# include "dvoshell.h"
+
+int coordmosaic (int argc, char **argv) {
+
+  int N, ix, iy;
+  off_t i, j, nt, Nimage, *subset, Nsubset;
+  time_t tzero;
+  double trange;
+  Buffer *bufX, *bufY;
+  SkyRegionSelection *selection;
+  Image *image;
+
+  if (!InitPhotcodes ()) return (FALSE);
+
+  // parse skyregion options
+  if ((selection = SetRegionSelection (&argc, argv)) == NULL) {
+    gprint (GP_ERR, "invalid sky region selection\n");
+    return FALSE;
+  }
+
+  int TimeSelect = FALSE;
+  if ((N = get_argument (argc, argv, "-time"))) {
+    remove_argument (N, &argc, argv);
+    if (!ohana_str_to_time (argv[N], &tzero)) { 
+      gprint (GP_ERR, "syntax error\n");
+      return (FALSE);
+    }
+    remove_argument (N, &argc, argv);
+    if (!ohana_str_to_dtime (argv[N], &trange)) { 
+      gprint (GP_ERR, "syntax error\n");
+      return (FALSE);
+    }
+    remove_argument (N, &argc, argv);
+    TimeSelect = TRUE;
+    gprint (GP_ERR, "plotting in range %ds - %ds (%f seconds)\n", (int)tzero, (int)(tzero + trange), trange);
+  }
+
+  /* 
+  PhotCode *Photcode = NULL;
+  if ((N = get_argument (argc, argv, "-photcode"))) {
+    remove_argument (N, &argc, argv);
+    Photcode = GetPhotcodebyName (argv[N]);
+    if (Photcode == NULL) {
+      gprint (GP_ERR, "photcode not found in photcode table\n");
+      return (FALSE);
+    }
+    remove_argument (N, &argc, argv);
+  }
+  if ((N = get_argument (argc, argv, "-Nphotcode"))) {
+    remove_argument (N, &argc, argv);
+    Photcode = GetPhotcodebyCode (atoi(argv[N]));
+    if (Photcode == NULL) {
+      gprint (GP_ERR, "photcode not found in photcode table\n");
+      return (FALSE);
+    }
+    remove_argument (N, &argc, argv);
+  }
+  */
+
+  char *Name = NULL;
+  if ((N = get_argument (argc, argv, "-name"))) {
+    remove_argument (N, &argc, argv);
+    Name = strcreate (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  /* 
+  int chipID = -1;
+  if ((N = get_argument (argc, argv, "-chip"))) {
+    remove_argument (N, &argc, argv);
+    chipID = atoi (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+  */
+
+  // save the image plate scales
+  Vector *cd1v = NULL, *cd2v = NULL;
+  if ((cd1v = SelectVector ("cd1", ANYVECTOR, TRUE)) == NULL) return (FALSE);
+  if ((cd2v = SelectVector ("cd2", ANYVECTOR, TRUE)) == NULL) return (FALSE);
+
+  if (argc != 5) goto syntax;
+
+  if ((bufX = SelectBuffer (argv[1], ANYBUFFER, TRUE)) == NULL) goto escape;
+  if ((bufY = SelectBuffer (argv[2], ANYBUFFER, TRUE)) == NULL) goto escape;
+  int Nx = atoi (argv[3]);
+  int Ny = atoi (argv[4]);
+
+  gfits_free_matrix (&bufX[0].matrix);
+  gfits_free_header (&bufX[0].header);
+  CreateBuffer (bufX, Nx, Ny, -32, 0.0, 1.0); // initialized to 0.0 here
+  strcpy (bufX[0].file, "(empty)");
+
+  gfits_free_matrix (&bufY[0].matrix);
+  gfits_free_header (&bufY[0].header);
+  CreateBuffer (bufY, Nx, Ny, -32, 0.0, 1.0); // initialized to 0.0 here
+  strcpy (bufY[0].file, "(empty)");
+
+  if ((image = LoadImagesDVO (&Nimage)) == NULL) return (FALSE);
+  image_subset (image, Nimage, &subset, &Nsubset, selection, tzero, trange, TimeSelect);
+
+  float *vX = (float *) bufX[0].matrix.buffer;
+  float *vY = (float *) bufY[0].matrix.buffer;
+
+  int Nsum = 0;
+  int NSUM = 1000;
+  opihi_flt *cd1 = NULL;
+  opihi_flt *cd2 = NULL;
+  ALLOCATE (cd1, opihi_flt, NSUM);
+  ALLOCATE (cd2, opihi_flt, NSUM);
+
+  int NX = 0;
+  int NY = 0;
+  float dX = NAN;
+  float dY = NAN;
+
+  // only select the DIS (mosaic) images
+  for (j = 0; j < Nsubset; j++) {
+    i = subset[j];
+    if (Name && (strstr (image[i].name, Name) == (char *) NULL)) continue;
+
+    if (strcmp (&image[i].coords.ctype[4], "-DIS")) continue;
+
+    if (!isfinite(dX)) {
+      NX = image[i].NX;
+      NY = image[i].NY;
+      dX = NX / (float) Nx;
+      dY = NY / (float) Ny;
+    } else {
+      if ((NX != image[i].NX) || (NY != image[i].NY)) {
+	// fprintf (stderr, "mosaic size mismatch? %d,%d vs %d,%d\n", NX, NY, image[i].NX, image[i].NY);
+      }
+    }
+
+    // DIS image pixels range fom -0.5*NX to +0.5*NX
+    // output pixels range from 0 to Nx
+    // dX = NX / Nx
+    // fx = ix * dX - 0.5*NX
+
+    Coords coords = image[i].coords;
+    // coords.Npolyterms = 0;
+
+    // the coords have an arbitrary rotation.  I want derotate:
+    double T = 1.0 / (image[i].coords.pc1_1*image[i].coords.pc2_2 - image[i].coords.pc2_1*image[i].coords.pc1_2);
+    double A10 = +image[i].coords.pc2_2 * T;
+    double A01 = -image[i].coords.pc1_2 * T;
+    double B10 = -image[i].coords.pc2_1 * T;
+    double B01 = +image[i].coords.pc1_1 * T;
+
+    coords.pc1_1 = image[i].coords.pc1_1 * A10 + image[i].coords.pc2_1 * A01;
+    coords.pc1_2 = image[i].coords.pc1_2 * A10 + image[i].coords.pc2_2 * A01;
+    coords.pc2_1 = image[i].coords.pc1_1 * B10 + image[i].coords.pc2_1 * B01;
+    coords.pc2_2 = image[i].coords.pc1_2 * B10 + image[i].coords.pc2_2 * B01;
+
+    if (coords.Npolyterms > 1) {
+      for (nt = 0; nt < 3; nt++) {
+	coords.polyterms[nt][0] = image[i].coords.polyterms[nt][0] * A10 + image[i].coords.polyterms[nt][1] * A01;
+	coords.polyterms[nt][1] = image[i].coords.polyterms[nt][0] * B10 + image[i].coords.polyterms[nt][1] * B01;
+      }
+    }
+
+    if (coords.Npolyterms > 2) {
+      for (nt = 3; nt < 7; nt++) {
+	coords.polyterms[nt][0] = image[i].coords.polyterms[nt][0] * A10 + image[i].coords.polyterms[nt][1] * A01;
+	coords.polyterms[nt][1] = image[i].coords.polyterms[nt][0] * B10 + image[i].coords.polyterms[nt][1] * B01;
+      }
+    }
+
+    Coords linear = coords;
+    linear.Npolyterms = 0;
+
+    for (iy = 0; iy < Ny; iy++) {
+      double fy = iy * dY - 0.5*NY; // coordinate in full image
+      for (ix = 0; ix < Nx; ix++) {
+	double fx = ix * dX - 0.5*NX; // coordinate in full image
+
+	double Lo, Lm; //, dL;
+	double Mo, Mm; //, dM;
+
+	XY_to_LM (&Lo, &Mo, fx, fy, &coords);
+	XY_to_LM (&Lm, &Mm, fx, fy, &linear);
+	// dL = Lo - Lm;
+	// dM = Mo - Mm;
+
+	// vX[ix + iy*Nx] += dL;
+	// vY[ix + iy*Nx] += dM;
+	vX[ix + iy*Nx] += Lo;
+	vY[ix + iy*Nx] += Mo;
+      }
+    }
+
+    cd1[Nsum] = image[i].coords.cdelt1;
+    cd2[Nsum] = image[i].coords.cdelt2;
+    Nsum ++;
+    if (Nsum == NSUM) {
+      NSUM += 1000;
+      REALLOCATE (cd1, opihi_flt, NSUM);
+      REALLOCATE (cd2, opihi_flt, NSUM);
+    }
+  }
+
+  free (cd1v->elements.Flt); cd1v->elements.Flt = cd1; cd1v->Nelements = Nsum;
+  free (cd2v->elements.Flt); cd2v->elements.Flt = cd2; cd2v->Nelements = Nsum;
+
+  for (iy = 0; iy < Ny; iy++) {
+    for (ix = 0; ix < Nx; ix++) {
+      vX[ix + iy*Nx] /= (float) Nsum;
+      vY[ix + iy*Nx] /= (float) Nsum;
+    }
+  }
+
+  gfits_modify (&bufX->header, "MOS_NX", "%d", 1, NX);
+  gfits_modify (&bufX->header, "MOS_NY", "%d", 1, NY);
+  gfits_modify (&bufX->header, "MOS_DX", "%f", 1, dX);
+  gfits_modify (&bufX->header, "MOS_DY", "%f", 1, dY);
+  gfits_modify (&bufX->header, "MOS_NSUM", "%d", 1, Nsum);
+
+  fprintf (stderr, "Nsum: %d\n", Nsum);
+  return TRUE;
+
+ syntax:
+  gprint (GP_ERR, "USAGE: coordmosaic buffX buffY Nx Ny\n");
+ escape:
+  return (FALSE);
+}
+
+# define ESCAPE(MSG) { \
+    if (src) fclose (src); \
+    if (tgt) fclose (tgt); \
+    fprintf (stderr, "%s\n", MSG); return FALSE; }
+
+# define GET_COLUMN(OUT,NAME,TYPE) \
+  TYPE *OUT = gfits_get_bintable_column_data (&header, &table, NAME, type, &Nrow, &Ncol); \
+  myAssert (!strcmp(type, #TYPE), "wrong column type");
+
+int psastro_model (int argc, char **argv) {
+
+  // I need to write out the full psastro input model based on my new fits
+
+  // astrometry model consists of an empty PHU + 4 extensions:
+  // CHIPS : 
+  // FP
+  // TP
+  // SKY
+
+  int Ncol;
+  off_t Nrow, Nout;
+  char type[16];
+
+  FTable table;
+  Header header;
+  table.header = &header;
+
+  FILE *src = NULL, *tgt = NULL;
+
+  if (argc != 3) {
+    fprintf (stderr, "USAGE: psastro_model (src) (tgt)\n");
+    return FALSE;
+  }
+
+  // I am going to read in the tables from one file and save them (with updates) in another
+  src = fopen (argv[1], "r");
+  if (!src) ESCAPE ("failed to open source file");
+
+  tgt = fopen (argv[2], "w");
+  if (!tgt) ESCAPE ("failed to open output file");
+
+  // read the PHU 
+  if (!gfits_load_header (src, &header)) ESCAPE ("error loading PHU");
+  int Nbytes = gfits_data_size (&header);
+  if (Nbytes) ESCAPE ("non-zero PHU matrix??");
+
+  // save the PHU
+  if (!gfits_save_header (tgt, &header)) ESCAPE ("error saving PHU");
+  gfits_free_header (&header);
+
+  { 
+    // read the CHIPS 
+    if (!gfits_load_header (src, &header)) ESCAPE ("error loading CHIPS header");
+    if (!gfits_fread_ftable_data (src, &table, FALSE)) ESCAPE ("error reading table for CHIPS");
+  
+    // these set the value of Nrow
+    GET_COLUMN (SEGMENT , "SEGMENT", char ); int Nsegment = Ncol;
+    GET_COLUMN (PARENT  , "PARENT" , char ); 
+    GET_COLUMN (MINX    , "MINX"   , float);
+    GET_COLUMN (MAXX    , "MAXX"   , float);
+    GET_COLUMN (MINY    , "MINY"   , float);
+    GET_COLUMN (MAXY    , "MAXY"   , float);
+    GET_COLUMN (XORDER  , "XORDER" , int  );
+    GET_COLUMN (YORDER  , "YORDER" , int  );
+    GET_COLUMN (NXORDER , "NXORDER", int  );
+    GET_COLUMN (NYORDER , "NYORDER", int  );
+    GET_COLUMN (POLY_X  , "POLY_X" , float);
+    GET_COLUMN (POLY_Y  , "POLY_Y" , float);
+    GET_COLUMN (ERROR_X , "ERROR_X", float);
+    GET_COLUMN (ERROR_Y , "ERROR_Y", float);
+    GET_COLUMN (MASK_X  , "MASK_X" , char  );
+    GET_COLUMN (MASK_Y  , "MASK_Y" , char  );
+
+    // I am keeping the same number of entries, but changing the values of
+    // POLY_X, POLY_Y
+    int i;
+    for (i = 0; i < Nrow; i++) {
+      // validate that NX, NY orders are 1
+      assert (NXORDER[i] == 1);
+      assert (NYORDER[i] == 1);
+
+      char name[16], segment[16];
+
+      int found, xmask, ymask;
+      
+      memset (segment, 0, 16); memcpy  (segment, &SEGMENT[i*Nsegment], 4);
+      snprintf (name, 16, "%s_L_CX%dY%d", segment, XORDER[i], YORDER[i]);
+      double xvalue = get_double_variable (name, &found);
+      xmask = !found;
+      
+      memset (segment, 0, 16); memcpy  (segment, &SEGMENT[i*Nsegment], 4);
+      snprintf (name, 16, "%s_M_CX%dY%d", segment, XORDER[i], YORDER[i]);
+      double yvalue = get_double_variable (name, &found);
+      ymask = !found;
+
+      POLY_X[i] = xvalue;
+      POLY_Y[i] = yvalue;
+      ERROR_X[i] = 0.0;
+      ERROR_Y[i] = 0.0;
+      MASK_X[i] = xmask;
+      MASK_Y[i] = ymask;
+    }
+
+    // reset the table size to 0 rows -- this forces the data array to be reallocate by gfits_set_bintable_column
+    gfits_modify (&header, "NAXIS2", "%d", 1, 0); 
+
+    gfits_set_bintable_column (&header, &table, "SEGMENT",  SEGMENT , Nrow);
+    gfits_set_bintable_column (&header, &table, "PARENT" ,  PARENT  , Nrow);
+    gfits_set_bintable_column (&header, &table, "MINX"   ,  MINX    , Nrow);
+    gfits_set_bintable_column (&header, &table, "MAXX"   ,  MAXX    , Nrow);
+    gfits_set_bintable_column (&header, &table, "MINY"   ,  MINY    , Nrow);
+    gfits_set_bintable_column (&header, &table, "MAXY"   ,  MAXY    , Nrow);
+    gfits_set_bintable_column (&header, &table, "XORDER" ,  XORDER  , Nrow);
+    gfits_set_bintable_column (&header, &table, "YORDER" ,  YORDER  , Nrow);
+    gfits_set_bintable_column (&header, &table, "NXORDER",  NXORDER , Nrow);
+    gfits_set_bintable_column (&header, &table, "NYORDER",  NYORDER , Nrow);
+    gfits_set_bintable_column (&header, &table, "POLY_X" ,  POLY_X  , Nrow);
+    gfits_set_bintable_column (&header, &table, "POLY_Y" ,  POLY_Y  , Nrow);
+    gfits_set_bintable_column (&header, &table, "ERROR_X",  ERROR_X , Nrow);
+    gfits_set_bintable_column (&header, &table, "ERROR_Y",  ERROR_Y , Nrow);
+    gfits_set_bintable_column (&header, &table, "MASK_X" ,  MASK_X  , Nrow);
+    gfits_set_bintable_column (&header, &table, "MASK_Y" ,  MASK_Y  , Nrow);
+
+    free (SEGMENT );
+    free (PARENT  );
+    free (MINX    );
+    free (MAXX    );
+    free (MINY    );
+    free (MAXY    );
+    free (XORDER  );
+    free (YORDER  );
+    free (NXORDER );
+    free (NYORDER );
+    free (POLY_X  );
+    free (POLY_Y  );
+    free (ERROR_X );
+    free (ERROR_Y );
+    free (MASK_X  );
+    free (MASK_Y  );
+
+    // save the CHIPS 
+    gfits_fwrite_Theader (tgt, &header);
+    gfits_fwrite_table  (tgt, &table);
+    gfits_free_header (&header);
+    gfits_free_table (&table);
+  }  
+
+  { 
+    // read the FP
+    if (!gfits_load_header (src, &header)) ESCAPE ("error loading FP header");
+    if (!gfits_fread_ftable_data (src, &table, FALSE)) ESCAPE ("error reading table for FP");
+  
+    // these set the value of Nrow
+    GET_COLUMN (SEGMENT , "SEGMENT", char ); int Nsegment = Ncol;
+    GET_COLUMN (PARENT  , "PARENT" , char ); int Nparent = Ncol;
+    GET_COLUMN (MINX    , "MINX"   , float);
+    GET_COLUMN (MAXX    , "MAXX"   , float);
+    GET_COLUMN (MINY    , "MINY"   , float);
+    GET_COLUMN (MAXY    , "MAXY"   , float);
+    GET_COLUMN (XORDER  , "XORDER" , int  );
+    GET_COLUMN (YORDER  , "YORDER" , int  );
+    GET_COLUMN (NXORDER , "NXORDER", int  );
+    GET_COLUMN (NYORDER , "NYORDER", int  );
+    GET_COLUMN (POLY_X  , "POLY_X" , float);
+    GET_COLUMN (POLY_Y  , "POLY_Y" , float);
+    GET_COLUMN (ERROR_X , "ERROR_X", float);
+    GET_COLUMN (ERROR_Y , "ERROR_Y", float);
+    GET_COLUMN (MASK_X  , "MASK_X" , char  );
+    GET_COLUMN (MASK_Y  , "MASK_Y" , char  );
+
+    Nout = 16;
+
+    REALLOCATE (SEGMENT , char , Nout*Nsegment);
+    REALLOCATE (PARENT  , char , Nout*Nparent);
+    REALLOCATE (MINX    , float, Nout);
+    REALLOCATE (MAXX    , float, Nout);
+    REALLOCATE (MINY    , float, Nout);
+    REALLOCATE (MAXY    , float, Nout);
+    REALLOCATE (XORDER  , int  , Nout);
+    REALLOCATE (YORDER  , int  , Nout);
+    REALLOCATE (NXORDER , int  , Nout);
+    REALLOCATE (NYORDER , int  , Nout);
+    REALLOCATE (POLY_X  , float, Nout);
+    REALLOCATE (POLY_Y  , float, Nout);
+    REALLOCATE (ERROR_X , float, Nout);
+    REALLOCATE (ERROR_Y , float, Nout);
+    REALLOCATE (MASK_X  , char , Nout);
+    REALLOCATE (MASK_Y  , char , Nout);
+
+    float minX = MINX[0];
+    float maxX = MAXX[0];
+    float minY = MINY[0];
+    float maxY = MAXY[0];
+
+    int ix, iy, nrow;
+    nrow = 0;
+    for (ix = 0; ix < 4; ix++) {
+      for (iy = 0; iy < 4; iy++) {
+	memcpy (&SEGMENT[nrow*Nsegment], "FOCAL_PLANE", strlen("FOCAL_PLANE"));
+	memcpy (&PARENT[nrow*Nparent], "TANGENT_PLANE", strlen("TANGENT_PLANE"));
+	MINX[nrow] = minX;
+	MAXX[nrow] = maxX;
+	MINY[nrow] = minY;
+	MAXY[nrow] = maxY;
+	XORDER[nrow] = ix;
+	YORDER[nrow] = iy;
+	NXORDER[nrow] = 3;
+	NYORDER[nrow] = 3;
+
+	char name[16];
+
+	int found, xmask, ymask;
+	snprintf (name, 16, "L_X%dY%d", ix, iy);
+	double xvalue = get_double_variable (name, &found);
+	xmask = !found;
+
+	snprintf (name, 16, "M_X%dY%d", ix, iy);
+	double yvalue = get_double_variable (name, &found);
+	ymask = !found;
+
+	POLY_X[nrow] = xvalue;
+	POLY_Y[nrow] = yvalue;
+	ERROR_X[nrow] = 0.0;
+	ERROR_Y[nrow] = 0.0;
+	MASK_X[nrow] = xmask;
+	MASK_Y[nrow] = ymask;
+	nrow ++;
+      }
+    }
+
+    // reset the table size to 0 rows -- this forces the data array to be reallocate by gfits_set_bintable_column
+    gfits_modify (&header, "NAXIS2", "%d", 1, 0); 
+
+    gfits_set_bintable_column (&header, &table, "SEGMENT",  SEGMENT , Nout);
+    gfits_set_bintable_column (&header, &table, "PARENT" ,  PARENT  , Nout);
+    gfits_set_bintable_column (&header, &table, "MINX"   ,  MINX    , Nout);
+    gfits_set_bintable_column (&header, &table, "MAXX"   ,  MAXX    , Nout);
+    gfits_set_bintable_column (&header, &table, "MINY"   ,  MINY    , Nout);
+    gfits_set_bintable_column (&header, &table, "MAXY"   ,  MAXY    , Nout);
+    gfits_set_bintable_column (&header, &table, "XORDER" ,  XORDER  , Nout);
+    gfits_set_bintable_column (&header, &table, "YORDER" ,  YORDER  , Nout);
+    gfits_set_bintable_column (&header, &table, "NXORDER",  NXORDER , Nout);
+    gfits_set_bintable_column (&header, &table, "NYORDER",  NYORDER , Nout);
+    gfits_set_bintable_column (&header, &table, "POLY_X" ,  POLY_X  , Nout);
+    gfits_set_bintable_column (&header, &table, "POLY_Y" ,  POLY_Y  , Nout);
+    gfits_set_bintable_column (&header, &table, "ERROR_X",  ERROR_X , Nout);
+    gfits_set_bintable_column (&header, &table, "ERROR_Y",  ERROR_Y , Nout);
+    gfits_set_bintable_column (&header, &table, "MASK_X" ,  MASK_X  , Nout);
+    gfits_set_bintable_column (&header, &table, "MASK_Y" ,  MASK_Y  , Nout);
+
+    free (SEGMENT );
+    free (PARENT  );
+    free (MINX    );
+    free (MAXX    );
+    free (MINY    );
+    free (MAXY    );
+    free (XORDER  );
+    free (YORDER  );
+    free (NXORDER );
+    free (NYORDER );
+    free (POLY_X  );
+    free (POLY_Y  );
+    free (ERROR_X );
+    free (ERROR_Y );
+    free (MASK_X  );
+    free (MASK_Y  );
+
+    // save the FP 
+    gfits_fwrite_Theader (tgt, &header);
+    gfits_fwrite_table  (tgt, &table);
+    gfits_free_header (&header);
+    gfits_free_table (&table);
+  }
+  
+  // read the TP
+  if (!gfits_load_header (src, &header)) ESCAPE ("error loading TP header");
+  if (!gfits_fread_ftable_data (src, &table, FALSE)) ESCAPE ("error reading table for TP");
+  
+  // save the TP 
+  gfits_fwrite_Theader (tgt, &header);
+  gfits_fwrite_table  (tgt, &table);
+  gfits_free_header (&header);
+  gfits_free_table (&table);
+  
+  // read the SKY
+  if (!gfits_load_header (src, &header)) ESCAPE ("error loading SKY header");
+  if (!gfits_fread_ftable_data (src, &table, FALSE)) ESCAPE ("error reading table for SKY");
+  
+  // save the SKY 
+  gfits_fwrite_Theader (tgt, &header);
+  gfits_fwrite_table  (tgt, &table);
+  gfits_free_header (&header);
+  gfits_free_table (&table);
+  
+  fclose (tgt);
+  fclose (src);
+
+  return TRUE;
+}
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/fitsed.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/fitsed.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/fitsed.c	(revision 37403)
@@ -83,5 +83,5 @@
   /* interpret command-line options */
   if ((selection = SetRegionSelection (&argc, argv)) == NULL) goto escape;
-  if (!SetPhotSelections (&argc, argv, 4)) goto usage;
+  // if (!SetPhotSelections (&argc, argv, 4)) goto usage;
 
   PLOT = FALSE;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/gstar.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/gstar.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/gstar.c	(revision 37403)
@@ -15,6 +15,6 @@
   GSTAR_UCDIST,
   GSTAR_AVE_AP_MAG,
-  GSTAR_AVE_MAG_20,
-  GSTAR_AVE_MAG_80,
+  GSTAR_AVE_MAG_MIN,
+  GSTAR_AVE_MAG_MAX,
   GSTAR_AVE_KRON_MAG,
   GSTAR_AVE_KRON_MAG_ERR,
@@ -23,4 +23,24 @@
   GSTAR_STACK_FLUX_KRON,
   GSTAR_STACK_FLUX_KRON_ERR,
+  GSTAR_STACK_FLUX_APER,
+  GSTAR_STACK_FLUX_APER_ERR,
+  GSTAR_WARP_FLUX_PSF,
+  GSTAR_WARP_FLUX_PSF_ERR,
+  GSTAR_WARP_FLUX_KRON,
+  GSTAR_WARP_FLUX_KRON_ERR,
+  GSTAR_WARP_FLUX_APER,
+  GSTAR_WARP_FLUX_APER_ERR,
+  GSTAR_STACK_MAG_PSF,
+  GSTAR_STACK_MAG_PSF_ERR,
+  GSTAR_STACK_MAG_KRON,
+  GSTAR_STACK_MAG_KRON_ERR,
+  GSTAR_STACK_MAG_APER,
+  GSTAR_STACK_MAG_APER_ERR,
+  GSTAR_WARP_MAG_PSF,
+  GSTAR_WARP_MAG_PSF_ERR,
+  GSTAR_WARP_MAG_KRON,
+  GSTAR_WARP_MAG_KRON_ERR,
+  GSTAR_WARP_MAG_APER,
+  GSTAR_WARP_MAG_APER_ERR,
 } GSTAR_SECF_CODES;
 
@@ -31,8 +51,8 @@
 void sort_index_float (float *X, int *IDX, int N) {
 
-# define SWAPFUNC(A,B){ float tmp; int itmp; 	\
-  tmp = X[A]; X[A] = X[B]; X[B] = tmp; \
-  itmp = IDX[A]; IDX[A] = IDX[B]; IDX[B] = itmp; \
-}
+# define SWAPFUNC(A,B){ float tmp; int itmp;		\
+    tmp = X[A]; X[A] = X[B]; X[B] = tmp;		\
+    itmp = IDX[A]; IDX[A] = IDX[B]; IDX[B] = itmp;	\
+  }
 # define COMPARE(A,B)(X[A] < X[B])
 
@@ -52,5 +72,5 @@
   off_t i, Nstars, *N1;
   off_t j, k, m, N, Nlo, Nhi;
-  int Nsecfilt, NPTS, QUIET, FULL_OUTPUT, STACK_OUTPUT, INST, SHOW_MASKS;
+  int Nsecfilt, NPTS, QUIET, INST, SHOW_MASKS;
   int found, GetMeasures;
   int SaveVectors;
@@ -109,5 +129,5 @@
   }
 
-  FULL_OUTPUT = FALSE;
+  int FULL_OUTPUT = FALSE;
   if ((N = get_argument (argc, argv, "-full"))) {
     FULL_OUTPUT = TRUE;
@@ -115,7 +135,43 @@
   }
 
-  STACK_OUTPUT = FALSE;
-  if ((N = get_argument (argc, argv, "-stack"))) {
+  int STACK_OUTPUT = FALSE;
+  if ((N = get_argument (argc, argv, "+stack"))) {
     STACK_OUTPUT = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+
+  int EXTRA_OUTPUT = FALSE;
+  if ((N = get_argument (argc, argv, "+extras"))) {
+    EXTRA_OUTPUT = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+
+  int WARP_OUTPUT = FALSE;
+  if ((N = get_argument (argc, argv, "+warp"))) {
+    WARP_OUTPUT = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+
+  int FLUX_OUTPUT = FALSE;
+  if ((N = get_argument (argc, argv, "+flux"))) {
+    FLUX_OUTPUT = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+
+  int MAG_OUTPUT = TRUE;
+  if ((N = get_argument (argc, argv, "-mag"))) {
+    MAG_OUTPUT = FALSE;
+    remove_argument (N, &argc, argv);
+  }
+
+  int KRON_OUTPUT = FALSE;
+  if ((N = get_argument (argc, argv, "+kron"))) {
+    KRON_OUTPUT = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+
+  int APER_OUTPUT = FALSE;
+  if ((N = get_argument (argc, argv, "+aper"))) {
+    APER_OUTPUT = TRUE;
     remove_argument (N, &argc, argv);
   }
@@ -185,6 +241,6 @@
   // an error exit status here is a significant error
   if (!dvo_catalog_open (&catalog, NULL, FALSE, "r")) {
-      fprintf (stderr, "ERROR: failure to open catalog file %s\n", catalog.filename);
-      exit (2);
+    fprintf (stderr, "ERROR: failure to open catalog file %s\n", catalog.filename);
+    exit (2);
   }
   dvo_catalog_unlock (&catalog);
@@ -248,5 +304,5 @@
       k = N1[i];
       if (!QUIET) {
-	gprint (GP_LOG, "star: "OFF_T_FMT"\n",  i);
+	gprint (GP_LOG, "star: "OFF_T_FMT"\n",  k);
 	gprint (GP_LOG, "%11.7f ", catalog.average[k].R);
 	gprint (GP_LOG, "%11.7f ", catalog.average[k].D);
@@ -259,88 +315,228 @@
 	
 	if (FULL_OUTPUT) {
-	    gprint (GP_LOG, "%f ",     catalog.average[k].dR);
-	    gprint (GP_LOG, "%f ",     catalog.average[k].dD);
-	    gprint (GP_LOG, "%f ",     catalog.average[k].uR);
-	    gprint (GP_LOG, "%f ",     catalog.average[k].uD);
-	    gprint (GP_LOG, "%f ",     catalog.average[k].duR);
-	    gprint (GP_LOG, "%f ",     catalog.average[k].duD);
-	    gprint (GP_LOG, "%f ",     catalog.average[k].P);
-	    gprint (GP_LOG, "%f   ",     catalog.average[k].dP);
-
-	    gprint (GP_LOG, "%f   ",     catalog.average[k].ChiSqPM);
-	    gprint (GP_LOG, "%f   ",     catalog.average[k].ChiSqPar);
-
-	    date = ohana_sec_to_date (catalog.average[k].Tmean);
-	    gprint (GP_LOG, "%20s ",     date);
-	    gprint (GP_LOG, "%f   ",     catalog.average[k].Trange / 86400.0);
+	  gprint (GP_LOG, "%f ",     catalog.average[k].dR);
+	  gprint (GP_LOG, "%f ",     catalog.average[k].dD);
+	  gprint (GP_LOG, "%f ",     catalog.average[k].uR);
+	  gprint (GP_LOG, "%f ",     catalog.average[k].uD);
+	  gprint (GP_LOG, "%f ",     catalog.average[k].duR);
+	  gprint (GP_LOG, "%f ",     catalog.average[k].duD);
+	  gprint (GP_LOG, "%f ",     catalog.average[k].P);
+	  gprint (GP_LOG, "%f   ",     catalog.average[k].dP);
+
+	  gprint (GP_LOG, "%f   ",     catalog.average[k].ChiSqPM);
+	  gprint (GP_LOG, "%f   ",     catalog.average[k].ChiSqPar);
+
+	  date = ohana_sec_to_date (catalog.average[k].Tmean);
+	  gprint (GP_LOG, "%20s ",     date);
+	  gprint (GP_LOG, "%f   ",     catalog.average[k].Trange / 86400.0);
 	}
 
-	gprint (GP_LOG, "\n");
+	gprint (GP_LOG, "\n\n");
       
 	/* filter names */
+	gprint (GP_LOG, "filter     : ");
 	for (j = 0; j < Nsecfilt; j++) printPhotcodeSequence (&catalog.average[k], &catalog.secfilt[Nsecfilt*k], j, GSTAR_FILTER_NAMES);
 	gprint (GP_LOG, "\n");
 
 	/* average mags */
+	gprint (GP_LOG, "chp_psf_ave: ");
 	for (j = 0; j < Nsecfilt; j++) printPhotcodeSequence (&catalog.average[k], &catalog.secfilt[Nsecfilt*k], j, GSTAR_AVE_MAG);
 	gprint (GP_LOG, "\n");
 
 	/* average mag errors */
+	gprint (GP_LOG, "chp_psf_err: ");
 	for (j = 0; j < Nsecfilt; j++) printPhotcodeSequence (&catalog.average[k], &catalog.secfilt[Nsecfilt*k], j, GSTAR_AVE_MAG_ERR);
 	gprint (GP_LOG, "\n");
 
 	/* average mag chisq */
+	gprint (GP_LOG, "chp_psf_chi: ");
 	for (j = 0; j < Nsecfilt; j++) printPhotcodeSequence (&catalog.average[k], &catalog.secfilt[Nsecfilt*k], j, GSTAR_AVE_MAG_CHISQ);
 	gprint (GP_LOG, "\n");
 
-	if (FULL_OUTPUT) {
+	
+	if (APER_OUTPUT) {
 	  /* Map */
+	  gprint (GP_LOG, "chp_ap__ave: ");
 	  for (j = 0; j < Nsecfilt; j++) printPhotcodeSequence (&catalog.average[k], &catalog.secfilt[Nsecfilt*k], j, GSTAR_AVE_AP_MAG);
 	  gprint (GP_LOG, "\n");
-
+	}
+
+	if (KRON_OUTPUT) {
 	  /* Mkron */
+	  gprint (GP_LOG, "chp_krn_ave: ");
 	  for (j = 0; j < Nsecfilt; j++) printPhotcodeSequence (&catalog.average[k], &catalog.secfilt[Nsecfilt*k], j, GSTAR_AVE_KRON_MAG);
 	  gprint (GP_LOG, "\n");
 
 	  /* dMkron */
+	  gprint (GP_LOG, "chp_krn_err: ");
 	  for (j = 0; j < Nsecfilt; j++) printPhotcodeSequence (&catalog.average[k], &catalog.secfilt[Nsecfilt*k], j, GSTAR_AVE_KRON_MAG_ERR);
 	  gprint (GP_LOG, "\n");
-
-	  /* M_20 */
-	  for (j = 0; j < Nsecfilt; j++) printPhotcodeSequence (&catalog.average[k], &catalog.secfilt[Nsecfilt*k], j, GSTAR_AVE_MAG_20);
-	  gprint (GP_LOG, "\n");
-
-	  /* M_80 */
-	  for (j = 0; j < Nsecfilt; j++) printPhotcodeSequence (&catalog.average[k], &catalog.secfilt[Nsecfilt*k], j, GSTAR_AVE_MAG_80);;
+	} 
+
+	if (EXTRA_OUTPUT) {
+	  /* Mmin */
+	  gprint (GP_LOG, "chp_psf_min: ");
+	  for (j = 0; j < Nsecfilt; j++) printPhotcodeSequence (&catalog.average[k], &catalog.secfilt[Nsecfilt*k], j, GSTAR_AVE_MAG_MIN);
+	  gprint (GP_LOG, "\n");
+
+	  /* Mmax */
+	  gprint (GP_LOG, "chp_psf_max: ");
+	  for (j = 0; j < Nsecfilt; j++) printPhotcodeSequence (&catalog.average[k], &catalog.secfilt[Nsecfilt*k], j, GSTAR_AVE_MAG_MAX);;
 	  gprint (GP_LOG, "\n");
 
 	  /* UCDIST */
+	  gprint (GP_LOG, "ubercal_dst: ");
 	  for (j = 0; j < Nsecfilt; j++) printPhotcodeSequence (&catalog.average[k], &catalog.secfilt[Nsecfilt*k], j, GSTAR_UCDIST);;
 	  gprint (GP_LOG, "\n");
 
 	  /* secfilt flags */
+	  gprint (GP_LOG, "filtflags:   ");
 	  for (j = 0; j < Nsecfilt; j++) printPhotcodeSequence (&catalog.average[k], &catalog.secfilt[Nsecfilt*k], j, GSTAR_SECF_FLAGS);
 	  gprint (GP_LOG, "\n");
-
 	}
-	if (STACK_OUTPUT) {
+	if (STACK_OUTPUT && MAG_OUTPUT) {
 	  /* FluxPSF */
+	  gprint (GP_LOG, "stk_psf_ave: ");
+	  for (j = 0; j < Nsecfilt; j++) printPhotcodeSequence (&catalog.average[k], &catalog.secfilt[Nsecfilt*k], j, GSTAR_STACK_MAG_PSF);
+	  gprint (GP_LOG, "\n");
+  
+	  /* dFluxPSF */
+	  gprint (GP_LOG, "stk_psf_err: ");
+	  for (j = 0; j < Nsecfilt; j++) printPhotcodeSequence (&catalog.average[k], &catalog.secfilt[Nsecfilt*k], j, GSTAR_STACK_MAG_PSF_ERR);
+	  gprint (GP_LOG, "\n");
+  
+	  if (KRON_OUTPUT) {
+	    /* MagKron */
+	    gprint (GP_LOG, "stk_krn_ave: ");
+	    for (j = 0; j < Nsecfilt; j++) printPhotcodeSequence (&catalog.average[k], &catalog.secfilt[Nsecfilt*k], j, GSTAR_STACK_MAG_KRON);
+	    gprint (GP_LOG, "\n");
+  
+	    /* dMagKron */
+	    gprint (GP_LOG, "stk_krn_err: ");
+	    for (j = 0; j < Nsecfilt; j++) printPhotcodeSequence (&catalog.average[k], &catalog.secfilt[Nsecfilt*k], j, GSTAR_STACK_MAG_KRON_ERR);
+	    gprint (GP_LOG, "\n");
+	  }
+
+	  if (APER_OUTPUT) {
+	    /* MagAper */
+	    gprint (GP_LOG, "stk_ap__ave: ");
+	    for (j = 0; j < Nsecfilt; j++) printPhotcodeSequence (&catalog.average[k], &catalog.secfilt[Nsecfilt*k], j, GSTAR_STACK_MAG_APER);
+	    gprint (GP_LOG, "\n");
+  
+	    /* dMagAper */
+	    gprint (GP_LOG, "stk_ap__err: ");
+	    for (j = 0; j < Nsecfilt; j++) printPhotcodeSequence (&catalog.average[k], &catalog.secfilt[Nsecfilt*k], j, GSTAR_STACK_MAG_APER_ERR);
+	    gprint (GP_LOG, "\n");
+	  }
+	}
+	if (WARP_OUTPUT && MAG_OUTPUT) {
+	  /* FluxPSF */
+	  gprint (GP_LOG, "wrp_psf_ave: ");
+	  for (j = 0; j < Nsecfilt; j++) printPhotcodeSequence (&catalog.average[k], &catalog.secfilt[Nsecfilt*k], j, GSTAR_WARP_MAG_PSF);
+	  gprint (GP_LOG, "\n");
+  
+	  /* dFluxPSF */
+	  gprint (GP_LOG, "wrp_psf_err: ");
+	  for (j = 0; j < Nsecfilt; j++) printPhotcodeSequence (&catalog.average[k], &catalog.secfilt[Nsecfilt*k], j, GSTAR_WARP_MAG_PSF_ERR);
+	  gprint (GP_LOG, "\n");
+  
+	  if (KRON_OUTPUT) {
+	    /* MagKron */
+	    gprint (GP_LOG, "wrp_krn_ave: ");
+	    for (j = 0; j < Nsecfilt; j++) printPhotcodeSequence (&catalog.average[k], &catalog.secfilt[Nsecfilt*k], j, GSTAR_WARP_MAG_KRON);
+	    gprint (GP_LOG, "\n");
+  
+	    /* dMagKron */
+	    gprint (GP_LOG, "wrp_krn_err: ");
+	    for (j = 0; j < Nsecfilt; j++) printPhotcodeSequence (&catalog.average[k], &catalog.secfilt[Nsecfilt*k], j, GSTAR_WARP_MAG_KRON_ERR);
+	    gprint (GP_LOG, "\n");
+
+	  }
+
+	  if (APER_OUTPUT) {
+	    /* MagAper */
+	    gprint (GP_LOG, "wrp_ap__ave: ");
+	    for (j = 0; j < Nsecfilt; j++) printPhotcodeSequence (&catalog.average[k], &catalog.secfilt[Nsecfilt*k], j, GSTAR_WARP_MAG_APER);
+	    gprint (GP_LOG, "\n");
+  
+	    /* dMagAper */
+	    gprint (GP_LOG, "wrp_ap__err: ");
+	    for (j = 0; j < Nsecfilt; j++) printPhotcodeSequence (&catalog.average[k], &catalog.secfilt[Nsecfilt*k], j, GSTAR_WARP_MAG_APER_ERR);
+	    gprint (GP_LOG, "\n");
+	  }
+	}
+	if (STACK_OUTPUT && FLUX_OUTPUT) {
+	  /* FluxPSF */
+	  gprint (GP_LOG, "stk_psf_ave: ");
 	  for (j = 0; j < Nsecfilt; j++) printPhotcodeSequence (&catalog.average[k], &catalog.secfilt[Nsecfilt*k], j, GSTAR_STACK_FLUX_PSF);
 	  gprint (GP_LOG, "\n");
-
+  
 	  /* dFluxPSF */
+	  gprint (GP_LOG, "stk_psf_err: ");
 	  for (j = 0; j < Nsecfilt; j++) printPhotcodeSequence (&catalog.average[k], &catalog.secfilt[Nsecfilt*k], j, GSTAR_STACK_FLUX_PSF_ERR);
 	  gprint (GP_LOG, "\n");
-
-	  /* FluxKron */
-	  for (j = 0; j < Nsecfilt; j++) printPhotcodeSequence (&catalog.average[k], &catalog.secfilt[Nsecfilt*k], j, GSTAR_STACK_FLUX_KRON);
-	  gprint (GP_LOG, "\n");
-
-	  /* dFluxKron */
-	  for (j = 0; j < Nsecfilt; j++) printPhotcodeSequence (&catalog.average[k], &catalog.secfilt[Nsecfilt*k], j, GSTAR_STACK_FLUX_KRON_ERR);
-	  gprint (GP_LOG, "\n");
-
+  
+	  if (KRON_OUTPUT) {
+	    /* FluxKron */
+	    gprint (GP_LOG, "stk_krn_ave: ");
+	    for (j = 0; j < Nsecfilt; j++) printPhotcodeSequence (&catalog.average[k], &catalog.secfilt[Nsecfilt*k], j, GSTAR_STACK_FLUX_KRON);
+	    gprint (GP_LOG, "\n");
+  
+	    /* dFluxKron */
+	    gprint (GP_LOG, "stk_krn_err: ");
+	    for (j = 0; j < Nsecfilt; j++) printPhotcodeSequence (&catalog.average[k], &catalog.secfilt[Nsecfilt*k], j, GSTAR_STACK_FLUX_KRON_ERR);
+	    gprint (GP_LOG, "\n");
+	  }
+
+	  if (APER_OUTPUT) {
+	    /* FluxAper */
+	    gprint (GP_LOG, "stk_ap_ave: ");
+	    for (j = 0; j < Nsecfilt; j++) printPhotcodeSequence (&catalog.average[k], &catalog.secfilt[Nsecfilt*k], j, GSTAR_STACK_FLUX_APER);
+	    gprint (GP_LOG, "\n");
+  
+	    /* dFluxAper */
+	    gprint (GP_LOG, "stk_ap_err: ");
+	    for (j = 0; j < Nsecfilt; j++) printPhotcodeSequence (&catalog.average[k], &catalog.secfilt[Nsecfilt*k], j, GSTAR_STACK_FLUX_APER_ERR);
+	    gprint (GP_LOG, "\n");
+	  }
 	}
-      }
+	if (WARP_OUTPUT && FLUX_OUTPUT) {
+	  /* FluxPSF */
+	  gprint (GP_LOG, "wrp_psf_ave: ");
+	  for (j = 0; j < Nsecfilt; j++) printPhotcodeSequence (&catalog.average[k], &catalog.secfilt[Nsecfilt*k], j, GSTAR_WARP_FLUX_PSF);
+	  gprint (GP_LOG, "\n");
+  
+	  /* dFluxPSF */
+	  gprint (GP_LOG, "wrp_psf_ave: ");
+	  for (j = 0; j < Nsecfilt; j++) printPhotcodeSequence (&catalog.average[k], &catalog.secfilt[Nsecfilt*k], j, GSTAR_WARP_FLUX_PSF_ERR);
+	  gprint (GP_LOG, "\n");
+  
+	  if (KRON_OUTPUT) {
+	    /* FluxKron */
+	    gprint (GP_LOG, "wrp_krn_ave: ");
+	    for (j = 0; j < Nsecfilt; j++) printPhotcodeSequence (&catalog.average[k], &catalog.secfilt[Nsecfilt*k], j, GSTAR_WARP_FLUX_KRON);
+	    gprint (GP_LOG, "\n");
+  
+	    /* dFluxKron */
+	    gprint (GP_LOG, "wrp_krn_err: ");
+	    for (j = 0; j < Nsecfilt; j++) printPhotcodeSequence (&catalog.average[k], &catalog.secfilt[Nsecfilt*k], j, GSTAR_WARP_FLUX_KRON_ERR);
+	    gprint (GP_LOG, "\n");
+	  }
+
+	  if (APER_OUTPUT) {
+	    /* FluxAper */
+	    gprint (GP_LOG, "wrp_ap__ave: ");
+	    for (j = 0; j < Nsecfilt; j++) printPhotcodeSequence (&catalog.average[k], &catalog.secfilt[Nsecfilt*k], j, GSTAR_WARP_FLUX_APER);
+	    gprint (GP_LOG, "\n");
+  
+	    /* dFluxAper */
+	    gprint (GP_LOG, "wrp_ap__err: ");
+	    for (j = 0; j < Nsecfilt; j++) printPhotcodeSequence (&catalog.average[k], &catalog.secfilt[Nsecfilt*k], j, GSTAR_WARP_FLUX_APER_ERR);
+	    gprint (GP_LOG, "\n");
+	  }
+	}
+      }
+      gprint (GP_LOG, "\n");
+      
       if (GetMeasures || SaveVectors) {
 
@@ -374,10 +570,13 @@
 	  int Nv = index[j];
 
-	  Mcat = PhotCat (&catalog.measure[Nv]);
+	  Mcat = PhotCat (&catalog.measure[Nv], MAG_CLASS_PSF);
 	  if (INST) {
-	    Mrel = PhotInst (&catalog.measure[Nv]);
+	    Mrel = PhotInst (&catalog.measure[Nv], MAG_CLASS_PSF);
 	  } else {
-	    Mrel = PhotRel (&catalog.measure[Nv], &catalog.average[k], &catalog.secfilt[k*Nsecfilt]);
-	  }
+	    Mrel = PhotRel (&catalog.measure[Nv], &catalog.average[k], &catalog.secfilt[k*Nsecfilt], MAG_CLASS_PSF);
+	  }
+
+	  float dRoff = dvoOffsetR(&catalog.measure[Nv], &catalog.average[k]);
+	  float dDoff = dvoOffsetD(&catalog.measure[Nv], &catalog.average[k]);
 
 	  if (GetMeasures && !QUIET) {
@@ -387,6 +586,7 @@
 	    gprint (GP_LOG, "%6.3f  ", catalog.measure[Nv].dM);
 	    gprint (GP_LOG, "%20s  ",  date);
-	    gprint (GP_LOG, "%7.4f ",  catalog.measure[Nv].dR);
-	    gprint (GP_LOG, "%7.4f ",  catalog.measure[Nv].dD);
+	    
+	    gprint (GP_LOG, "%7.4f ",  dRoff);
+	    gprint (GP_LOG, "%7.4f ",  dDoff);
 	    gprint (GP_LOG, "0x%08x ", catalog.measure[Nv].photFlags);
 	    gprint (GP_LOG, "0x%08x ", catalog.measure[Nv].dbFlags);
@@ -409,31 +609,31 @@
 
 	    if (FULL_OUTPUT) {
-		gprint (GP_LOG, "%6.3f ", catalog.measure[Nv].Mcal);
-		gprint (GP_LOG, "%6.3f ", catalog.measure[Nv].Map);
-		gprint (GP_LOG, "%6.3f ", catalog.measure[Nv].Mkron);
-		gprint (GP_LOG, "%6.3f ", catalog.measure[Nv].dMkron);
-		gprint (GP_LOG, "%5.1f ", pow(10.0, 0.4*catalog.measure[Nv].dt));
-		gprint (GP_LOG, "%5.3f ", catalog.measure[Nv].airmass);
-		gprint (GP_LOG, "%6.1f ", catalog.measure[Nv].az);
-		gprint (GP_LOG, "%6.1f ", catalog.measure[Nv].Xccd);
-		gprint (GP_LOG, "%6.1f ", catalog.measure[Nv].Yccd);
-		gprint (GP_LOG, "%3.1f ", FromShortPixels(catalog.measure[Nv].dXccd));
-		gprint (GP_LOG, "%3.1f ", FromShortPixels(catalog.measure[Nv].dYccd));
-		gprint (GP_LOG, "%6.1f ", catalog.measure[Nv].Sky);
-		gprint (GP_LOG, "%5.1f ", catalog.measure[Nv].dSky);
-		gprint (GP_LOG, "%8d ", catalog.measure[Nv].averef);
-		gprint (GP_LOG, "0x%08x ", catalog.measure[Nv].detID);
-		gprint (GP_LOG, "0x%08x ", catalog.measure[Nv].imageID);
-		gprint (GP_LOG, "%.3f ", catalog.measure[Nv].psfQF);
-		gprint (GP_LOG, "%.1f ", catalog.measure[Nv].psfChisq);
-		gprint (GP_LOG, "%.1f ", catalog.measure[Nv].crNsigma);
-		gprint (GP_LOG, "%.1f ", catalog.measure[Nv].extNsigma);
-		gprint (GP_LOG, "%.1f ", FromShortDegrees(catalog.measure[Nv].theta));
+	      gprint (GP_LOG, "%6.3f ", catalog.measure[Nv].Mcal);
+	      gprint (GP_LOG, "%6.3f ", catalog.measure[Nv].Map);
+	      gprint (GP_LOG, "%6.3f ", catalog.measure[Nv].Mkron);
+	      gprint (GP_LOG, "%6.3f ", catalog.measure[Nv].dMkron);
+	      gprint (GP_LOG, "%5.1f ", pow(10.0, 0.4*catalog.measure[Nv].dt));
+	      gprint (GP_LOG, "%5.3f ", catalog.measure[Nv].airmass);
+	      gprint (GP_LOG, "%6.1f ", catalog.measure[Nv].az);
+	      gprint (GP_LOG, "%6.1f ", catalog.measure[Nv].Xccd);
+	      gprint (GP_LOG, "%6.1f ", catalog.measure[Nv].Yccd);
+	      gprint (GP_LOG, "%3.1f ", FromShortPixels(catalog.measure[Nv].dXccd));
+	      gprint (GP_LOG, "%3.1f ", FromShortPixels(catalog.measure[Nv].dYccd));
+	      gprint (GP_LOG, "%6.1f ", catalog.measure[Nv].Sky);
+	      gprint (GP_LOG, "%5.1f ", catalog.measure[Nv].dSky);
+	      gprint (GP_LOG, "%8d ", catalog.measure[Nv].averef);
+	      gprint (GP_LOG, "0x%08x ", catalog.measure[Nv].detID);
+	      gprint (GP_LOG, "0x%08x ", catalog.measure[Nv].imageID);
+	      gprint (GP_LOG, "%5.3f ", catalog.measure[Nv].psfQF);
+	      gprint (GP_LOG, "%7.1f ", catalog.measure[Nv].psfChisq);
+	      // gprint (GP_LOG, "%3.1f ", catalog.measure[Nv].crNsigma);
+	      gprint (GP_LOG, "%4.1f ", catalog.measure[Nv].extNsigma);
+	      gprint (GP_LOG, "%5.1f ", FromShortDegrees(catalog.measure[Nv].theta));
 	    }
-	    if (STACK_OUTPUT) {
-		gprint (GP_LOG, "%10.3e ", catalog.measure[Nv].FluxPSF);
-		gprint (GP_LOG, "%10.3e ", catalog.measure[Nv].dFluxPSF);
-		gprint (GP_LOG, "%10.3e ", catalog.measure[Nv].FluxKron);
-		gprint (GP_LOG, "%10.3e ", catalog.measure[Nv].dFluxKron);
+	    if (FLUX_OUTPUT) {
+	      gprint (GP_LOG, "%10.3e ", catalog.measure[Nv].FluxPSF);
+	      gprint (GP_LOG, "%10.3e ", catalog.measure[Nv].dFluxPSF);
+	      gprint (GP_LOG, "%10.3e ", catalog.measure[Nv].FluxKron);
+	      gprint (GP_LOG, "%10.3e ", catalog.measure[Nv].dFluxKron);
 	    }
 	    gprint (GP_LOG, "\n");
@@ -447,6 +647,6 @@
 	    vec3[0].elements.Flt[N] = catalog.measure[Nv].airmass;
 	    vec4[0].elements.Flt[N] = catalog.measure[Nv].photcode;
-	    vec5[0].elements.Flt[N] = catalog.measure[Nv].dR;
-	    vec6[0].elements.Flt[N] = catalog.measure[Nv].dD;
+	    vec5[0].elements.Flt[N] = dRoff;
+	    vec6[0].elements.Flt[N] = dDoff;
 	    N ++;
 	    if (N == NPTS - 1) {
@@ -543,17 +743,17 @@
 
   switch (type) {
-    case GSTAR_AVE_MAG: /* average mags */
-      if (seq == -1) {
-	print_double (NAN);
-      } else {
-	print_double (secfilt[seq].M);
-      }
-      break;
-
-    case GSTAR_AVE_MAG_ERR: /* average mags errors */
-      if (seq == -1) {
-	print_double (NAN);
-      } else {
-	print_double (secfilt[seq].dM);
+    case GSTAR_AVE_MAG_MIN: /* average ap mags */
+      if (seq == -1) {
+	print_double (NAN);
+      } else {
+	print_double (secfilt[seq].Mmin);
+      }
+      break;
+
+    case GSTAR_AVE_MAG_MAX: /* average ap mags */
+      if (seq == -1) {
+	print_double (NAN);
+      } else {
+	print_double (secfilt[seq].Mmax);
       }
       break;
@@ -561,7 +761,7 @@
     case GSTAR_AVE_MAG_CHISQ: /* average mag chisq */
       if (seq == -1) {
-	print_short (NAN_S_SHORT, NAN_S_SHORT);
-      } else {
-	print_short (pow (10.0, 0.01*secfilt[seq].Xm), secfilt[seq].Xm);
+	print_double (NAN);
+      } else {
+	print_double (secfilt[seq].Mchisq);
       }
       break;
@@ -588,4 +788,22 @@
       break;
 
+      /*** CHIP : MAG ***/
+
+    case GSTAR_AVE_MAG: /* average mags */
+      if (seq == -1) {
+	print_double (NAN);
+      } else {
+	print_double (secfilt[seq].M);
+      }
+      break;
+
+    case GSTAR_AVE_MAG_ERR: /* average mags errors */
+      if (seq == -1) {
+	print_double (NAN);
+      } else {
+	print_double (secfilt[seq].dM);
+      }
+      break;
+
     case GSTAR_AVE_AP_MAG: /* average ap mags */
       if (seq == -1) {
@@ -596,20 +814,4 @@
       break;
 
-    case GSTAR_AVE_MAG_20: /* average ap mags */
-      if (seq == -1) {
-	print_double (NAN);
-      } else {
-	print_short (0.001*secfilt[seq].M_20, secfilt[seq].M_20);
-      }
-      break;
-
-    case GSTAR_AVE_MAG_80: /* average ap mags */
-      if (seq == -1) {
-	print_double (NAN);
-      } else {
-	print_short (0.001*secfilt[seq].M_80, secfilt[seq].M_80);
-      }
-      break;
-
     case GSTAR_AVE_KRON_MAG: /* average ap mags */
       if (seq == -1) {
@@ -628,9 +830,11 @@
       break;
 
+      /******************* STACK : FLUX **********************/
+
     case GSTAR_STACK_FLUX_PSF: /* average ap mags */
       if (seq == -1) {
 	print_double (NAN);
       } else {
-	print_double_exp (secfilt[seq].FluxPSF);
+	print_double_exp (secfilt[seq].FpsfStk);
       }
       break;
@@ -640,5 +844,5 @@
 	print_double (NAN);
       } else {
-	print_double_exp (secfilt[seq].dFluxPSF);
+	print_double_exp (secfilt[seq].dFpsfStk);
       }
       break;
@@ -648,5 +852,5 @@
 	print_double (NAN);
       } else {
-	print_double_exp (secfilt[seq].FluxKron);
+	print_double_exp (secfilt[seq].FkronStk);
       }
       break;
@@ -656,5 +860,171 @@
 	print_double (NAN);
       } else {
-	print_double_exp (secfilt[seq].dFluxKron);
+	print_double_exp (secfilt[seq].dFkronStk);
+      }
+      break;
+
+    case GSTAR_STACK_FLUX_APER: /* average ap mags */
+      if (seq == -1) {
+	print_double (NAN);
+      } else {
+	print_double_exp (secfilt[seq].FapStk);
+      }
+      break;
+
+    case GSTAR_STACK_FLUX_APER_ERR: /* average ap mags */
+      if (seq == -1) {
+	print_double (NAN);
+      } else {
+	print_double_exp (secfilt[seq].dFapStk);
+      }
+      break;
+
+      /******************* STACK : MAG **********************/
+
+    case GSTAR_STACK_MAG_PSF: /* average ap mags */
+      if (seq == -1) {
+	print_double (NAN);
+      } else {
+	print_double (secfilt[seq].MpsfStk);
+      }
+      break;
+
+    case GSTAR_STACK_MAG_PSF_ERR: /* average ap mags */
+      if (seq == -1) {
+	print_double (NAN);
+      } else {
+	print_double (secfilt[seq].dFpsfStk / secfilt[seq].FpsfStk);
+      }
+      break;
+
+    case GSTAR_STACK_MAG_KRON: /* average ap mags */
+      if (seq == -1) {
+	print_double (NAN);
+      } else {
+	print_double (secfilt[seq].MkronStk);
+      }
+      break;
+
+    case GSTAR_STACK_MAG_KRON_ERR: /* average ap mags */
+      if (seq == -1) {
+	print_double (NAN);
+      } else {
+	print_double (secfilt[seq].dFkronStk / secfilt[seq].FkronStk);
+      }
+      break;
+
+    case GSTAR_STACK_MAG_APER: /* average ap mags */
+      if (seq == -1) {
+	print_double (NAN);
+      } else {
+	print_double (secfilt[seq].MapStk);
+      }
+      break;
+
+    case GSTAR_STACK_MAG_APER_ERR: /* average ap mags */
+      if (seq == -1) {
+	print_double (NAN);
+      } else {
+	print_double (secfilt[seq].dFapStk / secfilt[seq].FapStk);
+      }
+      break;
+
+      /******************* WARP : FLUX **********************/
+
+    case GSTAR_WARP_FLUX_PSF: /* average ap mags */
+      if (seq == -1) {
+	print_double (NAN);
+      } else {
+	print_double_exp (secfilt[seq].FpsfWrp);
+      }
+      break;
+
+    case GSTAR_WARP_FLUX_PSF_ERR: /* average ap mags */
+      if (seq == -1) {
+	print_double (NAN);
+      } else {
+	print_double_exp (secfilt[seq].dFpsfWrp);
+      }
+      break;
+
+    case GSTAR_WARP_FLUX_KRON: /* average ap mags */
+      if (seq == -1) {
+	print_double (NAN);
+      } else {
+	print_double_exp (secfilt[seq].FkronWrp);
+      }
+      break;
+
+    case GSTAR_WARP_FLUX_KRON_ERR: /* average ap mags */
+      if (seq == -1) {
+	print_double (NAN);
+      } else {
+	print_double_exp (secfilt[seq].dFkronWrp);
+      }
+      break;
+
+    case GSTAR_WARP_FLUX_APER: /* average ap mags */
+      if (seq == -1) {
+	print_double (NAN);
+      } else {
+	print_double_exp (secfilt[seq].FapWrp);
+      }
+      break;
+
+    case GSTAR_WARP_FLUX_APER_ERR: /* average ap mags */
+      if (seq == -1) {
+	print_double (NAN);
+      } else {
+	print_double_exp (secfilt[seq].dFapWrp);
+      }
+      break;
+
+      /******************* WARP : MAG **********************/
+
+    case GSTAR_WARP_MAG_PSF: /* average ap mags */
+      if (seq == -1) {
+	print_double (NAN);
+      } else {
+	print_double (secfilt[seq].MpsfWrp);
+      }
+      break;
+
+    case GSTAR_WARP_MAG_PSF_ERR: /* average ap mags */
+      if (seq == -1) {
+	print_double (NAN);
+      } else {
+	print_double (secfilt[seq].dFpsfWrp / secfilt[seq].FpsfWrp);
+      }
+      break;
+
+    case GSTAR_WARP_MAG_KRON: /* average ap mags */
+      if (seq == -1) {
+	print_double (NAN);
+      } else {
+	print_double (secfilt[seq].MkronWrp);
+      }
+      break;
+
+    case GSTAR_WARP_MAG_KRON_ERR: /* average ap mags */
+      if (seq == -1) {
+	print_double (NAN);
+      } else {
+	print_double (secfilt[seq].dFkronWrp / secfilt[seq].FkronWrp);
+      }
+      break;
+
+    case GSTAR_WARP_MAG_APER: /* average ap mags */
+      if (seq == -1) {
+	print_double (NAN);
+      } else {
+	print_double (secfilt[seq].MapWrp);
+      }
+      break;
+
+    case GSTAR_WARP_MAG_APER_ERR: /* average ap mags */
+      if (seq == -1) {
+	print_double (NAN);
+      } else {
+	print_double (secfilt[seq].dFapWrp / secfilt[seq].FapWrp);
       }
       break;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/hosts.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/hosts.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/hosts.c	(revision 37403)
@@ -3,5 +3,8 @@
 # define DVO_MAX_PATH 1024
 
-enum {TEMP_NONE, TEMP_DVO_RESULTS, TEMP_DVO_LOG, TEMP_RELASTRO_CATALOG, TEMP_RELPHOT_CATALOG, TEMP_RELPHOT_LOG, TEMP_DVOPSPS_DET, TEMP_FIXSTKIDS_RESULTS};
+enum {TEMP_NONE, TEMP_DVO_RESULTS, TEMP_DVO_LOG, 
+      TEMP_RELASTRO_CATALOG, TEMP_RELPHOT_CATALOG, TEMP_RELPHOT_LOG, TEMP_DVOPSPS_DET, TEMP_FIXSTKIDS_RESULTS,
+      TEMP_RELASTRO_CAT_FULL, TEMP_RELPHOT_CAT_FULL, TEMP_CHECKASTRO_CAT_FULL,
+};
 
 // functions to manage the remote hosts
@@ -71,6 +74,9 @@
       if (!strcasecmp(argv[N], "dvo.results"))       TEMP_TYPE = TEMP_DVO_RESULTS;
       if (!strcasecmp(argv[N], "dvo.log"))           TEMP_TYPE = TEMP_DVO_LOG;
-      if (!strcasecmp(argv[N], "relastro.catalog"))   TEMP_TYPE = TEMP_RELASTRO_CATALOG;
+      if (!strcasecmp(argv[N], "relastro.catalog"))  TEMP_TYPE = TEMP_RELASTRO_CATALOG;
       if (!strcasecmp(argv[N], "relphot.catalog"))   TEMP_TYPE = TEMP_RELPHOT_CATALOG;
+      if (!strcasecmp(argv[N], "relastro.catfull"))  TEMP_TYPE = TEMP_RELASTRO_CAT_FULL;
+      if (!strcasecmp(argv[N], "checkastro.catfull"))TEMP_TYPE = TEMP_CHECKASTRO_CAT_FULL;
+      if (!strcasecmp(argv[N], "relphot.catfull"))   TEMP_TYPE = TEMP_RELPHOT_CAT_FULL;
       if (!strcasecmp(argv[N], "relphot.log"))       TEMP_TYPE = TEMP_RELPHOT_LOG;
       if (!strcasecmp(argv[N], "dvopsps.det"))       TEMP_TYPE = TEMP_DVOPSPS_DET;
@@ -78,5 +84,5 @@
       if (TEMP_TYPE == TEMP_NONE) {
 	gprint (GP_ERR, "USAGE: hosts purge-temp [-type (type)]\n");
-	gprint (GP_ERR, "  allowed types dvo.results, dvo.log, relphot.results, relphot.log]\n");
+	gprint (GP_ERR, "  allowed types dvo.results, dvo.log, relphot.catalog, relphot.log, relphot.catfull, relastro.catalog, relastro.catfull, checkastro.catfull, dvopsps.det, fixstkids.results]\n");
 	return FALSE;
       }
@@ -118,4 +124,7 @@
 	if (TEMP_TYPE == TEMP_RELPHOT_CATALOG) 	 snprintf (name, DVO_MAX_PATH, "%s/relphot.catalog.subset.dat", table->hosts[i].pathname);
 	if (TEMP_TYPE == TEMP_RELPHOT_LOG)     	 snprintf (name, DVO_MAX_PATH, "%s/log.rlpc.*", table->hosts[i].pathname);
+	if (TEMP_TYPE == TEMP_RELASTRO_CAT_FULL) snprintf (name, DVO_MAX_PATH, "%s/relastro.catalog.?????.?????.dat", table->hosts[i].pathname);
+	if (TEMP_TYPE == TEMP_CHECKASTRO_CAT_FULL) snprintf (name, DVO_MAX_PATH, "%s/checkastro.catalog.?????.?????.dat", table->hosts[i].pathname);
+	if (TEMP_TYPE == TEMP_RELPHOT_CAT_FULL)	 snprintf (name, DVO_MAX_PATH, "%s/relphot.catalog.?????.?????.dat", table->hosts[i].pathname);
 	if (TEMP_TYPE == TEMP_DVOPSPS_DET)     	 snprintf (name, DVO_MAX_PATH, "%s/dvopsps.*.det.dat", table->hosts[i].pathname);
 	if (TEMP_TYPE == TEMP_FIXSTKIDS_RESULTS) snprintf (name, DVO_MAX_PATH, "%s/fixstkids.results.*.dat", table->hosts[i].pathname);
@@ -126,4 +135,7 @@
 	if (TEMP_TYPE == TEMP_RELPHOT_CATALOG) 	 snprintf (name, DVO_MAX_PATH, "%s/relphot.catalog.subset.dat", table->hosts[i].pathname);
 	if (TEMP_TYPE == TEMP_RELPHOT_LOG)     	 snprintf (name, DVO_MAX_PATH, "%s/log.rlpc.*", table->hosts[i].pathname);
+	if (TEMP_TYPE == TEMP_RELASTRO_CAT_FULL) snprintf (name, DVO_MAX_PATH, "%s/relastro.catalog.%05d.?????.dat", table->hosts[i].pathname, PID);
+	if (TEMP_TYPE == TEMP_CHECKASTRO_CAT_FULL) snprintf (name, DVO_MAX_PATH, "%s/checkastro.catalog.%05d.?????.dat", table->hosts[i].pathname, PID);
+	if (TEMP_TYPE == TEMP_RELPHOT_CAT_FULL)	 snprintf (name, DVO_MAX_PATH, "%s/relphot.catalog.%05d.?????.dat", table->hosts[i].pathname, PID);
 	if (TEMP_TYPE == TEMP_DVOPSPS_DET)     	 snprintf (name, DVO_MAX_PATH, "%s/dvopsps.%05d.*.det.dat", table->hosts[i].pathname, PID);
 	if (TEMP_TYPE == TEMP_FIXSTKIDS_RESULTS) snprintf (name, DVO_MAX_PATH, "%s/fixstkids.results.%05d.*.dat", table->hosts[i].pathname, PID);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/imdata.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/imdata.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/imdata.c	(revision 37403)
@@ -3,5 +3,5 @@
 int imdata (int argc, char **argv) {
   
-  off_t i, j, k, n, I;
+  off_t i, j, k, I;
   int N, NPTS, found, mode, TimeSelect, TimeFormat;
   off_t Nregions, NREGIONS;
@@ -152,6 +152,5 @@
 	for (i = 0; i < catalog.Nmeasure; i++) {
 	  if ((catalog.measure[i].t < start) || (catalog.measure[i].t > stop)) continue;
-	  n = catalog.measure[i].averef;
-	  vec[0].elements.Flt[N] = catalog.average[n].R - catalog.measure[i].dR / 3600.0;
+	  vec[0].elements.Flt[N] = catalog.measure[i].R;
 	  N++;
 	  CHECK_REALLOCATE (vec[0].elements.Flt, opihi_flt, NPTS, N, 1000);
@@ -161,6 +160,5 @@
 	for (i = 0; i < catalog.Nmeasure; i++) {
 	  if ((catalog.measure[i].t < start) || (catalog.measure[i].t > stop)) continue;
-	  n = catalog.measure[i].averef;
-	  vec[0].elements.Flt[N] = catalog.average[n].D - catalog.measure[i].dD / 3600.0;
+	  vec[0].elements.Flt[N] = catalog.measure[i].D;
 	  N++;
 	  CHECK_REALLOCATE (vec[0].elements.Flt, opihi_flt, NPTS, N, 1000);
@@ -194,5 +192,5 @@
 	for (i = 0; i < catalog.Nmeasure; i++) {
 	  if ((catalog.measure[i].t < start) || (catalog.measure[i].t > stop)) continue;
-	  n = catalog.measure[i].averef;
+	  //n = catalog.measure[i].averef;
 	  // vec[0].elements.Flt[N] = catalog.average[n].M;
 	  N++;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/imextract.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/imextract.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/imextract.c	(revision 37403)
@@ -185,5 +185,5 @@
     gprint (GP_ERR, "  Mcal : photometry calibration (mags)\n");
     gprint (GP_ERR, "  dMcal : photometry calibration error (mags)\n");
-    gprint (GP_ERR, "  Xm : chisq of photometry calibration\n");
+    gprint (GP_ERR, "  Mchisq : chisq of photometry calibration\n");
     gprint (GP_ERR, "  photcode : numeric photcode value for image\n");
     gprint (GP_ERR, "  exptime : exposure duration (seconds)\n");
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/init.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/init.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/init.c	(revision 37403)
@@ -14,4 +14,6 @@
 int cmpread         PROTO((int, char **));
 int coordimage      PROTO((int, char **));
+int coordmosaic     PROTO((int, char **));
+int psastro_model   PROTO((int, char **));
 int ddmags          PROTO((int, char **));
 int detrend         PROTO((int, char **));
@@ -64,21 +66,23 @@
   {1, "avmatch",     avmatch,      "extract average data values matched to RA,DEC points"},
   {1, "badimages",   badimages,    "look for images with anomalous astrometry"},
-  {1, "calextract",  calextract,   "extract photometry calibration"},
-  {1, "calmextract", calmextract,  "extract photometry calibration"},
+//  {1, "calextract",  calextract,   "extract photometry calibration"},
+//  {1, "calmextract", calmextract,  "extract photometry calibration"},
   {1, "catdir",      catdir_define,"re-define CATDIR"},
-  {1, "ccd",         ccd,          "plot color-color diagram"},
+//  {1, "ccd",         ccd,          "plot color-color diagram"},
   {1, "cmatch",      cmatch,       "match two catalogs"},
-  {1, "cmd",         cmd,          "plot cmd of stars in current region"},
+//  {1, "cmd",         cmd,          "plot cmd of stars in current region"},
   {1, "cmpload",     cmpload,      "load cmp file into ?"},
   {1, "cmpread",     cmpread,      "read data from cmp format files"},
   {1, "coordimage",  coordimage,   "generate a map of the transformation residuals"},
-  {1, "ddmags",      ddmags,       "plot magnitude differences"},
+  {1, "coordmosaic", coordmosaic,  "generate a map of the distortion"},
+  {1, "psastro_model", psastro_model, "save psastro-format astrometry model"},
+//  {1, "ddmags",      ddmags,       "plot magnitude differences"},
   {1, "detrend",     detrend,      "extract from detrend database?"},
-  {1, "dmagaves",    dmagaves,     "foo"},
-  {1, "dmagmeas",    dmagmeas,     "foo"},
-  {1, "dmags",       dmags,        "plot differential magnitudes between filters"},
+//  {1, "dmagaves",    dmagaves,     "foo"},
+//  {1, "dmagmeas",    dmagmeas,     "foo"},
+//  {1, "dmags",       dmags,        "plot differential magnitudes between filters"},
   {1, "dmt",         dmt,          "plot mag scatter"},
   {1, "elixir",      elixir,       "talk to elixir"},
-  {1, "fitcolors",   fitcolors,    "fit chip-to-chip color terms"},
+//  {1, "fitcolors",   fitcolors,    "fit chip-to-chip color terms"},
   {1, "fitsed",      fitsed,       "fit stellar SEDs to objects"},
   {1, "gcat",        gcat,         "get catalog at location"},
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/lcurve.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/lcurve.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/lcurve.c	(revision 37403)
@@ -129,5 +129,5 @@
 	if (ErrorBars) dYvec.elements.Flt[N] = catalog.measure[m].dM;
 	Xvec.elements.Flt[N] = TimeValue (catalog.measure[m].t, TimeReference, TimeFormat);
-	Yvec.elements.Flt[N] = PhotCat (&catalog.measure[m]);
+	Yvec.elements.Flt[N] = PhotCat (&catalog.measure[m], MAG_CLASS_PSF);
 	/**** need to use PhotRel optionally here ****/
 	N++; 
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/lightcurve.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/lightcurve.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/lightcurve.c	(revision 37403)
@@ -121,7 +121,7 @@
 	dmvec[0].elements.Flt[N] = catalog.measure[m].dM;
 	if (RELPHOT) {
-	  mvec[0].elements.Flt[N] = PhotCat (&catalog.measure[m]);
+	  mvec[0].elements.Flt[N] = PhotCat (&catalog.measure[m], MAG_CLASS_PSF);
 	} else {
-	  mvec[0].elements.Flt[N] = PhotRel (&catalog.measure[m], &catalog.average[k], &catalog.secfilt[k*Nsecfilt]);
+	  mvec[0].elements.Flt[N] = PhotRel (&catalog.measure[m], &catalog.average[k], &catalog.secfilt[k*Nsecfilt], MAG_CLASS_PSF);
 	}
 	N++; 
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/photcode_ops.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/photcode_ops.c	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/photcode_ops.c	(revision 37403)
@@ -0,0 +1,35 @@
+# include "dvoshell.h"
+
+/* (re)load photcodes from photcode table */
+int InitPhotcodes () {
+
+  double ZERO_POINT;
+  char MasterPhotcodeFile[256];
+  char CatdirPhotcodeFile[256];
+  char *catdir;
+
+  if (VarConfig ("ZERO_PT", "%lf", &ZERO_POINT) == (char *) NULL) {
+    gprint (GP_ERR, "ZERO_PT undefined in config\n");
+    return (FALSE);
+  }
+  SetZeroPoint (ZERO_POINT);
+
+  catdir = GetCATDIR();
+  if (catdir == NULL) {
+    CatdirPhotcodeFile[0] = 0;
+  } else {
+    sprintf (CatdirPhotcodeFile, "%s/Photcodes.dat", catdir);
+  }
+
+  if (VarConfig ("PHOTCODE_FILE", "%s", MasterPhotcodeFile) == (char *) NULL) {
+    gprint (GP_ERR, "PHOTCODE_FILE undefined in config\n");
+    return (FALSE);
+  }
+
+  // XXX now that DVO does not allow write access, we can drop the MasterPhotcodeFile
+  if (!LoadPhotcodes (CatdirPhotcodeFile, MasterPhotcodeFile, FALSE)) {
+    gprint (GP_ERR, "error loading photcode table %s or master file %s\n", CatdirPhotcodeFile, MasterPhotcodeFile);
+    return (FALSE);
+  }
+  return (TRUE);
+}
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/photometry.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/photometry.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/photometry.c	(revision 37403)
@@ -41,4 +41,5 @@
   }
 
+# if (0)
 /* selection criteria */
 /* selections based on Measure quantities */
@@ -78,5 +79,7 @@
 static time_t TimeReference;
 static int TimeFormat;
-
+# endif
+
+# if (0)
 int GetTimeSelection (time_t *tz, time_t *te) {
   *tz = tzero;
@@ -298,39 +301,7 @@
   return;
 }
-
-/* (re)load photcodes from photcode table */
-int InitPhotcodes () {
-
-  double ZERO_POINT;
-  char MasterPhotcodeFile[256];
-  char CatdirPhotcodeFile[256];
-  char *catdir;
-
-  if (VarConfig ("ZERO_PT", "%lf", &ZERO_POINT) == (char *) NULL) {
-    gprint (GP_ERR, "ZERO_PT undefined in config\n");
-    return (FALSE);
-  }
-  SetZeroPoint (ZERO_POINT);
-
-  catdir = GetCATDIR();
-  if (catdir == NULL) {
-    CatdirPhotcodeFile[0] = 0;
-  } else {
-    sprintf (CatdirPhotcodeFile, "%s/Photcodes.dat", catdir);
-  }
-
-  if (VarConfig ("PHOTCODE_FILE", "%s", MasterPhotcodeFile) == (char *) NULL) {
-    gprint (GP_ERR, "PHOTCODE_FILE undefined in config\n");
-    return (FALSE);
-  }
-
-  // XXX now that DVO does not allow write access, we can drop the MasterPhotcodeFile
-  if (!LoadPhotcodes (CatdirPhotcodeFile, MasterPhotcodeFile, FALSE)) {
-    gprint (GP_ERR, "error loading photcode table %s or master file %s\n", CatdirPhotcodeFile, MasterPhotcodeFile);
-    return (FALSE);
-  }
-  return (TRUE);
-}
-
+# endif
+
+# if (0)
 int ListPhotSelections () {
 
@@ -1121,5 +1092,7 @@
   return (list);
 }
-
+# endif
+
+# if (0)
 double GetMeasure (int param, Average *average, Measure *measure, double mag) {
 
@@ -1135,8 +1108,8 @@
       break;
     case MEAS_RA: /* OK */
-      value = average[0].R - measure[0].dR / 3600.0;
+      value = measure[0].R;
       break;
     case MEAS_DEC: /* OK */
-      value = average[0].D - measure[0].dD / 3600.0;
+      value = measure[0].D;
       break;
     case MEAS_DOPHOT: /* OK */
@@ -1156,8 +1129,8 @@
       break;
     case MEAS_RA_OFFSET: /* OK */
-      value = measure[0].dR;
+      value = dvoOffsetR(measure, average);
       break;
     case MEAS_DEC_OFFSET: /* OK */
-      value = measure[0].dD;
+      value = dvoOffsetD(measure, average);
       break;
     case MEAS_FWHM: /* OK */
@@ -1172,6 +1145,6 @@
       value = measure[0].Xccd;
 # else
-      ra  = average[0].R - measure[0].dR / 3600.0;
-      dec = average[0].D - measure[0].dD / 3600.0;
+      ra  = measure[0].R;
+      dec = measure[0].D;
       image = MatchImageDVO (measure[0].t, measure[0].photcode, measure[0].imageID);
       if (image == NULL) break;
@@ -1185,6 +1158,6 @@
       value = measure[0].Yccd;
 # else
-      ra  = average[0].R - measure[0].dR / 3600.0;
-      dec = average[0].D - measure[0].dD / 3600.0;
+      ra  = measure[0].R;
+      dec = measure[0].D;
       image = MatchImageDVO (measure[0].t, measure[0].photcode, measure[0].imageID);
       if (image == NULL) break;
@@ -1195,6 +1168,6 @@
 # if 0
     case MEAS_XMOSAIC: /* OK */
-      ra  = average[0].R - measure[0].dR / 3600.0;
-      dec = average[0].D - measure[0].dD / 3600.0;
+      ra  = measure[0].R;
+      dec = measure[0].D;
       mosaic = MatchMosaic (measure[0].t, measure[0].photcode); // XXX not used anymore
       if (mosaic == NULL) break;
@@ -1203,6 +1176,6 @@
       break;
     case MEAS_YMOSAIC: /* OK */
-      ra  = average[0].R - measure[0].dR / 3600.0;
-      dec = average[0].D - measure[0].dD / 3600.0;
+      ra  = measure[0].R;
+      dec = measure[0].D;
       mosaic = MatchMosaic (measure[0].t, measure[0].photcode); // XXX not used anymore
       if (mosaic == NULL) break;
@@ -1214,4 +1187,5 @@
   return (value);
 }
+# endif
 
 /** the mosaic entries do not use the registered mosaic found 
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/pmeasure.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/pmeasure.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/pmeasure.c	(revision 37403)
@@ -203,15 +203,15 @@
 	if (TimeSelect && (catalog.measure[m+k].t > tzero + trange)) continue;
 	if ((PhotcodeClip != -1) && (catalog.measure[m+k].photcode != PhotcodeClip)) continue;
-	mag = PhotCat (&catalog.measure[m+k]);
+	mag = PhotCat (&catalog.measure[m+k], MAG_CLASS_PSF);
 	Zvec[Npts] = MIN (1.0, MAX (0.01, (mag - Mz) / Mr));
 	if (LimExclude && (Zvec[Npts] > 0.99)) continue;
 	if (Zvec[Npts] < 0.011) continue;
-	R = catalog.average[i].R - catalog.measure[m+k].dR/3600.0;
-	D = catalog.average[i].D - catalog.measure[m+k].dD/3600.0;
+	R = catalog.measure[m+k].R;
+	D = catalog.measure[m+k].D;
 	// XXX drop this check
 	if ((R < Rmin) || (R > Rmax) || (D < -90.0) || (D > 90.0)) {
 	  char *date;
 	  date = ohana_sec_to_date (catalog.measure[m+k].t);
-	  gprint (GP_LOG, "out: %f, %f : %s : (%f, %f) + (%f, %f)\n", R, D, date, catalog.average[i].R, catalog.average[i].D, catalog.measure[m+k].dR/3600.0, catalog.measure[m+k].dD/3600.0);
+	  gprint (GP_LOG, "out: %f, %f : %s : (%f, %f) + (%f, %f)\n", R, D, date, catalog.average[i].R, catalog.average[i].D, catalog.measure[m+k].R, catalog.measure[m+k].D);
 	  free (date);
 	}
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/subpix.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/subpix.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/dvo/subpix.c	(revision 37403)
@@ -138,5 +138,5 @@
     for (j = 0; j < Nmeasure; j++) {
       if (measure[j].t == Timage) { 
-	Mabs = PhotCat (&measure[j]);
+	Mabs = PhotCat (&measure[j], MAG_CLASS_PSF);
 	RD_to_XY (&X, &Y, Ra, Dec, &image[I].coords);
 	t = TimeValue (measure[j].t, TimeReference, TimeFormat);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/include/dvomath.h
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/include/dvomath.h	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/include/dvomath.h	(revision 37403)
@@ -170,4 +170,7 @@
 Vector      **ReadVectorTableFITS   PROTO((char *filename, char *extname, int *Nvec));
 
+int           VectorAssignData          PROTO((Vector **vec, char *type, void *data, int Nrows, int Nval));
+int           VectorAssignDataTranspose PROTO((Vector **vec, char *type, void *data, int Nrows, int Nval));
+
 /* buffer handling */
 Buffer       *InitBuffer            PROTO((void));
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/include/dvoshell.h
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/include/dvoshell.h	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/include/dvoshell.h	(revision 37403)
@@ -90,13 +90,4 @@
 int           wordhash              PROTO((char *word));
 
-int          GetMagMode             PROTO((char *string));
-PhotCode    *ParsePhotcodeField     PROTO((char *field, int *mode, int def));
-int          ParseMeasureField      PROTO((dbField *field, char *fieldName));
-int          ParseAverageField      PROTO((dbField *field, char *fieldName));
-int          ParseImageField        PROTO((dbField *field, char *fieldName));
-
-dbValue      dbExtractMeasures      PROTO((Average *average, SecFilt *secfilt, Measure *measure, dbField *field));
-dbValue      dbExtractImages        PROTO((Image *image, off_t Nimage, off_t N, dbField *field));
-
 int          HostTableLaunchJobs    PROTO((SkyList *sky, HostTable *table, char *basecmd, char *options, int VERBOSE));
 int          HostTableParallelOps   PROTO((SkyList *sky, int argc, char **argv, char *ResultFile, int ReadVectors, int Nelements, int VERBOSE));
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/include/shell.h
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/include/shell.h	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/include/shell.h	(revision 37403)
@@ -166,4 +166,6 @@
 // wrap readline in ohana mem functions:
 char         *opihi_readline            PROTO((char *prompt));
+
+int set_list_varname (char *line, char *base, int N, int excelStyle);
 
 /* gprint functions */
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/lib.shell/VectorIO.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/lib.shell/VectorIO.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/lib.shell/VectorIO.c	(revision 37403)
@@ -134,5 +134,5 @@
   FTable ftable;
 
-  int i, j, k;
+  int i, j;
   FILE *f = NULL;
 
@@ -202,20 +202,9 @@
     assert (status);
 
-# define ASSIGN_DATA(TYPE,OPTYPE) \
-    /* assign the data to the actual vector */ \
-    if (!strcmp (type, #TYPE)) { \
-      TYPE *Ptr = data;	    \
-      for (k = 0; k < Nrows; k++) { \
-	for (j = 0; j < Nval; j++, Ptr++) { \
-	  vec[Nvec + j][0].elements.OPTYPE[k] = *Ptr; \
-	} } }
-
-    // assign the data to the actual vector
-    ASSIGN_DATA(char,    Int);
-    ASSIGN_DATA(short,   Int);
-    ASSIGN_DATA(int,     Int);
-    ASSIGN_DATA(int64_t, Int);
-    ASSIGN_DATA(float,   Flt);
-    ASSIGN_DATA(double,  Flt);
+    if (!VectorAssignData(&vec[Nvec], type, data, Nrows, Nval)) {
+      // free unneeded things
+      gprint (GP_ERR, "trouble parsing data block type %s\n", type);
+      return (NULL);
+    }
 
     free (data);
@@ -241,2 +230,52 @@
 //  return (FALSE);
 }
+
+# define ASSIGN_DATA(TYPE,DTYPE,OPTYPE)	       \
+    /* assign the data to the actual vector */ \
+    if (!strcmp (type, #TYPE)) { \
+      DTYPE *Ptr = data;		    \
+      for (k = 0; k < Nrows; k++) { \
+	for (j = 0; j < Nval; j++, Ptr++) { \
+	  vec[j][0].elements.OPTYPE[k] = *Ptr; \
+	  } } return TRUE; }
+
+int VectorAssignData (Vector **vec, char *type, void *data, int Nrows, int Nval) {
+
+  int j, k;
+
+  // assign the data to the actual vector
+  ASSIGN_DATA(byte,    char,    Int);
+  ASSIGN_DATA(char,    char,    Int);
+  ASSIGN_DATA(short,   short,   Int);
+  ASSIGN_DATA(int,     int,     Int);
+  ASSIGN_DATA(int64_t, int64_t, Int);
+  ASSIGN_DATA(float,   float,   Flt);
+  ASSIGN_DATA(double,  double,  Flt);
+
+  return FALSE;
+}
+
+# define ASSIGN_DATA_TRANSPOSE(TYPE,DTYPE,OPTYPE)	\
+    /* assign the data to the actual vector */ \
+    if (!strcmp (type, #TYPE)) { \
+      DTYPE *Ptr = data;		    \
+      for (k = 0; k < Nrows; k++) { \
+	for (j = 0; j < Nval; j++, Ptr++) { \
+	  vec[k][0].elements.OPTYPE[j] = *Ptr; \
+	  } } return TRUE; }
+
+int VectorAssignDataTranspose (Vector **vec, char *type, void *data, int Nrows, int Nval) {
+
+  int j, k;
+
+  // assign the data to the actual vector
+  ASSIGN_DATA_TRANSPOSE(byte,    char,    Int);
+  ASSIGN_DATA_TRANSPOSE(char,    char,    Int);
+  ASSIGN_DATA_TRANSPOSE(short,   short,   Int);
+  ASSIGN_DATA_TRANSPOSE(int,     int,     Int);
+  ASSIGN_DATA_TRANSPOSE(int64_t, int64_t, Int);
+  ASSIGN_DATA_TRANSPOSE(float,   float,   Flt);
+  ASSIGN_DATA_TRANSPOSE(double,  double,  Flt);
+
+  return FALSE;
+}
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/lib.shell/string.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/lib.shell/string.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/lib.shell/string.c	(revision 37403)
@@ -322,2 +322,31 @@
 }
 
+int set_list_varname (char *line, char *base, int N, int excelStyle) {
+
+  int i;
+    
+  // A-Z correspond to 0 - 25
+
+  if (excelStyle) {
+    float f = log(26.0);
+    float g = (N == 0) ? 0.0 : log(1.0*N);
+    int Ndigit = (int) (g / f) + 1;
+    if (Ndigit > 10) {
+      sprintf (line, "%s:ZZZZZZZZZZ", base);
+      return FALSE;
+    }
+    char name[12];
+    memset (name, 0, 12);
+    for (i = 0; i < Ndigit; i++) {
+      float Npow = Ndigit - i - 1;
+      float g = pow(26.0, Npow);
+      int V = (int) (N / g);
+      name[i] = (Npow == 0.0) ? 'A' + V : 'A' + V - 1;
+      N -= V * g;
+    }
+    sprintf (line, "%s:%s", base, name);
+  } else {
+    sprintf (line, "%s:%d", base, N);
+  }
+  return TRUE;
+}
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/pcontrol/PclientCommand.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/pcontrol/PclientCommand.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/opihi/pcontrol/PclientCommand.c	(revision 37403)
@@ -25,5 +25,5 @@
     return (PCLIENT_DOWN);
   }
-  
+
   // prepare host to accept response
   host[0].response_state = response_state;
@@ -35,5 +35,5 @@
   return (PCLIENT_GOOD);
 }
-  
+
 // check for response; message must end with specified string.
 // accumulate the response in the buffer
@@ -47,4 +47,6 @@
   ASSERT (response != NULL, "response missing");
   ASSERT (buffer != NULL, "buffer missing");
+
+  // INITTIME;
 
   /* avoid blocking very long on read, test every 100 usec, up to 0.1 sec */
@@ -66,6 +68,12 @@
     return (PCLIENT_DOWN);
   }
-  if (line == NULL) return (PCLIENT_HUNG);
-  if (status == -1) return (PCLIENT_HUNG);
+  if (line == NULL) {
+      // MARKTIME ("-- client hung (line NULL): %s : %f sec\n", host[0].hostname, dtime);
+      return (PCLIENT_HUNG);
+  }
+  if (status == -1) {
+      // MARKTIME ("-- client hung (status -1): %s : %f sec\n", host[0].hostname, dtime);
+      return (PCLIENT_HUNG);
+  }
 
   // fprintf (stderr, "response: %s\n", buffer[0].buffer);
@@ -75,5 +83,5 @@
 
 /* memstr returns a view, not an allocated string : don't free */
-/* ReadtoIOBuffer returns : 
+/* ReadtoIOBuffer returns :
     0 - pipe closed
    -1 - no more data in pipe, data not ready
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/photdbc/Makefile
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/photdbc/Makefile	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/photdbc/Makefile	(revision 37403)
@@ -31,4 +31,5 @@
 $(SRC)/args.$(ARCH).o		   \
 $(SRC)/copy_images.$(ARCH).o	   \
+$(SRC)/select_images.$(ARCH).o	   \
 $(SRC)/Shutdown.$(ARCH).o          \
 $(SRC)/join_stars.$(ARCH).o        \
@@ -41,5 +42,4 @@
 $(SRC)/ConfigInit.$(ARCH).o	   \
 $(SRC)/args.$(ARCH).o		   \
-$(SRC)/copy_images.$(ARCH).o	   \
 $(SRC)/Shutdown.$(ARCH).o          \
 $(SRC)/join_stars.$(ARCH).o        \
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/photdbc/include/photdbc.h
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/photdbc/include/photdbc.h	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/photdbc/include/photdbc.h	(revision 37403)
@@ -20,4 +20,11 @@
   int    Nmeas;
 } StatType;
+
+typedef struct {
+  double Xc[5];
+  double Yc[5];
+  double Rc;
+  double Dc;
+} SkyRegionCoords;
 
 int    PARALLEL;
@@ -80,7 +87,7 @@
 PhotCodeData photcodes;
 
-char          *PHOTCODE_DROP_LIST, *PHOTCODE_SKIP_LIST;
-int           NphotcodesDrop,      NphotcodesSkip;
-PhotCode     **photcodesDrop,     **photcodesSkip;
+char          *PHOTCODE_DROP_LIST, *PHOTCODE_KEEP_LIST;
+int           NphotcodesDrop,      NphotcodesKeep;
+PhotCode     **photcodesDrop,     **photcodesKeep;
 
 # define FLAG_AREA            0X0001
@@ -131,6 +138,11 @@
 void SetProtect (int mode);
 int SetSignals (void);
-int copy_images (char *outdir);
+int copy_images (char *outdir, SkyList *skylist);
 void usage();
+
+void dsortindex (double *X, off_t *Y, int N);
+off_t getRegionStartByRA (double R, double *Rref, off_t Nregions);
+
+Image *select_images (SkyList *skylist, Image *timage, off_t Ntimage, off_t **LineNumber, off_t *Nimage, int UseFullOverlap);
 
 int photdbc_catalogs (char *outroot, SkyList *skylist, int hostID);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/photdbc/src/args.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/photdbc/src/args.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/photdbc/src/args.c	(revision 37403)
@@ -85,4 +85,5 @@
   }
 
+  // measurements with these photcodes are not copied to the output
   PHOTCODE_DROP_LIST = NULL;
   if ((N = get_argument (argc, argv, "-photcode-drop"))) {
@@ -92,8 +93,11 @@
   }
 
-  PHOTCODE_SKIP_LIST = NULL;
-  if ((N = get_argument (argc, argv, "-photcode-skip"))) {
-    remove_argument (N, &argc, argv);
-    PHOTCODE_SKIP_LIST = strcreate(argv[N]);
+  // measurements with these photcodes are kept ***regardless of quality***
+  // -photcode-keep J will keep all J-band measurements of all kinds
+  // -photcode-keep GPC1.02.g will keep all g-band measurements from chip XY02
+  PHOTCODE_KEEP_LIST = NULL;
+  if ((N = get_argument (argc, argv, "-photcode-keep"))) {
+    remove_argument (N, &argc, argv);
+    PHOTCODE_KEEP_LIST = strcreate(argv[N]);
     remove_argument (N, &argc, argv);
   }
@@ -254,8 +258,8 @@
   }
 
-  PHOTCODE_SKIP_LIST = NULL;
-  if ((N = get_argument (argc, argv, "-photcode-skip"))) {
-    remove_argument (N, &argc, argv);
-    PHOTCODE_SKIP_LIST = strcreate(argv[N]);
+  PHOTCODE_KEEP_LIST = NULL;
+  if ((N = get_argument (argc, argv, "-photcode-keep"))) {
+    remove_argument (N, &argc, argv);
+    PHOTCODE_KEEP_LIST = strcreate(argv[N]);
     remove_argument (N, &argc, argv);
   }
@@ -290,5 +294,5 @@
   
   fprintf (stderr, " -photcode-drop   : remove these photcodes from the output (REF or DEP only)\n");
-  fprintf (stderr, " -photcode-skip  : ignore these photcodes when assessing the validity (keep unless object is dropped)\n");
+  fprintf (stderr, " -photcode-keep  : ignore these photcodes when assessing the validity (keep unless object is dropped)\n");
 
   fprintf (stderr, " -instmag (min) (max) : range of valid instrumental magnitudes (or measurements are dropped)\n");
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/photdbc/src/copy_images.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/photdbc/src/copy_images.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/photdbc/src/copy_images.c	(revision 37403)
@@ -1,13 +1,14 @@
 # include "photdbc.h"
 
-int copy_images (char *outdir) {
+int copy_images (char *outdir, SkyList *skylist) {
 
   int status;
-  off_t Nimage;
+  off_t Nimage, Nsubset;
+  off_t *LineNumber;
   char *ImageOut;
   unsigned int imageID;
   FITS_DB in;
   FITS_DB out;
-  Image *image;
+  Image *image, *subset;
   struct stat filestat;
   char *path;
@@ -50,5 +51,8 @@
       exit (2);
   }
-  dvo_image_addrows (&out, image, Nimage);
+
+  subset = select_images (skylist, image, Nimage, &LineNumber, &Nsubset, FALSE);
+
+  dvo_image_addrows (&out, subset, Nsubset);
 
   // note that imageID is unsigned int
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/photdbc/src/get_mags.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/photdbc/src/get_mags.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/photdbc/src/get_mags.c	(revision 37403)
@@ -22,5 +22,5 @@
       catalog[0].secfilt[i*Nsecfilt+j].M  = NAN;
       catalog[0].secfilt[i*Nsecfilt+j].dM = NAN;
-      catalog[0].secfilt[i*Nsecfilt+j].Xm = NAN_S_SHORT;
+      catalog[0].secfilt[i*Nsecfilt+j].Mchisq = NAN;
     }
   }
@@ -56,6 +56,6 @@
       Mval = (Nsec == -1) ? &catalog[0].average[i].dM : &catalog[0].secfilt[i*Nsecfilt+Nsec].dM;
       *Mval = stats.sigma;
-      Mval = (Nsec == -1) ? &catalog[0].average[i].Xm : &catalog[0].secfilt[i*Nsecfilt+Nsec].Xm;
-      *Mval = 100.0*log10(stats.chisq);
+      Mval = (Nsec == -1) ? &catalog[0].average[i].Mchisq : &catalog[0].secfilt[i*Nsecfilt+Nsec].Mchisq;
+      *Mval = stats.chisq;
     }
   }
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/photdbc/src/initialize.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/photdbc/src/initialize.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/photdbc/src/initialize.c	(revision 37403)
@@ -13,5 +13,5 @@
 
   photcodesDrop = ParsePhotcodeList (PHOTCODE_DROP_LIST, &NphotcodesDrop, FALSE);
-  photcodesSkip = ParsePhotcodeList (PHOTCODE_SKIP_LIST, &NphotcodesSkip, FALSE);
+  photcodesKeep = ParsePhotcodeList (PHOTCODE_KEEP_LIST, &NphotcodesKeep, FALSE);
 
   if (SHOW_PARAMS) {
@@ -54,5 +54,5 @@
 
   photcodesDrop = ParsePhotcodeList (PHOTCODE_DROP_LIST, &NphotcodesDrop, FALSE);
-  photcodesSkip = ParsePhotcodeList (PHOTCODE_SKIP_LIST, &NphotcodesSkip, FALSE);
+  photcodesKeep = ParsePhotcodeList (PHOTCODE_KEEP_LIST, &NphotcodesKeep, FALSE);
 
   if (SHOW_PARAMS) {
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/photdbc/src/join_stars.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/photdbc/src/join_stars.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/photdbc/src/join_stars.c	(revision 37403)
@@ -3,5 +3,5 @@
 void join_stars (Catalog *catalog) {
 
-  off_t i, j, k, m, M, Ni, Nj, first_j, Nfirst;
+  off_t i, j, k, m, Ni, Nj, first_j;
   off_t Naves, Nmeas, Ncurr;
   off_t Naverage, Nmeasure, *index;
@@ -109,6 +109,6 @@
 	mpointer[Nmeas].measure = m;
 	mpointer[Nmeas].averef  = Naves;
-	mpointer[Nmeas].R       = average[Ni].R - measure[m].dR / 3600.0;
-	mpointer[Nmeas].D       = average[Ni].D - measure[m].dD / 3600.0;
+	mpointer[Nmeas].R       = measure[m].R;
+	mpointer[Nmeas].D       = measure[m].D;
 	Nmeas ++;
       }
@@ -155,9 +155,8 @@
 	  mpointer[Nmeas].measure = m;
 	  mpointer[Nmeas].averef  = Ncurr;
-	  mpointer[Nmeas].R       = average[Nj].R - measure[m].dR / 3600.0;
-	  mpointer[Nmeas].D       = average[Nj].D - measure[m].dD / 3600.0;
+	  mpointer[Nmeas].R       = measure[m].R;
+	  mpointer[Nmeas].D       = measure[m].D;
 	  Nmeas ++;
 	}
-	Nfirst = average[Nj].Nmeasure;
 	naverage[Ncurr].Nmeasure += average[Nj].Nmeasure;
 	found[j] = TRUE;
@@ -178,10 +177,10 @@
 
 	/* update original measurement offsets for new detections */
-	for (k = Nfirst; k < naverage[Ncurr].Nmeasure; k++) {
-	  m = naverage[Ncurr].measureOffset + k;
-	  M = mpointer[m].measure;
-	  measure[M].dR = 3600.0*(Sr - mpointer[m].R);
-	  measure[M].dD = 3600.0*(Sd - mpointer[m].D);
-	}
+	// for (k = Nfirst; k < naverage[Ncurr].Nmeasure; k++) {
+	//   m = naverage[Ncurr].measureOffset + k;
+	//   M = mpointer[m].measure;
+	//   measure[M].dR = 3600.0*(Sr - mpointer[m].R);
+	//   measure[M].dD = 3600.0*(Sd - mpointer[m].D);
+	// }
 
 	/* update current reference star position */
@@ -189,10 +188,11 @@
 # else
 	/* update original measurement offsets for new detections */
-	for (k = Nfirst; k < naverage[Ncurr].Nmeasure; k++) {
-	  m = naverage[Ncurr].measureOffset + k;
-	  M = mpointer[m].measure;
-	  measure[M].dR = 3600.0*(naverage[Ncurr].R - mpointer[m].R);
-	  measure[M].dD = 3600.0*(naverage[Ncurr].D - mpointer[m].D);
-	}
+	// now not needed measure[M] carries R,D
+	// for (k = Nfirst; k < naverage[Ncurr].Nmeasure; k++) {
+	//   m = naverage[Ncurr].measureOffset + k;
+	//   M = mpointer[m].measure;
+	//   measure[M].dR = 3600.0*(naverage[Ncurr].R - mpointer[m].R);
+	//   measure[M].dD = 3600.0*(naverage[Ncurr].D - mpointer[m].D);
+	// }
 # endif
       }
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/photdbc/src/make_subcatalog.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/photdbc/src/make_subcatalog.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/photdbc/src/make_subcatalog.c	(revision 37403)
@@ -9,5 +9,5 @@
   off_t NAVERAGE, NMEASURE, Naverage, Nmeasure, Nm, Nsecfilt;
   double mag, minMag, minSigma;
-  int keep, *secSkip;
+  int keep, *secKeep;
   PhotCode *photcode;
   
@@ -16,11 +16,11 @@
 
   // set up a list of SEC entries to ignore when evaluating a source
-  ALLOCATE (secSkip, int, Nsecfilt);
+  ALLOCATE (secKeep, int, Nsecfilt);
   for (i = 0; i < Nsecfilt; i++) {
-      secSkip[i] = FALSE;
+      secKeep[i] = FALSE;
       photcode = GetPhotcodebyNsec(i);
-      for (k = 0; k < NphotcodesSkip; k++) {
-	  if (photcodesSkip[k][0].code != photcode[0].code) continue; 
-	  secSkip[i] = TRUE;
+      for (k = 0; k < NphotcodesKeep; k++) {
+	  if (photcodesKeep[k][0].code != photcode[0].code) continue; 
+	  secKeep[i] = TRUE;
       }
   }
@@ -67,5 +67,5 @@
       keep = FALSE;
       for (j = 0; !keep && (j < Nsecfilt); j++) {
-	  if (secSkip[j]) continue;
+	  if (secKeep[j]) continue;
 	  if (catalog[0].secfilt[Nsecfilt*i+j].Ncode >= NCODE_MIN) {
 	      keep = TRUE;
@@ -101,7 +101,7 @@
       if (NphotcodesDrop > 0) {
 	  found = FALSE;
-	  for (k = 0; (k < NphotcodesSkip) && !found; k++) {
-	      if (photcodesSkip[k][0].code == catalog[0].measure[offset].photcode) found = TRUE;
-	      if (photcodesSkip[k][0].code == GetPhotcodeEquivCodebyCode(catalog[0].measure[offset].photcode)) found = TRUE;
+	  for (k = 0; (k < NphotcodesDrop) && !found; k++) {
+	      if (photcodesDrop[k][0].code == catalog[0].measure[offset].photcode) found = TRUE;
+	      if (photcodesDrop[k][0].code == GetPhotcodeEquivCodebyCode(catalog[0].measure[offset].photcode)) found = TRUE;
 	  }
 	  if (found) continue;
@@ -109,9 +109,9 @@
   
       // ignore certain photcodes to assess the measurements
-      if (NphotcodesSkip > 0) {
+      if (NphotcodesKeep > 0) {
 	  found = FALSE;
-	  for (k = 0; (k < NphotcodesSkip) && !found; k++) {
-	      if (photcodesSkip[k][0].code == catalog[0].measure[offset].photcode) found = TRUE;
-	      if (photcodesSkip[k][0].code == GetPhotcodeEquivCodebyCode(catalog[0].measure[offset].photcode)) found = TRUE;
+	  for (k = 0; (k < NphotcodesKeep) && !found; k++) {
+	      if (photcodesKeep[k][0].code == catalog[0].measure[offset].photcode) found = TRUE;
+	      if (photcodesKeep[k][0].code == GetPhotcodeEquivCodebyCode(catalog[0].measure[offset].photcode)) found = TRUE;
 	  }
 	  if (found) goto keep;
@@ -123,5 +123,5 @@
       // select measurements by mag limit -- drop exactly this measurement  
       if (ExcludeByInstMag) {
-	mag = PhotInst (&catalog[0].measure[offset]);
+	mag = PhotInst (&catalog[0].measure[offset], MAG_CLASS_PSF);
 	if (mag < INST_MAG_MIN) continue;
 	if (mag > INST_MAG_MAX) continue;
@@ -135,5 +135,5 @@
       // check measurements for this object -- drop object if no measurements pass
       if (ExcludeByMaxMinMag) {
-	mag = PhotSys (&catalog[0].measure[offset], &catalog[0].average[i], &catalog[0].secfilt[i*Nsecfilt]);
+	mag = PhotSys (&catalog[0].measure[offset], &catalog[0].average[i], &catalog[0].secfilt[i*Nsecfilt], MAG_CLASS_PSF);
 	minMag = MIN (minMag, mag);
       }
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/photdbc/src/photdbc.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/photdbc/src/photdbc.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/photdbc/src/photdbc.c	(revision 37403)
@@ -9,11 +9,11 @@
   initialize (argc, argv);
 
-  // load and copy the image table
-  copy_images (argv[1]);
-
   // the output catalog needs to inherit the SKY_DEPTH of the input catalog
   sky = SkyTableLoadOptimal (CATDIR, NULL, NULL, TRUE, 0, VERBOSE);
   SkyTableSetFilenames (sky, CATDIR, "cpt");
   skylist = SkyListByPatch (sky, -1, &REGION);
+
+  // load and copy the image table
+  copy_images (argv[1], skylist);
 
   // hostID is 0 for master program
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/photdbc/src/photdbc_catalogs.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/photdbc/src/photdbc_catalogs.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/photdbc/src/photdbc_catalogs.c	(revision 37403)
@@ -120,5 +120,5 @@
     if (ExcludeByMaxMinMag) { snprintf (tmpline, DVO_MAX_PATH, "%s -maxminmag %f",     command, MAX_MIN_MAG);    	        strcpy (command, tmpline); }
     if (PHOTCODE_DROP_LIST) { snprintf (tmpline, DVO_MAX_PATH, "%s -photcode-drop %s", command, PHOTCODE_DROP_LIST); 	strcpy (command, tmpline); }
-    if (PHOTCODE_SKIP_LIST) { snprintf (tmpline, DVO_MAX_PATH, "%s -photcode-skip %s", command, PHOTCODE_SKIP_LIST); 	strcpy (command, tmpline); }
+    if (PHOTCODE_KEEP_LIST) { snprintf (tmpline, DVO_MAX_PATH, "%s -photcode-keep %s", command, PHOTCODE_KEEP_LIST); 	strcpy (command, tmpline); }
     if (CATFORMAT)          { snprintf (tmpline, DVO_MAX_PATH, "%s -set-format %s",    command, CATFORMAT); 	                strcpy (command, tmpline); }
     if (CATMODE)            { snprintf (tmpline, DVO_MAX_PATH, "%s -set-mode %s",      command, CATMODE);        	        strcpy (command, tmpline); }
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/photdbc/src/select_images.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/photdbc/src/select_images.c	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/photdbc/src/select_images.c	(revision 37403)
@@ -0,0 +1,234 @@
+# include "photdbc.h"
+
+/* this function returns a list of all images which overlap the given SkyList (set of
+   SkyRegions).  All images in the image catalog are tested once, so there is no check that an
+   image already has been included.  LineNum stores the locations in the Image database of the
+   list of images */
+
+Image *select_images (SkyList *skylist, Image *timage, off_t Ntimage, off_t **LineNumber, off_t *Nimage, int UseFullOverlap) {
+  
+  Image *image;
+  off_t i, j, k, nimage, NIMAGE, D_NIMAGE;
+  off_t *line_number;
+  int found;
+  double Ri[5], Di[5], Xi[5], Yi[5], dx, dy;
+  Coords tcoords;
+  SkyRegionCoords *skycoords;
+  
+  double RmaxSkyRegion, RminSkyRegion, RmidSkyRegion, DminSkyRegion, DmaxSkyRegion;
+
+  double *RmaxSky;
+  off_t *index;
+
+  if (skylist[0].Nregions < 1) {
+    *Nimage = 0;
+    *LineNumber = NULL;
+    if (VERBOSE) fprintf (stderr, "no matching sky regions\n");
+    return NULL;
+  }
+
+  // if no region is selected, we are choosing the whole sky; I should sort-circuit
+  // this function in that case
+
+  INITTIME;
+
+  // the comparison is made in the catalog local projection. below we set crval1,2
+  tcoords.crpix1 = tcoords.crpix2 = 0.0;
+  tcoords.cdelt1 = tcoords.cdelt2 = 1.0 / 3600.0;
+  tcoords.pc1_1  = tcoords.pc2_2 = 1.0;
+  tcoords.pc1_2  = tcoords.pc2_1 = 0.0;
+  strcpy (tcoords.ctype, "DEC--TAN");
+
+  ALLOCATE (skycoords, SkyRegionCoords, skylist[0].Nregions);
+
+  ALLOCATE (RmaxSky, double, skylist[0].Nregions);
+  ALLOCATE (index, off_t, skylist[0].Nregions);
+
+  RminSkyRegion = +360.0;
+  RmaxSkyRegion = -360.0;
+  DminSkyRegion = +90.0;
+  DmaxSkyRegion = -90.0;
+
+  D_NIMAGE = 6000;
+
+  /* compare with each region file */
+  for (i = 0; i < skylist[0].Nregions; i++) { 
+
+    /* we make positional comparisons in the projection of catalog */
+    skycoords[i].Rc = 0.5*(skylist[0].regions[i][0].Rmax + skylist[0].regions[i][0].Rmin);
+    skycoords[i].Dc = 0.5*(skylist[0].regions[i][0].Dmax + skylist[0].regions[i][0].Dmin);
+    tcoords.crval1 = skycoords[i].Rc;
+    tcoords.crval2 = skycoords[i].Dc;
+
+    /* define catalog corners */
+    RD_to_XY (&skycoords[i].Xc[0], &skycoords[i].Yc[0], skylist[0].regions[i][0].Rmin, skylist[0].regions[i][0].Dmin, &tcoords);
+    RD_to_XY (&skycoords[i].Xc[1], &skycoords[i].Yc[1], skylist[0].regions[i][0].Rmax, skylist[0].regions[i][0].Dmin, &tcoords);
+    RD_to_XY (&skycoords[i].Xc[2], &skycoords[i].Yc[2], skylist[0].regions[i][0].Rmax, skylist[0].regions[i][0].Dmax, &tcoords);
+    RD_to_XY (&skycoords[i].Xc[3], &skycoords[i].Yc[3], skylist[0].regions[i][0].Rmin, skylist[0].regions[i][0].Dmax, &tcoords);
+    skycoords[i].Xc[4] = skycoords[i].Xc[0];    
+    skycoords[i].Yc[4] = skycoords[i].Yc[0];    
+
+    RmaxSky[i] = skylist[0].regions[i][0].Rmax;
+    index[i] = i;
+
+    dx = 0.02*(skycoords[i].Xc[2] - skycoords[i].Xc[0]);
+    dy = 0.02*(skycoords[i].Yc[2] - skycoords[i].Yc[0]);
+    skycoords[i].Xc[0] -= dx; skycoords[i].Yc[0] -= dy;
+    skycoords[i].Xc[1] += dx; skycoords[i].Yc[1] -= dy;
+    skycoords[i].Xc[2] += dx; skycoords[i].Yc[2] += dy;
+    skycoords[i].Xc[3] -= dx; skycoords[i].Yc[3] += dy;
+    skycoords[i].Xc[4] -= dx; skycoords[i].Yc[4] -= dy;
+
+    RminSkyRegion = MIN(RminSkyRegion, skylist[0].regions[i][0].Rmin);
+    RmaxSkyRegion = MAX(RmaxSkyRegion, skylist[0].regions[i][0].Rmax);
+    DminSkyRegion = MIN(DminSkyRegion, skylist[0].regions[i][0].Dmin);
+    DmaxSkyRegion = MAX(DmaxSkyRegion, skylist[0].regions[i][0].Dmax);
+  }
+  RmidSkyRegion = 0.5*(RminSkyRegion + RmaxSkyRegion);
+  MARKTIME("create sky region coords: %f sec\n", dtime);
+
+  dsortindex (RmaxSky, index, skylist[0].Nregions);
+  MARKTIME("sort sky coords: %f sec\n", dtime);
+
+  if (VERBOSE) fprintf (stderr, "finding images\n");
+  BuildChipMatch (timage, Ntimage);
+  MARKTIME("build chip match: %f sec\n", dtime);
+
+  nimage = 0;
+  NIMAGE = D_NIMAGE;
+  ALLOCATE (image, Image, NIMAGE);
+  ALLOCATE (line_number, off_t, NIMAGE);
+  
+  // go through the complete list of images, selecting ones which overlap any region
+  for (i = 0; i < Ntimage; i++) {
+      
+    /* exclude images by photcode, or equiv photcode, if specified */
+    if (NphotcodesDrop > 0) {
+      if (timage[i].photcode == 0) goto keep_image; // PHU image can be immediately passed in here
+      found = FALSE; // here 'found' refers to a match to a drop photcode
+      for (k = 0; (k < NphotcodesDrop) && !found; k++) {
+	if (photcodesDrop[k][0].code == timage[i].photcode) found = TRUE;
+	if (photcodesDrop[k][0].code == GetPhotcodeEquivCodebyCode(timage[i].photcode)) found = TRUE;
+      }
+      if (found) continue;
+    }
+keep_image:
+
+    // this adds 1.3 sec for 3M images
+    if (!FindMosaicForImage (timage, Ntimage, i)) {
+      fprintf (stderr, "cannot find mosaic for "OFF_T_FMT"\n", i);
+      continue;
+    }
+
+    /* define image corners - note the DIS images (mosaic phu) are special */
+    if (!strcmp(&timage[i].coords.ctype[4], "-DIS")) {
+      Xi[0] = -0.5*timage[i].NX; Yi[0] = -0.5*timage[i].NY;
+      Xi[1] = +0.5*timage[i].NX; Yi[1] = -0.5*timage[i].NY;
+      Xi[2] = +0.5*timage[i].NX; Yi[2] = +0.5*timage[i].NY;
+      Xi[3] = -0.5*timage[i].NX; Yi[3] = +0.5*timage[i].NY;
+      Xi[4] = -0.5*timage[i].NX; Yi[4] = -0.5*timage[i].NY;
+    } else {
+      Xi[0] = 0;            Yi[0] = 0;
+      Xi[1] = timage[i].NX; Yi[1] = 0;
+      Xi[2] = timage[i].NX; Yi[2] = timage[i].NY;
+      Xi[3] = 0;            Yi[3] = timage[i].NY;
+      Xi[4] = 0;            Yi[4] = 0;
+    }
+    found = FALSE;
+
+    /* transform corners to ra,dec -- costs ~3sec for 3M images (pikake) */
+    double RminImage = RmidSkyRegion + 180.0;
+    double RmaxImage = RmidSkyRegion - 180.0;
+    double DminImage = +90.0;
+    double DmaxImage = -90.0;
+    for (j = 0; j < 5; j++) {
+      XY_to_RD (&Ri[j], &Di[j], Xi[j], Yi[j], &timage[i].coords);
+      Ri[j] = ohana_normalize_angle_to_midpoint (Ri[j], RmidSkyRegion);
+
+      RminImage = MIN(RminImage, Ri[j]);
+      RmaxImage = MAX(RmaxImage, Ri[j]);
+      DminImage = MIN(DminImage, Di[j]);
+      DmaxImage = MAX(DmaxImage, Di[j]);
+    }
+    if (RmaxImage - RminImage > 180.0) {
+	double tmp = RminImage;
+	RmaxImage = RminImage;
+	RminImage = tmp - 360.0;
+    }
+
+    // check that this image is even in range of the searched region
+    if (DminImage > DmaxSkyRegion) continue;
+    if (DmaxImage < DminSkyRegion) continue;
+    
+    // the sky region RA is defined to be 0 - 360.0
+    if (RminImage > RmaxSkyRegion) continue;
+    if (RmaxImage < RminSkyRegion) continue;
+
+    // require that the full image be inside the region of interest (only for non PHU
+    // images) XXX : if we calibrate the mosaic, require that the full mosaic be inside
+    // the region and all of its chips..
+    if (UseFullOverlap && strcmp(&timage[i].coords.ctype[4], "-DIS")) {
+      if (RmaxImage > REGION.Rmax) continue;
+      if (RminImage < REGION.Rmin) continue;
+      if (DmaxImage > REGION.Dmax) continue;
+      if (DminImage < REGION.Dmin) continue;
+    }
+
+    image[nimage] = timage[i]; 
+    line_number[nimage] = i;
+    nimage ++;
+    if (nimage == NIMAGE) {
+      NIMAGE += D_NIMAGE;
+      D_NIMAGE = MAX (100000, D_NIMAGE * 1.5);
+      REALLOCATE (image, Image, NIMAGE);
+      REALLOCATE (line_number, off_t, NIMAGE);
+    }
+  }
+  MARKTIME("finish image selection: %f sec\n", dtime);
+
+  if (VERBOSE) fprintf (stderr, "found "OFF_T_FMT" images\n", nimage);
+
+  REALLOCATE (image, Image, MAX (nimage, 1));
+  REALLOCATE (line_number, off_t, MAX (nimage, 1));
+  free (skycoords);
+  free (RmaxSky);
+  free (index);
+
+  *Nimage  = nimage;
+  *LineNumber = line_number;
+  return (image);
+}
+
+void dsortindex (double *X, off_t *Y, int N) {
+
+# define SWAPFUNC(A,B){ double tmpf; off_t tmpi; \
+  tmpf = X[A]; X[A] = X[B]; X[B] = tmpf; \
+  tmpi = Y[A]; Y[A] = Y[B]; Y[B] = tmpi; \
+}
+# define COMPARE(A,B)(X[A] < X[B])
+
+  OHANA_SORT (N, COMPARE, SWAPFUNC);
+
+# undef SWAPFUNC
+# undef COMPARE
+
+}
+
+off_t getRegionStartByRA (double R, double *Rref, off_t Nregions) {
+
+  // use bisection to find the overlapping mosaic
+
+  off_t Nlo, Nhi, N;
+
+  // find the last mosaic before start
+  Nlo = 0; Nhi = Nregions;
+  while (Nhi - Nlo > 10) {
+    N = 0.5*(Nlo + Nhi);
+    if (Rref[N] < R) {
+      Nlo = MAX(N, 0);
+    } else {
+      Nhi = MIN(N, Nregions);
+    }
+  }
+  return (Nlo);
+}
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/Makefile
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/Makefile	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/Makefile	(revision 37403)
@@ -59,4 +59,5 @@
 $(SRC)/save_catalogs.$(ARCH).o       \
 $(SRC)/CoordOps.$(ARCH).o            \
+$(SRC)/extra.$(ARCH).o            \
 $(SRC)/FixProblemImages.$(ARCH).o    \
 $(SRC)/StarMaps.$(ARCH).o    \
@@ -117,4 +118,5 @@
 $(SRC)/save_catalogs.$(ARCH).o       \
 $(SRC)/CoordOps.$(ARCH).o            \
+$(SRC)/extra.$(ARCH).o            \
 $(SRC)/high_speed_catalogs.$(ARCH).o  \
 $(SRC)/high_speed_objects.$(ARCH).o  \
@@ -127,4 +129,5 @@
 $(SRC)/plotstuff.$(ARCH).o	     \
 $(SRC)/relastroVisual.$(ARCH).o \
+$(SRC)/syncfile.$(ARCH).o \
 $(SRC)/BrightCatalog.$(ARCH).o 
 
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/doc/pv2.txt
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/doc/pv2.txt	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/doc/pv2.txt	(revision 37403)
@@ -0,0 +1,121 @@
+
+2014.07.03
+
+Thinking some more about the galactic rotation / solar motion based
+tie of relastro.  What do I need in the db to do this process?  Here
+is an outline:
+
+* generate the PS1 + 2MASS (+ other) database
+
+* ingest the stellar distances from greg.  this boils down to distance
+  (or parallax) + error.  These values exist for ~500M objects, so a
+  non-trivial fraction of the db.  I suppose the easiest way to handle
+  this is as an extra 2 fields in average.d.  The correct (database)
+  way to do this would be to define another table with objID, par,
+  dpar, refID
+
+* a stand-alone process like setastrom would run through the database
+  and set the RoffGAL,DoffGAL offsets.
+
+** I have a model for the motion, but I will need to choose a
+   reference date.  I suppose it does not matter too much in detail,
+   but obviously I should not choose J1900.  I assume I should choose
+   something like the mean epoch (but it needs to be a single epoch
+   for the survey).  so, eg, 2012.01.01.  So, I use the model to
+   predict the offset for the given distance in the dR,dD direction.  
+
+ref: R,D -> P,Q -> L,M -> X,Y (average)
+raw: X,Y -> L,N -> P,Q -> R,D (measure)
+
+* fit is raw.X,Y -> ref.L,M
+
+* KHE : apply correction to raw.X,Y (I can calculate it for all stars
+
+* DCR : apply correction to raw.X,Y (need more than one color, can
+  calculate up front). choose a median color and airmass?  
+
+* GAL : I want the transformation of a given image to convert X,Y to
+  R,D for that epoch. This really says I need to apply the proper
+  motion offset to the ref.R,D so ref.L,M is a prediction of the true
+  position.
+
+* QSO : I have the QSO coordinates in the db as specific measurments
+  with their own photcode(s).  During the iteration, extract all
+  average.R,D for the QSOs and their specific measurements.  Fit
+  Y(l,m) to dR,dD.  Find the significant entries (how).  Subtract the
+  offsets from ALL average.R,D values??
+
+---------------------------------------------------
+
+* external steps:
+
+  * set the KHE X,Y offset values
+  * set the DCR X,Y offset values
+  * ingest the GAL P,dP values, set the GAL dR,dD values
+
+* relastro loop
+  * update objects
+  * fit & apply the QSO correction
+  * update chips
+
+  ** I need to do a better job of tracking the change from each
+     iteration.
+
+  ** add a bunch of visualizations to demonstrate the quality  
+
+2014.07.01
+
+I had a nice conversation with Valeri Makarov about astrometric
+calibration.  I have committed to send them the qsos matched to ps1
+positions.
+
+some things Valeri raised:
+
+1) if I make the QSOs into hard points, then they will drive the
+solution have to a peak consistency at that location.  thus errors
+will build up away from those points, with potential ringing.  His
+suggestion is to use a set of spherical harmonics to fit the residual
+between the QSO positions and relastro fitted position and to correct
+based on this model fit. 
+
+How exactly that works is not completely clear to me.  I imaging doing
+something iteratively.  my sequence is basically:
+
+1) fit the image parameters
+2) determine the per-epoch R,D values
+3) determine mean positions
+4) fit the Ylms between QSO radio positions (selected subset only)
+   and the new fitted R,D values 
+5) identify the significant Ylm terms, the negative of this is the
+   correction (actually, I'm fitting dR,dD = Y^D_lm, Y^R_lm
+6) adjust the mean positions for all objects based on the correction
+7) re-fit the images to these new positions
+8) back to step 2 and repeat...
+
+Clearly I can only do this (consistently) if I fit the entire sky (or
+as much as possible) in a single pass. I'll need to put some smarts
+into the relastro_parallel_regions to get this right.  But, also note
+that having the technology in place to apply the Ylms means that I can
+apply a correction from Valeri, if supplied.
+
+** What new fields do I need to handle this?  
+
+2) regarding the application of the Galactic rotation / solar motion
+model, Valeri raise the concern that different populations follow
+different rotation curves.  This is a good point, and an obvious one
+in retrospect.  In fact, we would like to be able to measure this.  
+
+Now, clearly Pop I and Pop II stars are very different in terms of
+rotation / stellar motions.   How much does this matter?
+Specifically, how much does solar motion matter vs the galactic
+rotation model?  Also, what fraction of my reference stars are likely
+to be giants instead of MS stars?  
+
+Some mitigation strategies:  
+
+1) attempt to use only stars in a modest range of colors and predicted
+distances? 
+2) ??
+
+NOTE: I need to get the QSOs from bertrand
+
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/include/relastro.h
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/include/relastro.h	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/include/relastro.h	(revision 37403)
@@ -5,13 +5,4 @@
 # include <assert.h>
 # include <pthread.h>
-
-# define MARKTIME(MSG,...) {			\
-    gettimeofday (&stopTimer, (void *) NULL);	\
-    float dtime = DTIME (stopTimer, startTimer);	\
-    fprintf (stderr, MSG, __VA_ARGS__); }
-
-# define INITTIME \
-  struct timeval startTimer, stopTimer; \
-  gettimeofday (&startTimer, (void *) NULL);
 
 // choose off_t or int depending on full-scale relphot analysis resources
@@ -83,7 +74,9 @@
   double L, M;  /* Focal Plane   - pixels  */
   double X, Y;  /* Chip Coords   - pixels  */
-  double Mag;
-  double dMag;
-  double dPos;
+  float Mag;
+  float ColorBlue;
+  float ColorRed;
+  float dMag;
+  float dPos;
   int mask;
   int Nmeas;
@@ -140,4 +133,12 @@
   int    Nmeas;
 } StatType;
+
+typedef struct {
+  off_t Nave;
+  off_t Npm;
+  off_t Npar;
+  off_t Nskip;
+  off_t Noffset;
+} FitStats;
 
 /* global variables set in parameter file */
@@ -207,7 +208,7 @@
 double MaxDensityValue;
 
-char          *PHOTCODE_KEEP_LIST, *PHOTCODE_SKIP_LIST;
-int           NphotcodesKeep,      NphotcodesSkip;
-PhotCode     **photcodesKeep,     **photcodesSkip;
+char          *PHOTCODE_KEEP_LIST, *PHOTCODE_SKIP_LIST, *PHOTCODE_RESET_LIST;
+int           NphotcodesKeep,      NphotcodesSkip,      NphotcodesReset;
+PhotCode     **photcodesKeep,     **photcodesSkip,     **photcodesReset;
 
 char          *PHOTCODE_A_LIST,  *PHOTCODE_B_LIST;
@@ -217,4 +218,12 @@
 SkyRegionSelection SELECTION;
 
+char         *DCR_BLUE_COLOR_POS,    *DCR_BLUE_COLOR_NEG;
+PhotCode     *DCR_BLUE_PHOTCODE_POS, *DCR_BLUE_PHOTCODE_NEG; 
+int           DCR_BLUE_NSEC_POS,      DCR_BLUE_NSEC_NEG; 
+
+char         *DCR_RED_COLOR_POS,    *DCR_RED_COLOR_NEG;
+PhotCode     *DCR_RED_PHOTCODE_POS, *DCR_RED_PHOTCODE_NEG; 
+int           DCR_RED_NSEC_POS,      DCR_RED_NSEC_NEG; 
+
 int ImagSelect;
 double ImagMin, ImagMax;
@@ -233,4 +242,7 @@
 int    CLIP_THRESH;
 int USE_BASIC_CHECK;
+
+int ExcludeBogus;
+double ExcludeBogusRadius;
 
 FitMode FIT_MODE;
@@ -307,5 +319,5 @@
 int           liststats           PROTO((double *value, double *dvalue, int N, StatType *stats));
 int           liststats_pos       PROTO((double *value, double *dvalue, int N, StatType *stats, int XVERB));
-Catalog      *load_catalogs       PROTO((SkyList *skylist, int *Ncatalog, int subselect, int hostID, char *hostpath));
+Catalog      *load_catalogs       PROTO((SkyList *skylist, int *Ncatalog, int subselect, int hostID, char *hostpath, char *syncfile));
 int           load_images         PROTO((FITS_DB *db, SkyList *skylist, int UseFullOverlap));
 Image        *select_images       PROTO((SkyList *skylist, Image *timage, off_t Ntimage, off_t **LineNumber, off_t *Nimage, int UseFullOverlap));
@@ -417,4 +429,6 @@
 int setMeanR (double ra_fit, MeasureTiny *measure, Average *average, SecFilt *secfilt);
 int setMeanD (double dec_fit, MeasureTiny *measure, Average *average, SecFilt *secfilt);
+double getMeanR_Big (Measure *measure, Average *average, SecFilt *secfilt);
+double getMeanD_Big (Measure *measure, Average *average, SecFilt *secfilt);
 int setMeanR_Big (double ra_fit, Measure *measure, Average *average, SecFilt *secfilt);
 int setMeanD_Big (double dec_fit, Measure *measure, Average *average, SecFilt *secfilt);
@@ -521,2 +535,14 @@
 int ImageTableSave (char *filename, Image *images, off_t Nimages);
 int select_mosaics_hostregion (RegionHostTable *regionHosts, Image *image, off_t Nimage);
+
+float getColorBlue (off_t meas, int cat);
+float getColorRed (off_t meas, int cat);
+
+int strextend (char *input, char *format,...);
+
+int areImagesLoaded ();
+int areImagesMatched ();
+
+int isGPC1chip (int photcode);
+int isGPC1stack (int photcode);
+int isGPC1warp (int photcode);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/BrightCatalog.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/BrightCatalog.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/BrightCatalog.c	(revision 37403)
@@ -68,6 +68,6 @@
  
     // need to create and assign to flat-field correction
-    GET_COLUMN(dR,        "RA_OFF",   	float);
-    GET_COLUMN(dD,        "DEC_OFF",  	float);
+    GET_COLUMN(R,         "RA",   	double);
+    GET_COLUMN(D,         "DEC",  	double);
     GET_COLUMN(M,         "MAG_SYS",  	float);
     GET_COLUMN(Mcal,      "MAG_CAL",  	float);
@@ -92,6 +92,6 @@
     ALLOCATE (measure, MeasureTiny, Nrow);
     for (i = 0; i < Nrow; i++) {
-      measure[i].dR        = dR[i];
-      measure[i].dD        = dD[i];
+      measure[i].R         = R[i];
+      measure[i].D         = D[i];
       measure[i].M         = M[i];
       measure[i].Mcal      = Mcal[i];
@@ -113,6 +113,6 @@
     // fprintf (stderr, "loaded data for %lld measures\n", (long long) Nrow);
 
-    free (dR      );
-    free (dD      );
+    free (R       );
+    free (D       );
     free (M       );
     free (Mcal    );
@@ -145,33 +145,34 @@
     if (!gfits_fread_ftable_data (f, &ftable, FALSE)) goto escape;
 
-    GET_COLUMN(R,              "RA",          double);
-    GET_COLUMN(D,              "DEC",         double);
-    GET_COLUMN(dR,             "RA_ERR",      float);
-    GET_COLUMN(dD,             "DEC_ERR",     float);
-    GET_COLUMN(uR,             "U_RA",        float);
-    GET_COLUMN(uD,             "U_DEC",       float);
-    GET_COLUMN(duR,            "V_RA_ERR",    float);
-    GET_COLUMN(duD,            "V_DEC_ERR",   float);
-    GET_COLUMN(P,              "PAR",         float);
-    GET_COLUMN(dP,             "PAR_ERR",     float);
-    GET_COLUMN(ChiSqAve,       "CHISQ_POS",   float);
-    GET_COLUMN(ChiSqPM,        "CHISQ_PM",    float);
-    GET_COLUMN(ChiSqPar,       "CHISQ_PAP",   float);
-    GET_COLUMN(Tmean,          "MEAN_EPOCH",  int);
-    GET_COLUMN(Trange,         "TIME_RANGE",  int);
-    GET_COLUMN(stargal,        "STARGAL_SEP", float);
-    GET_COLUMN(Npos,           "NUMBER_POS",  short);
-    GET_COLUMN(Nmeasure,       "NMEASURE",    short);
-    GET_COLUMN(Nmissing,       "NMISSING",    short);
-    GET_COLUMN(Nextend,        "NEXTEND",     short);
-    GET_COLUMN(measureOffset,  "OFF_MEASURE", int);
-    GET_COLUMN(missingOffset,  "OFF_MISSING", int);
-    GET_COLUMN(extendOffset,   "OFF_EXTEND",  int);
-    GET_COLUMN(flags,          "FLAGS",       int);
-    GET_COLUMN(photFlagsUpper, "PHOTFLAGS_U", int);
-    GET_COLUMN(photFlagsLower, "PHOTFLAGS_L", int);
-    GET_COLUMN(objID,          "OBJ_ID",      int);
-    GET_COLUMN(catID,          "CAT_ID",      int);
-    GET_COLUMN(extID,          "EXT_ID",      int64_t);
+    GET_COLUMN(R,              "RA",             double);
+    GET_COLUMN(D,              "DEC",            double);
+    GET_COLUMN(dR,             "RA_ERR",         float);
+    GET_COLUMN(dD,             "DEC_ERR",        float);
+    GET_COLUMN(uR,             "U_RA",           float);
+    GET_COLUMN(uD,             "U_DEC",          float);
+    GET_COLUMN(duR,            "V_RA_ERR",       float);
+    GET_COLUMN(duD,            "V_DEC_ERR",      float);
+    GET_COLUMN(P,              "PAR",            float);
+    GET_COLUMN(dP,             "PAR_ERR",        float);
+    GET_COLUMN(ChiSqAve,       "CHISQ_POS",      float);
+    GET_COLUMN(ChiSqPM,        "CHISQ_PM",       float);
+    GET_COLUMN(ChiSqPar,       "CHISQ_PAP",      float);
+    GET_COLUMN(Tmean,          "MEAN_EPOCH",     int);
+    GET_COLUMN(Trange,         "TIME_RANGE",     int);
+    GET_COLUMN(stargal,        "STARGAL_SEP",    float);
+    GET_COLUMN(Npos,           "NUMBER_POS",     short);
+    GET_COLUMN(Nmeasure,       "NMEASURE",       short);
+    GET_COLUMN(Nmissing,       "NMISSING",       short);
+    GET_COLUMN(Nextend,        "NEXTEND",        short);
+    GET_COLUMN(measureOffset,  "OFF_MEASURE",    int);
+    GET_COLUMN(missingOffset,  "OFF_MISSING",    int);
+    GET_COLUMN(refColorBlue,   "REF_COLOR_BLUE", float);
+    GET_COLUMN(refColorRed,    "REF_COLOR_RED",  float);
+    GET_COLUMN(flags,          "FLAGS",          int);
+    GET_COLUMN(photFlagsUpper, "PHOTFLAGS_U",    int);
+    GET_COLUMN(photFlagsLower, "PHOTFLAGS_L",    int);
+    GET_COLUMN(objID,          "OBJ_ID",         int);
+    GET_COLUMN(catID,          "CAT_ID",         int);
+    GET_COLUMN(extID,          "EXT_ID",         int64_t);
     gfits_free_header (&theader);
     gfits_free_table  (&ftable);
@@ -202,5 +203,6 @@
       average[i].measureOffset   = measureOffset[i]   ; 
       average[i].missingOffset   = missingOffset[i]   ; 
-      average[i].extendOffset    = extendOffset[i]    ;  
+      average[i].refColorBlue    = refColorBlue[i]    ;  
+      average[i].refColorRed     = refColorRed[i]     ;  
       average[i].flags           = flags[i]           ;
       average[i].photFlagsUpper  = photFlagsUpper[i]  ;
@@ -234,5 +236,6 @@
     free (measureOffset);
     free (missingOffset);
-    free (extendOffset);
+    free (refColorBlue);
+    free (refColorRed);
     free (flags);
     free (photFlagsUpper);
@@ -256,12 +259,12 @@
  
     // need to create and assign to flat-field correction
-    GET_COLUMN(M,     "MAG",      float);
-    GET_COLUMN(dM,    "MAG_ERR",  float);
-    GET_COLUMN(Xm,    "MAG_CHI",  float);
-    GET_COLUMN(flags, "FLAGS",    int);
-    GET_COLUMN(Ncode, "NCODE",    short);
-    GET_COLUMN(Nused, "NUSED",    short);
-    GET_COLUMN(M_20,  "MAG_20",   short);
-    GET_COLUMN(M_80,  "MAG_80",   short);
+    GET_COLUMN(M,      "MAG",      float);
+    GET_COLUMN(dM,     "MAG_ERR",  float);
+    GET_COLUMN(Mchisq, "MAG_CHI",  float);
+    GET_COLUMN(flags,  "FLAGS",    int);
+    GET_COLUMN(Ncode,  "NCODE",    short);
+    GET_COLUMN(Nused,  "NUSED",    short);
+    GET_COLUMN(Mmin,   "MAG_MIN",  float);
+    GET_COLUMN(Mmax,   "MAG_MAX",  float);
     gfits_free_header (&theader);
     gfits_free_table  (&ftable);
@@ -270,12 +273,12 @@
     ALLOCATE (secfilt, SecFilt, Nrow);
     for (i = 0; i < Nrow; i++) {
-      secfilt[i].M     = M[i];         
-      secfilt[i].dM    = dM[i];
-      secfilt[i].Xm    = Xm[i];
-      secfilt[i].flags = flags[i];
-      secfilt[i].Ncode = Ncode[i];
-      secfilt[i].Nused = Nused[i];
-      secfilt[i].M_20  = M_20[i];
-      secfilt[i].M_80  = M_80[i];
+      secfilt[i].M      = M[i];         
+      secfilt[i].dM     = dM[i];
+      secfilt[i].Mchisq = Mchisq[i];
+      secfilt[i].flags  = flags[i];
+      secfilt[i].Ncode  = Ncode[i];
+      secfilt[i].Nused  = Nused[i];
+      secfilt[i].Mmin   = Mmin[i];
+      secfilt[i].Mmax   = Mmax[i];
     }
     fprintf (stderr, "loaded data for %lld averages\n", (long long) Nrow);
@@ -283,10 +286,10 @@
     free (M    );
     free (dM   );
-    free (Xm   );
+    free (Mchisq);
     free (flags);
     free (Ncode);
     free (Nused);
-    free (M_20 );
-    free (M_80 );
+    free (Mmin );
+    free (Mmax );
     catalog->secfilt = secfilt;
     // assert Nsecfilt * Naverage = Nrow?
@@ -351,11 +354,11 @@
     gfits_define_bintable_column (&theader, "E", "Y_FIX",    "ccd y fiex coord",       	   "pix",    1.0, 0.0);
     gfits_define_bintable_column (&theader, "E", "EXPTIME",  "-2.5 * log (exposure time)", "sec",    1.0, 0.0);
-    gfits_define_bintable_column (&theader, "J", "TIME",     "time of exp",                "sec",    1.0, 1.0*0x8000);
-    gfits_define_bintable_column (&theader, "J", "AVE_REF",  "pointer to average table",    NULL,    1.0, 1.0*0x8000);
-    gfits_define_bintable_column (&theader, "J", "IMAGE_ID", "image",                       NULL,    1.0, 1.0*0x8000);
-    gfits_define_bintable_column (&theader, "J", "DB_FLAGS", "flags",                       NULL,    1.0, 1.0*0x8000);
-    gfits_define_bintable_column (&theader, "J", "PHOT_FLAGS", "photflags",                 NULL,    1.0, 1.0*0x8000);
-    gfits_define_bintable_column (&theader, "J", "CAT_ID",   "catalog",                     NULL,    1.0, 1.0*0x8000);
-    gfits_define_bintable_column (&theader, "I", "PHOTCODE", "photcode",                    NULL,    1.0, 1.0*0x80);
+    gfits_define_bintable_column (&theader, "J", "TIME",     "time of exp",                "sec",    1.0, 0.0);
+    gfits_define_bintable_column (&theader, "J", "AVE_REF",  "pointer to average table",    NULL,    1.0, 0.0);
+    gfits_define_bintable_column (&theader, "J", "IMAGE_ID", "image",                       NULL,    1.0, 0.0);
+    gfits_define_bintable_column (&theader, "J", "DB_FLAGS", "flags",                       NULL,    1.0, 0.0);
+    gfits_define_bintable_column (&theader, "J", "PHOT_FLAGS", "photflags",                 NULL,    1.0, 0.0);
+    gfits_define_bintable_column (&theader, "J", "CAT_ID",   "catalog",                     NULL,    1.0, 0.0);
+    gfits_define_bintable_column (&theader, "I", "PHOTCODE", "photcode",                    NULL,    1.0, 0.0);
 
     // generate the output array that carries the data
@@ -363,28 +366,28 @@
 
     // create intermediate storage arrays
-    float *dR        ; ALLOCATE (dR       ,  float, catalog->Nmeasure);
-    float *dD        ; ALLOCATE (dD       ,  float, catalog->Nmeasure);
-    float *M         ; ALLOCATE (M        ,  float, catalog->Nmeasure);
-    float *Mcal      ; ALLOCATE (Mcal     ,  float, catalog->Nmeasure);
-    float *dM        ; ALLOCATE (dM       ,  float, catalog->Nmeasure);
-    float *airmass   ; ALLOCATE (airmass  ,  float, catalog->Nmeasure);
-    float *Xccd      ; ALLOCATE (Xccd     ,  float, catalog->Nmeasure);
-    float *Yccd      ; ALLOCATE (Yccd     ,  float, catalog->Nmeasure);
-    float *Xfix      ; ALLOCATE (Xfix     ,  float, catalog->Nmeasure);
-    float *Yfix      ; ALLOCATE (Yfix     ,  float, catalog->Nmeasure);
-    float *dt        ; ALLOCATE (dt       ,  float, catalog->Nmeasure);
-    int   *t         ; ALLOCATE (t        ,  int  , catalog->Nmeasure);
-    int   *averef    ; ALLOCATE (averef   ,  int  , catalog->Nmeasure);
-    int   *imageID   ; ALLOCATE (imageID  ,  int  , catalog->Nmeasure);
-    int   *dbFlags   ; ALLOCATE (dbFlags  ,  int  , catalog->Nmeasure);
-    int   *photFlags ; ALLOCATE (photFlags,  int  , catalog->Nmeasure);
-    int   *catID     ; ALLOCATE (catID    ,  int  , catalog->Nmeasure);
-    short *photcode  ; ALLOCATE (photcode ,  short, catalog->Nmeasure);
+    double *R         ; ALLOCATE (R        ,  double, catalog->Nmeasure);
+    double *D         ; ALLOCATE (D        ,  double, catalog->Nmeasure);
+    float  *M         ; ALLOCATE (M        ,  float,  catalog->Nmeasure);
+    float  *Mcal      ; ALLOCATE (Mcal     ,  float,  catalog->Nmeasure);
+    float  *dM        ; ALLOCATE (dM       ,  float,  catalog->Nmeasure);
+    float  *airmass   ; ALLOCATE (airmass  ,  float,  catalog->Nmeasure);
+    float  *Xccd      ; ALLOCATE (Xccd     ,  float,  catalog->Nmeasure);
+    float  *Yccd      ; ALLOCATE (Yccd     ,  float,  catalog->Nmeasure);
+    float  *Xfix      ; ALLOCATE (Xfix     ,  float,  catalog->Nmeasure);
+    float  *Yfix      ; ALLOCATE (Yfix     ,  float,  catalog->Nmeasure);
+    float  *dt        ; ALLOCATE (dt       ,  float,  catalog->Nmeasure);
+    int    *t         ; ALLOCATE (t        ,  int  ,  catalog->Nmeasure);
+    int    *averef    ; ALLOCATE (averef   ,  int  ,  catalog->Nmeasure);
+    int    *imageID   ; ALLOCATE (imageID  ,  int  ,  catalog->Nmeasure);
+    int    *dbFlags   ; ALLOCATE (dbFlags  ,  int  ,  catalog->Nmeasure);
+    int    *photFlags ; ALLOCATE (photFlags,  int  ,  catalog->Nmeasure);
+    int    *catID     ; ALLOCATE (catID    ,  int  ,  catalog->Nmeasure);
+    short  *photcode  ; ALLOCATE (photcode ,  short,  catalog->Nmeasure);
 
     // assign the storage arrays
     MeasureTiny *measure = catalog->measure;
     for (i = 0; i < catalog->Nmeasure; i++) {
-      dR[i]       = measure[i].dR       ;
-      dD[i]       = measure[i].dD       ;
+      R[i]        = measure[i].R        ;
+      D[i]        = measure[i].D        ;
       M[i]  	  = measure[i].M        ;
       Mcal[i]     = measure[i].Mcal     ;
@@ -406,6 +409,6 @@
 
     // add the columns to the output array
-    gfits_set_bintable_column (&theader, &ftable, "RA_OFF",   	dR,        catalog->Nmeasure);
-    gfits_set_bintable_column (&theader, &ftable, "DEC_OFF",  	dD,        catalog->Nmeasure);
+    gfits_set_bintable_column (&theader, &ftable, "RA",   	R,         catalog->Nmeasure);
+    gfits_set_bintable_column (&theader, &ftable, "DEC",  	D,         catalog->Nmeasure);
     gfits_set_bintable_column (&theader, &ftable, "MAG_SYS",  	M,         catalog->Nmeasure);
     gfits_set_bintable_column (&theader, &ftable, "MAG_CAL",  	Mcal,      catalog->Nmeasure);
@@ -425,6 +428,6 @@
     gfits_set_bintable_column (&theader, &ftable, "PHOTCODE",   photcode,  catalog->Nmeasure);
 
-    free (dR      );
-    free (dD      );
+    free (R       );
+    free (D       );
     free (M       );
     free (Mcal    );
@@ -454,33 +457,34 @@
     gfits_create_table_header (&theader, "BINTABLE", "AVERAGE");
 
-    gfits_define_bintable_column (&theader, "D", "RA",          "RA", 	         	  	         		  "", 1.0, 0.0);
-    gfits_define_bintable_column (&theader, "D", "DEC",         "DEC", 	         	 	         		  "", 1.0, 0.0);
-    gfits_define_bintable_column (&theader, "E", "RA_ERR",      "RA error", 	         	         		  "", 1.0, 0.0);
-    gfits_define_bintable_column (&theader, "E", "DEC_ERR",     "DEC error", 	         	         		  "", 1.0, 0.0);
-    gfits_define_bintable_column (&theader, "E", "U_RA",        "RA*cos(D) proper-motion", 	         		  "", 1.0, 0.0);
-    gfits_define_bintable_column (&theader, "E", "U_DEC",       "DEC proper-motion", 	         	 		  "", 1.0, 0.0);
-    gfits_define_bintable_column (&theader, "E", "V_RA_ERR",    "RA*cos(D) p-m error", 	         	 		  "", 1.0, 0.0);
-    gfits_define_bintable_column (&theader, "E", "V_DEC_ERR",   "DEC p-m error", 	         	 		  "", 1.0, 0.0);
-    gfits_define_bintable_column (&theader, "E", "PAR",         "parallax", 	                         		  "", 1.0, 0.0);
-    gfits_define_bintable_column (&theader, "E", "PAR_ERR",     "parallax error", 	                 		  "", 1.0, 0.0);
-    gfits_define_bintable_column (&theader, "E", "CHISQ_POS",   "astrometry analysis chisq", 	         		  "", 1.0, 0.0);
-    gfits_define_bintable_column (&theader, "E", "CHISQ_PM",    "astrometry analysis chisq", 	         		  "", 1.0, 0.0);
-    gfits_define_bintable_column (&theader, "E", "CHISQ_PAP",   "astrometry analysis chisq", 	         		  "", 1.0, 0.0);
-    gfits_define_bintable_column (&theader, "J", "MEAN_EPOCH",  "mean epoch (PM-PAR ref)", 	         		  "", 1.0, 1.0*0x8000);
-    gfits_define_bintable_column (&theader, "J", "TIME_RANGE",  "mean epoch (PM-PAR ref)", 	         		  "", 1.0, 1.0*0x8000);
-    gfits_define_bintable_column (&theader, "E", "STARGAL_SEP", "star/galaxy separator",                		  "", 1.0, 0.0);   
-    gfits_define_bintable_column (&theader, "I", "NUMBER_POS",  "number of detections used for astrometry", 	          "", 1.0, 1.0*0x80);
-    gfits_define_bintable_column (&theader, "I", "NMEASURE",    "number of psf measurements", 	                          "", 1.0, 1.0*0x80);
-    gfits_define_bintable_column (&theader, "I", "NMISSING",    "number of missings", 	          	                  "", 1.0, 1.0*0x80);
-    gfits_define_bintable_column (&theader, "I", "NEXTEND",     "number of extended measurements", 	                  "", 1.0, 1.0*0x80);
-    gfits_define_bintable_column (&theader, "J", "OFF_MEASURE", "offset to first psf measurement", 	 	          "", 1.0, 1.0*0x8000);
-    gfits_define_bintable_column (&theader, "J", "OFF_MISSING", "offset to first missing obs", 	         	          "", 1.0, 1.0*0x8000);
-    gfits_define_bintable_column (&theader, "J", "OFF_EXTEND",  "offset to first extended measurement", 	          "", 1.0, 1.0*0x8000);
-    gfits_define_bintable_column (&theader, "J", "FLAGS",       "average object flags (star; ghost; etc)", 	          "", 1.0, 1.0*0x8000);
-    gfits_define_bintable_column (&theader, "J", "PHOTFLAGS_U", "upper bit of 2 bit summary of per-measure photflags", 	  "", 1.0, 1.0*0x8000);
-    gfits_define_bintable_column (&theader, "J", "PHOTFLAGS_L", "lower bit of 2 bit summary of per-measure photflags", 	  "", 1.0, 1.0*0x8000);
-    gfits_define_bintable_column (&theader, "J", "OBJ_ID",      "unique ID for object in table", 	                  "", 1.0, 1.0*0x8000);
-    gfits_define_bintable_column (&theader, "J", "CAT_ID",      "unique ID for table in which object was first realized", "", 1.0, 1.0*0x8000);
-    gfits_define_bintable_column (&theader, "K", "EXT_ID",      "external ID for object (eg PSPS objID)", 	          "", 1.0, 1.0*0x80000000);
+    gfits_define_bintable_column (&theader, "D", "RA",             "RA", 	         	  	         	  "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "D", "DEC",            "DEC", 	         	 	         	  "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "RA_ERR",         "RA error", 	         	         		  "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "DEC_ERR",        "DEC error", 	         	         	  "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "U_RA",           "RA*cos(D) proper-motion", 	         		  "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "U_DEC",          "DEC proper-motion", 	         	 	  "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "V_RA_ERR",       "RA*cos(D) p-m error", 	         	 	  "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "V_DEC_ERR",      "DEC p-m error", 	         	 		  "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "PAR",            "parallax", 	                         		  "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "PAR_ERR",        "parallax error", 	                 		  "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "CHISQ_POS",      "astrometry analysis chisq", 	         	  "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "CHISQ_PM",       "astrometry analysis chisq", 	         	  "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "CHISQ_PAP",      "astrometry analysis chisq", 	         	  "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "J", "MEAN_EPOCH",     "mean epoch (PM-PAR ref)", 	         		  "", 1.0, 0.00);
+    gfits_define_bintable_column (&theader, "J", "TIME_RANGE",     "mean epoch (PM-PAR ref)", 	         		  "", 1.0, 0.00);
+    gfits_define_bintable_column (&theader, "E", "STARGAL_SEP",    "star/galaxy separator",                		  "", 1.0, 0.0);   
+    gfits_define_bintable_column (&theader, "I", "NUMBER_POS",     "number of detections used for astrometry", 	          "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "I", "NMEASURE",       "number of psf measurements", 	                  "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "I", "NMISSING",       "number of missings", 	          	          "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "I", "NEXTEND",        "number of extended measurements", 	                  "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "J", "OFF_MEASURE",    "offset to first psf measurement", 	 	          "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "J", "OFF_MISSING",    "offset to first missing obs", 	         	  "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "REF_COLOR_BLUE", "reference color", 	                                  "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "REF_COLOR_RED",  "reference color", 	                                  "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "J", "FLAGS",          "average object flags (star; ghost; etc)", 	          "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "J", "PHOTFLAGS_U",    "upper bit of 2 bit summary of per-measure photflags", "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "J", "PHOTFLAGS_L",    "lower bit of 2 bit summary of per-measure photflags", "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "J", "OBJ_ID",         "unique ID for object in table", 	                  "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "J", "CAT_ID",         "unique ID for table in which object was first realized", "", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "K", "EXT_ID",         "external ID for object (eg PSPS objID)", 	          "", 1.0, 0.0);
 
     // generate the output array that carries the data
@@ -510,5 +514,6 @@
     int      *measureOffset ; ALLOCATE (measureOffset , int     , catalog->Naverage);
     int      *missingOffset ; ALLOCATE (missingOffset , int     , catalog->Naverage);
-    int      *extendOffset  ; ALLOCATE (extendOffset  , int     , catalog->Naverage);
+    float    *refColorBlue  ; ALLOCATE (refColorBlue  , float   , catalog->Naverage);
+    float    *refColorRed   ; ALLOCATE (refColorRed   , float   , catalog->Naverage);
     int      *flags         ; ALLOCATE (flags         , int     , catalog->Naverage);
     int      *photFlagsUpper; ALLOCATE (photFlagsUpper, int     , catalog->Naverage);
@@ -543,5 +548,6 @@
       measureOffset[i]   = average[i].measureOffset   ; 
       missingOffset[i]   = average[i].missingOffset   ; 
-      extendOffset[i]    = average[i].extendOffset    ;  
+      refColorBlue[i]    = average[i].refColorBlue    ;  
+      refColorRed[i]     = average[i].refColorRed     ;  
       flags[i]           = average[i].flags           ;
       photFlagsUpper[i]  = average[i].photFlagsUpper  ;
@@ -553,33 +559,34 @@
 
     // add the columns to the output array
-    gfits_set_bintable_column (&theader, &ftable, "RA",          R,               catalog->Naverage);
-    gfits_set_bintable_column (&theader, &ftable, "DEC",         D,               catalog->Naverage);
-    gfits_set_bintable_column (&theader, &ftable, "RA_ERR",      dR,              catalog->Naverage);
-    gfits_set_bintable_column (&theader, &ftable, "DEC_ERR",     dD,              catalog->Naverage);
-    gfits_set_bintable_column (&theader, &ftable, "U_RA",        uR,              catalog->Naverage);
-    gfits_set_bintable_column (&theader, &ftable, "U_DEC",       uD,              catalog->Naverage);
-    gfits_set_bintable_column (&theader, &ftable, "V_RA_ERR",    duR,             catalog->Naverage);
-    gfits_set_bintable_column (&theader, &ftable, "V_DEC_ERR",   duD,             catalog->Naverage);
-    gfits_set_bintable_column (&theader, &ftable, "PAR",         P,               catalog->Naverage);
-    gfits_set_bintable_column (&theader, &ftable, "PAR_ERR",     dP,              catalog->Naverage);
-    gfits_set_bintable_column (&theader, &ftable, "CHISQ_POS",   ChiSqAve,        catalog->Naverage);
-    gfits_set_bintable_column (&theader, &ftable, "CHISQ_PM",    ChiSqPM,         catalog->Naverage);
-    gfits_set_bintable_column (&theader, &ftable, "CHISQ_PAP",   ChiSqPar,        catalog->Naverage);
-    gfits_set_bintable_column (&theader, &ftable, "MEAN_EPOCH",  Tmean,           catalog->Naverage);
-    gfits_set_bintable_column (&theader, &ftable, "TIME_RANGE",  Trange,          catalog->Naverage);
-    gfits_set_bintable_column (&theader, &ftable, "STARGAL_SEP", stargal,         catalog->Naverage);
-    gfits_set_bintable_column (&theader, &ftable, "NUMBER_POS",  Npos,            catalog->Naverage);
-    gfits_set_bintable_column (&theader, &ftable, "NMEASURE",    Nmeasure,        catalog->Naverage);
-    gfits_set_bintable_column (&theader, &ftable, "NMISSING",    Nmissing,        catalog->Naverage);
-    gfits_set_bintable_column (&theader, &ftable, "NEXTEND",     Nextend,         catalog->Naverage);
-    gfits_set_bintable_column (&theader, &ftable, "OFF_MEASURE", measureOffset,   catalog->Naverage);
-    gfits_set_bintable_column (&theader, &ftable, "OFF_MISSING", missingOffset,   catalog->Naverage);
-    gfits_set_bintable_column (&theader, &ftable, "OFF_EXTEND",  extendOffset,    catalog->Naverage);
-    gfits_set_bintable_column (&theader, &ftable, "FLAGS",       flags,           catalog->Naverage);
-    gfits_set_bintable_column (&theader, &ftable, "PHOTFLAGS_U", photFlagsUpper,  catalog->Naverage);
-    gfits_set_bintable_column (&theader, &ftable, "PHOTFLAGS_L", photFlagsLower,  catalog->Naverage);
-    gfits_set_bintable_column (&theader, &ftable, "OBJ_ID",      objID,           catalog->Naverage);
-    gfits_set_bintable_column (&theader, &ftable, "CAT_ID",      catID,           catalog->Naverage);
-    gfits_set_bintable_column (&theader, &ftable, "EXT_ID",      extID,           catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "RA",             R,               catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "DEC",            D,               catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "RA_ERR",         dR,              catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "DEC_ERR",        dD,              catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "U_RA",           uR,              catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "U_DEC",          uD,              catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "V_RA_ERR",       duR,             catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "V_DEC_ERR",      duD,             catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "PAR",            P,               catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "PAR_ERR",        dP,              catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "CHISQ_POS",      ChiSqAve,        catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "CHISQ_PM",       ChiSqPM,         catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "CHISQ_PAP",      ChiSqPar,        catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "MEAN_EPOCH",     Tmean,           catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "TIME_RANGE",     Trange,          catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "STARGAL_SEP",    stargal,         catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "NUMBER_POS",     Npos,            catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "NMEASURE",       Nmeasure,        catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "NMISSING",       Nmissing,        catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "NEXTEND",        Nextend,         catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "OFF_MEASURE",    measureOffset,   catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "OFF_MISSING",    missingOffset,   catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "REF_COLOR_BLUE", refColorBlue,    catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "REF_COLOR_RED",  refColorRed,     catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "FLAGS",          flags,           catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "PHOTFLAGS_U",    photFlagsUpper,  catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "PHOTFLAGS_L",    photFlagsLower,  catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "OBJ_ID",         objID,           catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "CAT_ID",         catID,           catalog->Naverage);
+    gfits_set_bintable_column (&theader, &ftable, "EXT_ID",         extID,           catalog->Naverage);
 
     free (R);
@@ -605,5 +612,6 @@
     free (measureOffset);
     free (missingOffset);
-    free (extendOffset);
+    free (refColorBlue);
+    free (refColorRed);
     free (flags);
     free (photFlagsUpper);
@@ -629,6 +637,6 @@
     gfits_define_bintable_column (&theader, "I", "NCODE",    "magnitude (err)",           NULL,    1.0, 0.0);
     gfits_define_bintable_column (&theader, "I", "NUSED",    "airmass",                   NULL,    1.0, 0.0);
-    gfits_define_bintable_column (&theader, "I", "MAG_20",   "ccd x coord",              "pix",    1.0, 0.0);
-    gfits_define_bintable_column (&theader, "I", "MAG_80",   "ccd y coord",              "pix",    1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "MAG_MIN",   "ccd x coord",              "pix",    1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "MAG_MAX",   "ccd y coord",              "pix",    1.0, 0.0);
 
     // generate the output array that carries the data
@@ -642,42 +650,42 @@
     float *M        ; ALLOCATE (M      ,  float, Nsec);
     float *dM       ; ALLOCATE (dM     ,  float, Nsec);
-    float *Xm       ; ALLOCATE (Xm     ,  float, Nsec);
+    float *Mchisq   ; ALLOCATE (Mchisq ,  float, Nsec);
     int   *flags    ; ALLOCATE (flags  ,  int,   Nsec);
     short *Ncode    ; ALLOCATE (Ncode  ,  short, Nsec);
     short *Nused    ; ALLOCATE (Nused  ,  short, Nsec);
-    short *M_20     ; ALLOCATE (M_20   ,  short, Nsec);
-    short *M_80     ; ALLOCATE (M_80   ,  short, Nsec);
+    float *Mmin     ; ALLOCATE (Mmin   ,  float, Nsec);
+    float *Mmax     ; ALLOCATE (Mmax   ,  float, Nsec);
 
     // assign the storage arrays
     SecFilt *secfilt = catalog->secfilt;
     for (i = 0; i < Nsec; i++) {
-      M     [i]       = secfilt[i]. M      ;
-      dM    [i]       = secfilt[i]. dM     ;
-      Xm    [i]       = secfilt[i]. Xm     ;
-      flags [i]       = secfilt[i]. flags  ;
-      Ncode [i]       = secfilt[i]. Ncode  ;
-      Nused [i]       = secfilt[i]. Nused  ;
-      M_20  [i]       = secfilt[i]. M_20   ;
-      M_80  [i]       = secfilt[i]. M_80   ;
+      M     [i]       = secfilt[i].M      ;
+      dM    [i]       = secfilt[i].dM     ;
+      Mchisq[i]       = secfilt[i].Mchisq ;
+      flags [i]       = secfilt[i].flags  ;
+      Ncode [i]       = secfilt[i].Ncode  ;
+      Nused [i]       = secfilt[i].Nused  ;
+      Mmin  [i]       = secfilt[i].Mmin   ;
+      Mmax  [i]       = secfilt[i].Mmax   ;
     }
 
     // add the columns to the output array
-    gfits_set_bintable_column (&theader, &ftable, "MAG",      M    , Nsec);
-    gfits_set_bintable_column (&theader, &ftable, "MAG_ERR",  dM   , Nsec);
-    gfits_set_bintable_column (&theader, &ftable, "MAG_CHI",  Xm   , Nsec);
-    gfits_set_bintable_column (&theader, &ftable, "FLAGS",    flags, Nsec);
-    gfits_set_bintable_column (&theader, &ftable, "NCODE",    Ncode, Nsec);
-    gfits_set_bintable_column (&theader, &ftable, "NUSED",    Nused, Nsec);
-    gfits_set_bintable_column (&theader, &ftable, "MAG_20",   M_20 , Nsec);
-    gfits_set_bintable_column (&theader, &ftable, "MAG_80",   M_80 , Nsec);
+    gfits_set_bintable_column (&theader, &ftable, "MAG",      M     , Nsec);
+    gfits_set_bintable_column (&theader, &ftable, "MAG_ERR",  dM    , Nsec);
+    gfits_set_bintable_column (&theader, &ftable, "MAG_CHI",  Mchisq, Nsec);
+    gfits_set_bintable_column (&theader, &ftable, "FLAGS",    flags , Nsec);
+    gfits_set_bintable_column (&theader, &ftable, "NCODE",    Ncode , Nsec);
+    gfits_set_bintable_column (&theader, &ftable, "NUSED",    Nused , Nsec);
+    gfits_set_bintable_column (&theader, &ftable, "MAG_MIN",  Mmin  , Nsec);
+    gfits_set_bintable_column (&theader, &ftable, "MAG_MAX",  Mmax  , Nsec);
 
     free (M      );
     free (dM     );
-    free (Xm     );
+    free (Mchisq );
     free (flags  );
     free (Ncode  );
     free (Nused  );
-    free (M_20   );
-    free (M_80   );
+    free (Mmin   );
+    free (Mmax   );
 
     gfits_fwrite_Theader (f, &theader);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/FitChip.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/FitChip.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/FitChip.c	(revision 37403)
@@ -4,5 +4,5 @@
 int FitChip (StarData *raw, StarData *ref, int Nmatch, Image *image) {
 
-  int i, NstatFull, Nstat, Niter;
+  int i, NstatFull, Nstat, Niter, Nkeep;
   float dLsig, dMsig, dRsig;
   float dLsigFull, dMsigFull, dRsigFull;
@@ -24,4 +24,5 @@
 
     // measure the scatter distribution (use only the bright end detections)
+    Nkeep = 0;
     for (i = 0; i < Nmatch; i++) {
       if (raw[i].mask) continue;
@@ -42,5 +43,9 @@
 	continue;
       }
-    }
+      Nkeep ++;
+    }
+
+    // I'm rejecting some points from the fit above; I count the remainders and actually
+    // use that count to set order_use below
 
     // figures to assess the fitting process:
@@ -50,16 +55,15 @@
     relastroVisualPlotChipFit(raw, ref, dRmax, Nmatch);
 
-    // fit the requested order polynomial
-    if (CHIPORDER > 0) {
-      int Ndof_min = 3;
-      int order_max = 0.5*(sqrt(4*Nmatch - 4*Ndof_min + 1) - 3);
-      int order_use = MIN (CHIPORDER, order_max);
-      if (order_use < 1) {
-	if (VERBOSE2) fprintf (stderr, "insufficient measurements (%d) for linear fit\n", Nmatch);
-	image[0].flags |= ID_IMAGE_ASTROM_FEW;
-	return FALSE;
-      }
-      image[0].coords.Npolyterms = order_use;
-    }
+    // set the maximum order for the polynomial (based on number of stars kept above)
+    int order_use = 0;
+    if (Nkeep >  5) order_use = 1; // 4 stars per polynomial term (per dimension)
+    if (Nkeep > 30) order_use = 2; // 5 stars per polynomial term (per dimension)
+    if (Nkeep > 60) order_use = 3; // 6 stars per polynomial term (per dimension)
+    if (order_use < 1) {
+      if (VERBOSE2) fprintf (stderr, "insufficient measurements (%d) for linear fit\n", Nkeep);
+      image[0].flags |= ID_IMAGE_ASTROM_FEW;
+      return FALSE;
+    }
+    image[0].coords.Npolyterms = order_use;
 
     if (fit) fit_free (fit);
@@ -71,30 +75,4 @@
       fit_add (fit, raw[i].X, raw[i].Y, ref[i].L, ref[i].M, raw[i].dPos);
     }
-
-# if (0)
-    // check if the fit has enough data points for the polynomial order
-    skip = FALSE;
-    switch (image[0].coords.Npolyterms) {
-      case 0:
-      case 1:
-        skip = (fit[0].Npts < 8);
-        break;
-      case 2:
-        skip = (fit[0].Npts < 11);
-        break;
-      case 3:
-        skip = (fit[0].Npts < 15);
-        break;
-      default:
-        fprintf (stderr, "invalid chip order %d\n", image[0].coords.Npolyterms);
-	skip = TRUE;
-    }
-    if (skip) {
-      if (VERBOSE2) fprintf (stderr, "insufficient measurements (%d) for requested order (%d)\n", fit[0].Npts, image[0].coords.Npolyterms);
-      fit_free (fit);
-      image[0].flags |= ID_IMAGE_ASTROM_FEW;
-      return FALSE;
-    }
-# endif
 
     // measure the fit, update the coords & object coordinates
@@ -134,4 +112,35 @@
   }
 
+  int Ncolor;
+  float colorMedian;
+  float *colorList = NULL;
+  ALLOCATE (colorList, float, Nmatch);
+
+  // calculate the median blue color
+  Ncolor = 0;
+  for (i = 0; i < Nmatch; i++) {
+    if (!raw[i].mask) continue;
+    if (isnan(ref[i].ColorBlue)) continue;
+    colorList[Ncolor] = ref[i].ColorBlue;
+    Ncolor ++;
+  }
+  fsort (colorList, Ncolor);
+  colorMedian = (Ncolor > 0) ? colorList[(int)(0.5*Ncolor)] : NAN;
+  image[0].refColorBlue = colorMedian;
+
+  // calculate the median red color
+  Ncolor = 0;
+  for (i = 0; i < Nmatch; i++) {
+    if (!raw[i].mask) continue;
+    if (isnan(ref[i].ColorRed)) continue;
+    colorList[Ncolor] = ref[i].ColorRed;
+    Ncolor ++;
+  }
+  fsort (colorList, Ncolor);
+  colorMedian = (Ncolor > 0) ? colorList[(int)(0.5*Ncolor)] : NAN;
+  image[0].refColorRed = colorMedian;
+
+  free (colorList);
+
   GetScatterRawRef(&dLsigFull, &dMsigFull, &dRsigFull, &NstatFull, raw, ref, Nmatch, SIGMA_LIM);
   GetScatterRawRef(&dLsig,     &dMsig,     &dRsig,     &Nstat,     raw, ref, Nmatch, IMFIT_SYS_SIGMA_LIM);
@@ -151,4 +160,6 @@
   image[0].dYpixSys = dMsig;
   image[0].nFitAstrom = fit[0].Npts;
+
+  // fprintf (stderr, "%s %6.3f %4d %4d\n", image[0].name, image[0].refColor, Ncolor, image[0].nFitAstrom);
 
   if (fit) fit_free (fit);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/GetAstromError.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/GetAstromError.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/GetAstromError.c	(revision 37403)
@@ -30,4 +30,5 @@
 
   code 	= GetPhotcodebyCode (measure[0].photcode);
+  if (!code) return NAN;
 
   // do not raise an exception, just send back the result
@@ -72,4 +73,5 @@
 
   code 	= GetPhotcodebyCode (measure[0].photcode);
+  if (!code) return NAN;
 
   // do not raise an exception, just send back the result
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/ImageOps.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/ImageOps.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/ImageOps.c	(revision 37403)
@@ -39,4 +39,16 @@
 // N_onImage was 'Nlist'
 // N_ONIMAGE was 'NLIST'
+
+int areImagesLoaded () {
+
+  if (image) return TRUE;
+  return FALSE;
+}
+
+int areImagesMatched () {
+
+  if (MeasureToImage) return TRUE;
+  return FALSE;
+}
 
 Image *getimages (off_t *N, off_t **line_number) {
@@ -333,4 +345,22 @@
 */
 
+float getColorBlue (off_t meas, int cat) {
+
+  off_t i;
+
+  i = MeasureToImage[cat][meas];
+  if (i == -1) return (NAN);
+  return (image[i].refColorBlue);
+}
+
+float getColorRed (off_t meas, int cat) {
+
+  off_t i;
+
+  i = MeasureToImage[cat][meas];
+  if (i == -1) return (NAN);
+  return (image[i].refColorRed);
+}
+
 void plot_images () {
 
@@ -385,5 +415,5 @@
   for (j = 0; j < average[0].Nmeasure; j++) {
     off = average[0].measureOffset + j;
-    fprintf (stderr, "dR, dD, mag, dMag: %f, %f, %f, %f\n", measure[off].dR, measure[off].dD, measure[off].M, measure[off].dM);
+    fprintf (stderr, "R, D, mag, dMag: %lf, %lf, %f, %f\n", measure[off].R, measure[off].D, measure[off].M, measure[off].dM);
   }
   return;
@@ -468,10 +498,15 @@
     }
 
+    X = measure[0].Xccd;
+    Y = measure[0].Yccd;
     if (USE_FIXED_PIXCOORDS) {
-      X = isfinite(measure[0].Xfix) ? measure[0].Xfix : measure[0].Xccd;
-      Y = isfinite(measure[0].Yfix) ? measure[0].Yfix : measure[0].Yccd;
-    } else {
-      X = measure[0].Xccd;
-      Y = measure[0].Yccd;
+      if (isfinite(measure[0].Xfix) && isfinite(measure[0].Yfix)) {
+	float dX = measure[0].Xfix - measure[0].Xccd;
+	float dY = measure[0].Yfix - measure[0].Yccd;
+	if (hypot(dX,dY) < 2.0) {
+	  X = measure[0].Xfix;
+	  Y = measure[0].Yfix;
+	} 
+      }
     }
     n = measure[0].averef;
@@ -528,27 +563,28 @@
 
     // complain if the new location is far from the old location
-    if (fabs(csdec*(measure[0].dR - dR)) > DPOS_MAX_ASEC) {
+    if (fabs(csdec*(measure[0].R - R)) > DPOS_MAX_ASEC) {
       NoffRAori ++;
       if (VERBOSE2) {
-	fprintf (stderr, "measurement moves far from original location (R): %f %f (%f %f %f %f)\n", average[0].R, average[0].D, measure[0].dR, dR, csdec*(measure[0].dR - dR), dD);
+	fprintf (stderr, "measurement moves far from original location (R): %f %f (%f %f %f %f)\n", average[0].R, average[0].D, measure[0].R, dR, csdec*(measure[0].R - R), dD);
 	dump_measures (&average[0], catalog[c].measure);
       }
       // abort();
     }
-    if (fabs(measure[0].dD - dD) > DPOS_MAX_ASEC) {
+    if (fabs(measure[0].D - D) > DPOS_MAX_ASEC) {
       NoffDECori ++;
       if (VERBOSE2) {
-	fprintf (stderr, "measurement moves far from original location (D): %f %f (%f %f %f)\n", average[0].R, average[0].D, dR, measure[0].dD, dD);
+	fprintf (stderr, "measurement moves far from original location (D): %f %f (%f %f %f)\n", average[0].R, average[0].D, dR, measure[0].D, dD);
 	dump_measures (&average[0], catalog[c].measure);
       }      // abort();
     }
 
-    dPos += SQ(measure[0].dR - dR) + SQ(measure[0].dD - dD);
+    // XXX NOTE : apply csdec:
+    dPos += SQ(measure[0].R - R) + SQ(measure[0].D - D);
     nPos ++;
 
-    measure[0].dR = dR;
-    measure[0].dD = dD;
-    measureT[0].dR = dR;
-    measureT[0].dD = dD;
+    measure[0].R = R;
+    measure[0].D = D;
+    measureT[0].R = R;
+    measureT[0].D = D;
     
     // set the systematic error for this image:
@@ -560,5 +596,5 @@
 
   int Noff = NoffRAave + NoffDECave + NoffRAori + NoffDECori;
-  if (VERBOSE && (Noff > 0)) fprintf (stderr, "Noff ave RA %d, Noff ave DEC %d, Noff ori RA %d, Noff ori DEC %d\n", NoffRAave, NoffDECave, NoffRAori, NoffDECori);
+  if (VERBOSE2 && (Noff > 0)) fprintf (stderr, "Noff ave RA %d, Noff ave DEC %d, Noff ori RA %d, Noff ori DEC %d\n", NoffRAave, NoffDECave, NoffRAori, NoffDECori);
   saveOffsets (dPos, nPos, im);
 
@@ -575,5 +611,5 @@
 
   off_t i, m, c, n;
-  double X, Y, L, M, P, Q, R, D, dR, dD;
+  double X, Y, L, M, P, Q, R, D;
 
   Mosaic *mosaic;
@@ -609,14 +645,18 @@
     Measure *measure = &catalog[c].measure[m];
 
+    X = measure[0].Xccd;
+    Y = measure[0].Yccd;
     if (USE_FIXED_PIXCOORDS) {
-      X = isfinite(measure[0].Xfix) ? measure[0].Xfix : measure[0].Xccd;
-      Y = isfinite(measure[0].Yfix) ? measure[0].Yfix : measure[0].Yccd;
-    } else {
-      X = measure[0].Xccd;
-      Y = measure[0].Yccd;
+      if (isfinite(measure[0].Xfix) && isfinite(measure[0].Yfix)) {
+	float dX = measure[0].Xfix - measure[0].Xccd;
+	float dY = measure[0].Yfix - measure[0].Yccd;
+	if (hypot(dX,dY) < 2.0) {
+	  X = measure[0].Xfix;
+	  Y = measure[0].Yfix;
+	} 
+      }
     }
     n = measure[0].averef;
 
-    dR = dD = 0.0;
     if (moscoords == NULL) {
       // this is a Simple image (not a mosaic)
@@ -629,17 +669,17 @@
       LM_to_RD (&R, &D, P, Q, moscoords);
     }
-
-    measure[0].dR = dR;
-    measure[0].dD = dD;
-
-    if (measure[0].dR > +180.0*3600.0) {
+    measure[0].R = R;
+    measure[0].D = D;
+
+    float dRoff = dvoOffsetR(measure, &catalog[c].average[n]);
+
+    if (dRoff > +180.0*3600.0) {
       // average on high end of boundary, move star up
-      R += 360.0;
-      measure[0].dR = 3600.0*(catalog[c].average[n].R - R);
-    }
-    if (measure[0].dR < -180.0*3600.0) {
-      // average on low end of boundary, move star down
-      R -= 360.0;
-      measure[0].dR = 3600.0*(catalog[c].average[n].R - R);
+      measure[0].R += 360.0;
+      dRoff -= 360.0*3600.0;
+    }
+    if (dRoff < -180.0*3600.0) {
+      measure[0].R -= 360.0;
+      dRoff += 360.0*3600.0;
     }
   }
@@ -679,12 +719,16 @@
 
     /* apply the current image transformation or use the current value of R+dR, D+dD? */
+    raw[i].X = measure[0].Xccd;
+    raw[i].Y = measure[0].Yccd;
     if (USE_FIXED_PIXCOORDS) {
-      raw[i].X = isfinite(measure[0].Xfix) ? measure[0].Xfix : measure[0].Xccd;
-      raw[i].Y = isfinite(measure[0].Yfix) ? measure[0].Yfix : measure[0].Yccd;
-    } else {
-      raw[i].X = measure[0].Xccd;
-      raw[i].Y = measure[0].Yccd;
-    }
-
+      if (isfinite(measure[0].Xfix) && isfinite(measure[0].Yfix)) {
+	float dX = measure[0].Xfix - measure[0].Xccd;
+	float dY = measure[0].Yfix - measure[0].Yccd;
+	if (hypot(dX,dY) < 2.0) {
+	  raw[i].X = measure[0].Xfix;
+	  raw[i].Y = measure[0].Yfix;
+	} 
+      }
+    }
     raw[i].Mag  = measure[0].M;
     raw[i].dMag = measure[0].dM;
@@ -699,5 +743,5 @@
       raw[i].mask |= MARK_TOO_FEW_MEAS;
     }
-    if (!finite(measure[0].dR) || !finite(measure[0].dD)) {
+    if (!finite(measure[0].R) || !finite(measure[0].D)) {
       raw[i].mask |= MARK_NAN_POS_ERROR;
     }
@@ -738,4 +782,6 @@
   StarData *ref;
 
+  int Nsecfilt = GetPhotcodeNsecfilt();
+
   mosaic = NULL;
   moscoords = NULL;
@@ -765,4 +811,11 @@
     ref[i].dMag = measure[0].dM;
     ref[i].dPos = GetAstromErrorTiny (&measure[0], ERROR_MODE_POS);
+
+    if ((DCR_BLUE_NSEC_POS >= 0) && (DCR_BLUE_NSEC_NEG >= -1)) {
+      ref[i].ColorBlue = catalog[c].secfilt[n*Nsecfilt + DCR_BLUE_NSEC_POS].M - catalog[c].secfilt[n*Nsecfilt + DCR_BLUE_NSEC_NEG].M;
+    }
+    if ((DCR_RED_NSEC_POS >= 0) && (DCR_RED_NSEC_NEG >= -1)) {
+      ref[i].ColorRed = catalog[c].secfilt[n*Nsecfilt + DCR_RED_NSEC_POS].M - catalog[c].secfilt[n*Nsecfilt + DCR_RED_NSEC_NEG].M;
+    }
 
     ref[i].mask = FALSE;
@@ -839,6 +892,6 @@
       // skip measurements based on user selected criteria
       if (!MeasFilterTest(&measure[k], FALSE)) continue;
-      R[N] = measure[k].dR;
-      D[N] = measure[k].dD;
+      R[N] = measure[k].R;
+      D[N] = measure[k].D;
       dR[N] = GetAstromError (&measure[k], ERROR_MODE_RA);
       dD[N] = GetAstromError (&measure[k], ERROR_MODE_DEC);
@@ -859,5 +912,5 @@
     N = 0;
     for (k = 0; k < catalog[0].average[j].Nmeasure; k++) {
-      //reset flag on each invocation
+      // reset flag on each invocation
       measure[k].dbFlags &= ~ID_MEAS_POOR_ASTROM;
 
@@ -865,6 +918,6 @@
       if (!MeasFilterTest(&measure[k], FALSE)) continue;
       
-      x = measure[k].dR - statsR.median;
-      y = measure[k].dD - statsD.median;
+      x = measure[k].R - statsR.median;
+      y = measure[k].D - statsD.median;
       theta = atan2(y,x);
       if ((x*x + y*y) > (SQR(statsR.sigma * Ns * cos(theta)) + 
@@ -898,4 +951,7 @@
   double *R, *D, *dR, *dD, *d2;
   StatType statsR, statsD;
+
+  // XXX we are not going to use this for now
+  return;
 
   Nsecfilt = GetPhotcodeNsecfilt();
@@ -937,6 +993,6 @@
       // skip measurements based on user selected criteria
       if (!MeasFilterTest(&measure[k], FALSE)) continue;
-      R[N] = measure[k].dR;
-      D[N] = measure[k].dD;
+      R[N] = measure[k].R;
+      D[N] = measure[k].D;
       dR[N] = GetAstromError(&measure[k], ERROR_MODE_RA);
       dD[N] = GetAstromError(&measure[k], ERROR_MODE_DEC);
@@ -958,6 +1014,6 @@
       // skip bad measurements
       if (!MeasFilterTest(&measure[k], FALSE)) continue;  
-      x = measure[k].dR - statsR.median;
-      y = measure[k].dD - statsD.median;
+      x = measure[k].R - statsR.median;
+      y = measure[k].D - statsD.median;
       theta = atan2(y,x);
       d2[N] = (x*x + y*y) / (SQR(statsR.sigma * Ns * cos(theta)) + 
@@ -974,6 +1030,6 @@
     for (k = 0;  k < N; k++) {
       off_t ind = (off_t) index[k];
-      R[k] = measure[ind].dR;
-      D[k] = measure[ind].dD;
+      R[k] = measure[ind].R;
+      D[k] = measure[ind].D;
       dR[k] = GetAstromError(&measure[ind], ERROR_MODE_RA);
       dD[k] = GetAstromError(&measure[ind], ERROR_MODE_DEC);
@@ -989,6 +1045,6 @@
       //skip bad measurements
       if (!MeasFilterTest(&measure[k], FALSE)) continue;  
-      x = measure[k].dR - statsR.median;
-      y = measure[k].dD - statsD.median;
+      x = measure[k].R - statsR.median;
+      y = measure[k].D - statsD.median;
       theta = atan2(y,x);
       d2[N] = (x*x + y*y) / (SQR(statsR.sigma * Ns * cos(theta)) + 
@@ -1024,5 +1080,5 @@
   float mag;
 
-  if (!finite(measure[0].dR) || !finite(measure[0].dD)) return FALSE;
+  if (!finite(measure[0].R) || !finite(measure[0].D)) return FALSE;
   if (!finite(measure[0].M)) return FALSE; //XXX is this necessary for all relastro tasks?
   if (!finite(measure[0].dM)) return FALSE; //XXX is this necessary for all relastro tasks?
@@ -1063,4 +1119,5 @@
     } else {
       code = GetPhotcodebyCode (measure[0].photcode);
+      if (!code) return FALSE;
       mask = code[0].astromBadMask;
     }
@@ -1075,5 +1132,5 @@
   /* select measurements by mag limit */
   if (ImagSelect) {
-    mag = PhotInstTiny (measure);
+    mag = PhotInstTiny (measure, MAG_CLASS_PSF);
     if (mag < ImagMin || mag > ImagMax) return FALSE;
   }
@@ -1090,5 +1147,5 @@
   float mag;
 
-  if (!finite(measure[0].dR) || !finite(measure[0].dD)) return FALSE;
+  if (!finite(measure[0].R) || !finite(measure[0].D)) return FALSE;
   if (!finite(measure[0].M)) return FALSE; //XXX is this necessary for all relastro tasks?
   if (!finite(measure[0].dM)) return FALSE; //XXX is this necessary for all relastro tasks?
@@ -1129,4 +1186,5 @@
     } else {
       code = GetPhotcodebyCode (measure[0].photcode);
+      if (!code) return FALSE;
       mask = code[0].astromBadMask;
     }
@@ -1141,5 +1199,5 @@
   /* select measurements by mag limit */
   if (ImagSelect) {
-    mag = PhotInst (measure);
+    mag = PhotInst (measure, MAG_CLASS_PSF);
     if (mag < ImagMin || mag > ImagMax) return FALSE;
   }
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/MeanPosIO.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/MeanPosIO.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/MeanPosIO.c	(revision 37403)
@@ -111,6 +111,6 @@
   gfits_define_bintable_column (&theader, "D", "RA",        "mean position, ra",  "degrees", 1.0, 0.0);
   gfits_define_bintable_column (&theader, "D", "DEC",       "mean position, dec", "degrees", 1.0, 0.0);
-  gfits_define_bintable_column (&theader, "J", "OBJ_ID",    "object ID",          NULL,      1.0, 1.0*0x8000);
-  gfits_define_bintable_column (&theader, "J", "CAT_ID",    "catalog ID",         NULL,      1.0, 1.0*0x8000);
+  gfits_define_bintable_column (&theader, "J", "OBJ_ID",    "object ID",          NULL,      1.0, FT_BZERO_INT32);
+  gfits_define_bintable_column (&theader, "J", "CAT_ID",    "catalog ID",         NULL,      1.0, FT_BZERO_INT32);
 
   // generate the output array that carries the data
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/MosaicOps.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/MosaicOps.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/MosaicOps.c	(revision 37403)
@@ -97,12 +97,12 @@
 
     /* a new mosaic, define ranges */
-    mosaic[Nmosaic].start = start;
-    mosaic[Nmosaic].stop  = stop;
-    mosaic[Nmosaic].Mcal  = 0.0;
-    mosaic[Nmosaic].dMcal = 0.0;
-    mosaic[Nmosaic].Xm    = 0.0;
-    mosaic[Nmosaic].flags  = image[i].flags;
-    mosaic[Nmosaic].secz  = image[i].secz;
-    mosaic[Nmosaic].coords = image[i].coords;
+    mosaic[Nmosaic].start   = start;
+    mosaic[Nmosaic].stop    = stop;
+    mosaic[Nmosaic].Mcal    = 0.0;
+    mosaic[Nmosaic].dMcal   = 0.0;
+    mosaic[Nmosaic].Xm      = 0.0;
+    mosaic[Nmosaic].flags   = image[i].flags;
+    mosaic[Nmosaic].secz    = image[i].secz;
+    mosaic[Nmosaic].coords  = image[i].coords;
     mosaic[Nmosaic].myImage = i;
 
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/ParFactor.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/ParFactor.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/ParFactor.c	(revision 37403)
@@ -63,5 +63,6 @@
   double jd, lambda, beta, epsilon, Radius;
 
-  /* given a time T in UNIX seconds, determine the solar longitude S */
+  /* given a Time relative to Tmean, Tmean in years since J2000, determine the solar
+    longitude S */
 
   // jd = ohana_sec_to_jd (365.25*86400.0*(Time + Tmean));
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/Shutdown.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/Shutdown.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/Shutdown.c	(revision 37403)
@@ -23,5 +23,5 @@
   SetProtect (TRUE);
   gfits_db_close (db);
-  fprintf (stderr, "ERROR: addstar halted\n");
+  fprintf (stderr, "ERROR: relastro halted\n");
   exit (1);
 }
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/UpdateObjectOffsets.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/UpdateObjectOffsets.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/UpdateObjectOffsets.c	(revision 37403)
@@ -126,41 +126,47 @@
 	      table->hosts[i].hostID, CATDIR, table->hosts[i].pathname, UserPatch.Rmin, UserPatch.Rmax, UserPatch.Dmin, UserPatch.Dmax, STATMODE, MIN_ERROR);
 
-    char tmpline[1024];
-    if (FIT_MODE == FIT_PM_ONLY)  	 { snprintf (tmpline, 1024, "%s -pm",    command);           strcpy (command, tmpline); }
-    if (FIT_MODE == FIT_PAR_ONLY) 	 { snprintf (tmpline, 1024, "%s -par",   command);           strcpy (command, tmpline); }
-    if (FIT_MODE == FIT_PM_AND_PAR)      { snprintf (tmpline, 1024, "%s -pmpar", command);           strcpy (command, tmpline); }
-
-    if (VERBOSE)       { snprintf (tmpline, 1024, "%s -v",              command);                    strcpy (command, tmpline); }
-    if (VERBOSE2)      { snprintf (tmpline, 1024, "%s -vv",             command); 		     strcpy (command, tmpline); }
-    if (RESET)         { snprintf (tmpline, 1024, "%s -reset",          command); 		     strcpy (command, tmpline); }
-    if (UPDATE)        { snprintf (tmpline, 1024, "%s -update",         command); 		     strcpy (command, tmpline); }
-
-    if (RESET_BAD_IMAGES) { snprintf (tmpline, 1024, "%s -reset-bad-images", command); 		     strcpy (command, tmpline); }
-
-    if (ImagSelect)    { snprintf (tmpline, 1024, "%s -instmag %f %f",  command, ImagMin, ImagMax);  strcpy (command, tmpline); }
-    if (MaxDensityUse) { snprintf (tmpline, 1024, "%s -max-density %f", command, MaxDensityValue);   strcpy (command, tmpline); }
+    if (FIT_MODE == FIT_PM_ONLY)  	 strextend (command, "-pm");
+    if (FIT_MODE == FIT_PAR_ONLY) 	 strextend (command, "-par");
+    if (FIT_MODE == FIT_PM_AND_PAR)      strextend (command, "-pmpar");
+
+    if (VERBOSE)       strextend (command, "-v");
+    if (VERBOSE2)      strextend (command, "-vv");
+    if (RESET)         strextend (command, "-reset");
+    if (UPDATE)        strextend (command, "-update");
+
+    if (RESET_BAD_IMAGES) strextend (command, "-reset-bad-images");
+
+    if (ImagSelect)    strextend (command, "-instmag %f %f", ImagMin, ImagMax);
+    if (MaxDensityUse) strextend (command, "-max-density %f", MaxDensityValue);
     
-    if (USE_BASIC_CHECK) { snprintf (tmpline, 1024, "%s -basic-image-search", command);              strcpy (command, tmpline); }
-    if (FlagOutlier)   { snprintf (tmpline, 1024, "%s -clip %d",        command, CLIP_THRESH);       strcpy (command, tmpline); }
+    if (USE_BASIC_CHECK) strextend (command, "-basic-image-search");
+    if (FlagOutlier)     strextend (command, "-clip %d", CLIP_THRESH);
+    if (ExcludeBogus)    strextend (command, "-exclude-bogus %f", ExcludeBogusRadius);
     
-    if (USE_FIXED_PIXCOORDS) { snprintf (tmpline, 1024, "%s -D USE_FIXED_PIXCOORDS 1", command);     strcpy (command, tmpline); }
-
-    if (PHOTCODE_KEEP_LIST) { snprintf (tmpline, 1024, "%s +photcode %s", command, PHOTCODE_KEEP_LIST); strcpy (command, tmpline); }
-    if (PHOTCODE_SKIP_LIST) { snprintf (tmpline, 1024, "%s -photcode %s", command, PHOTCODE_SKIP_LIST); strcpy (command, tmpline); }
-    if (PhotFlagSelect)    { snprintf (tmpline, 1024, "%s +photflags",   command);                     strcpy (command, tmpline); }
-    if (PhotFlagBad)       { snprintf (tmpline, 1024, "%s +photflagbad %d", command, PhotFlagBad);     strcpy (command, tmpline); }
-    if (PhotFlagPoor)      { snprintf (tmpline, 1024, "%s +photflagpoor %d", command, PhotFlagPoor);   strcpy (command, tmpline); }
+    if (USE_FIXED_PIXCOORDS) strextend (command, "-D USE_FIXED_PIXCOORDS 1"); 
+
+    if (PHOTCODE_KEEP_LIST) strextend (command, "+photcode %s", PHOTCODE_KEEP_LIST);
+    if (PHOTCODE_SKIP_LIST) strextend (command, "-photcode %s", PHOTCODE_SKIP_LIST);
+    if (PhotFlagSelect)     strextend (command, "+photflags"); 
+    if (PhotFlagBad)        strextend (command, "+photflagbad %d", PhotFlagBad);
+    if (PhotFlagPoor)       strextend (command, "+photflagpoor %d", PhotFlagPoor);
     // XXX note that the above pass in the flag as decimal -- also note that args.c cannot handle 0xHEX values
 
-    if (MinBadQF > 0.0)    { snprintf (tmpline, 1024, "%s -min-bad-psfqf %f",        command, MinBadQF);      strcpy (command, tmpline); }
-    if (MaxMeanOffset != 10.0) { snprintf (tmpline, 1024, "%s -max-mean-offset  %f", command, MaxMeanOffset); strcpy (command, tmpline); }
+    if (DCR_BLUE_COLOR_POS && DCR_BLUE_COLOR_NEG) {
+      strextend (command, "-dcr-blue-color %s %s", DCR_BLUE_COLOR_POS, DCR_BLUE_COLOR_NEG); 
+    }
+    if (DCR_RED_COLOR_POS && DCR_RED_COLOR_NEG) {
+      strextend (command, "-dcr-red-color %s %s", DCR_RED_COLOR_POS, DCR_RED_COLOR_NEG); 
+    }
+
+    if (MinBadQF > 0.0)        strextend (command, "-min-bad-psfqf %f", MinBadQF); 
+    if (MaxMeanOffset != 10.0) strextend (command, "-max-mean-offset  %f", MaxMeanOffset);
 
     if (TimeSelect) { 
       char *tstart = ohana_sec_to_date (TSTART);
       char *tstop  = ohana_sec_to_date (TSTOP);
-      snprintf (tmpline, 1024, "%s -time %s %s", command, tstart, tstop); 
+      strextend (command, "-time %s %s", tstart, tstop); 
       free (tstart);
       free (tstop);
-      strcpy (command, tmpline); 
     }
     fprintf (stderr, "command: %s\n", command);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/UpdateObjects.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/UpdateObjects.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/UpdateObjects.c	(revision 37403)
@@ -1,3 +1,7 @@
 # include "relastro.h"
+# define PAR_TOOFEW 5
+
+int UpdateObjects_Chips (Average *average, SecFilt *secfilt, MeasureTiny *measure, Measure *measureBig, int Nsecfilt, FitStats *fitStats, int i, off_t m);
+int UpdateObjects_Stack (Average *average, SecFilt *secfilt, MeasureTiny *measure, Measure *measureBig, int Nsecfilt, FitStats *fitStats);
 
 static off_t Nmax;
@@ -10,4 +14,28 @@
 static double *T;
 static double *dT;
+static double *C_blue;
+static double *C_red;
+
+static Coords coords;
+
+static time_t T2000;
+
+void initFitStats (FitStats *fitStats) {
+  fitStats->Nave = 0;  
+  fitStats->Npm = 0;   
+  fitStats->Npar = 0;  
+  fitStats->Nskip = 0; 
+  fitStats->Noffset = 0;
+  return;
+}
+
+void sumFitStats (FitStats *srcFitStats, FitStats *tgtFitStats) {
+  tgtFitStats->Nave    += srcFitStats->Nave    ;  
+  tgtFitStats->Npm     += srcFitStats->Npm     ;   
+  tgtFitStats->Npar    += srcFitStats->Npar    ;  
+  tgtFitStats->Nskip   += srcFitStats->Nskip   ; 
+  tgtFitStats->Noffset += srcFitStats->Noffset ;
+  return;
+}
 
 void initObjectData (Catalog *catalog, int Ncatalog) {
@@ -36,43 +64,7 @@
   ALLOCATE (pX, double, MAX (1, Nmax));
   ALLOCATE (pY, double, MAX (1, Nmax));
-}  
-
-void freeObjectData () {
-
-  free (R);
-  free (D);
-  free (T);
-  free (X);
-  free (Y);
-
-  free (dR);
-  free (dD);
-  free (dT);
-  free (dX);
-  free (dY);
-
-  free (pX);
-  free (pY);
-}  
-
-// This function operates on both Measure and MeasureTiny.  In the big stages, this should
-// be called with just MeasureTiny set and Measure == NULL
-int UpdateObjects (Catalog *catalog, int Ncatalog) {
-
-  off_t j, k, m;
-  int i, N, Nsecfilt, mode, result, status, XVERB;
-  StatType statsR, statsD;
-  Coords coords;
-  PMFit fitAve, fitPM, fitPAR, fit;
-  time_t T2000;
-  off_t Nave, Npm, Npar, Nskip, Noffset;
-  off_t NaveSum, NpmSum, NparSum, NskipSum, NoffSum;
-  double Tmin, Tmax, Tmean, Trange;
-
-  memset (&fit,    0, sizeof(fit));
-  memset (&fitAve, 0, sizeof(fitAve));
-  memset (&fitPM,  0, sizeof(fitPM));
-  memset (&fitPAR, 0, sizeof(fitPAR));
-  initObjectData (catalog, Ncatalog);
+
+  ALLOCATE (C_blue, double, MAX (1, Nmax));
+  ALLOCATE (C_red,  double, MAX (1, Nmax));
 
   /* project coordinates to a plane centered on the object with units of arcsec */
@@ -87,352 +79,605 @@
   strcpy (coords.ctype, "DEC--SIN");
 
-  XVERB = FALSE;
-
   // use J2000 as a reference time
-  T2000 = ohana_date_to_sec ("2000/01/01");
+  T2000 = ohana_date_to_sec ("2000/01/01,12:00:00");
+}  
+
+void freeObjectData () {
+
+  free (R);
+  free (D);
+  free (T);
+  free (X);
+  free (Y);
+
+  free (dR);
+  free (dD);
+  free (dT);
+  free (dX);
+  free (dY);
+
+  free (pX);
+  free (pY);
+
+  free (C_blue);
+  free (C_red);
+}  
+
+// This function operates on both Measure and MeasureTiny.  In the big stages, this should
+// be called with just MeasureTiny set and Measure == NULL
+int UpdateObjects (Catalog *catalog, int Ncatalog) {
+
+  initObjectData (catalog, Ncatalog);
+
   // XXX in the future, use catalog[0].Nsecfilt only?  allow catalogs to have variable Nsecfilt?
-
-  Nsecfilt = GetPhotcodeNsecfilt ();
+  int Nsecfilt = GetPhotcodeNsecfilt ();
   if (Ncatalog) {
     assert (catalog[0].Nsecfilt == Nsecfilt);
   }
 
-  NaveSum = NparSum = NpmSum = NoffSum = NskipSum = 0;
+  FitStats sumStatsChips; initFitStats (&sumStatsChips);
+  FitStats sumStatsStack; initFitStats (&sumStatsStack);
+
+  int i;
   for (i = 0; i < Ncatalog; i++) {
 
     if (VERBOSE2) fprintf (stderr, "astrometrize catalog %d : "OFF_T_FMT" ave, "OFF_T_FMT" meas\n", i,  catalog[i].Naverage,  catalog[i].Nmeasure);
 
-    Nave = Npar = Npm = Nskip = Noffset = 0;
+    FitStats fitStatsChips; initFitStats (&fitStatsChips);
+    FitStats fitStatsStack; initFitStats (&fitStatsStack);
+
+    off_t j;
     for (j = 0; j < catalog[i].Naverage; j++) {
       /* calculate the average value of R,D for a single star */
-
-      XVERB = FALSE;
-      fitAve.chisq = NAN;
-      fitPM.chisq = NAN;
-      fitPAR.chisq = NAN;
-
-      if (catalog[i].average[j].Nmeasure == 0) {
-	  continue;
-      }
-
-      N = 0;
-      m = catalog[i].average[j].measureOffset;
+      off_t m = catalog[i].average[j].measureOffset;
       MeasureTiny *measure = &catalog[i].measureT[m];
       Measure *measureBig = catalog[i].measure ? &catalog[i].measure[m] : NULL;
-      // when we update the output measure values, we need to do it here
-
-      mode = FIT_MODE;
-
-      // XVERB |= (catalog[i].averge[j].objID == 0xc90) && (catalog[i].average[j].catID == 0x2a1e);
-      XVERB |= (catalog[i].average[j].objID == OBJ_ID_SRC) && (catalog[i].average[j].catID == CAT_ID_SRC);
-      XVERB |= (catalog[i].average[j].objID == OBJ_ID_DST) && (catalog[i].average[j].catID == CAT_ID_DST);
-
-      // find the basic properties of the detections for this object (Tmin, Tmax, Tmean)
-      for (k = 0; k < catalog[i].average[j].Nmeasure; k++) {
-
-	if (XVERB) {
-	  char *date = ohana_sec_to_date (measure[k].t);
-	  int dbFlagsBig = measureBig ? measureBig[k].dbFlags : 0;
-	  fprintf (stderr, OFF_T_FMT" %f %f %s : 0x%08x : 0x%08x\n",  k, measure[k].dR, measure[k].dD, date, measure[k].dbFlags, dbFlagsBig);
-	  free (date);
-	}
-
-	// does the measurement pass the supplied filtering constraints?
-	// MeasFilterTestTiny does not test psfQF
-	int keepMeasure = measureBig ? MeasFilterTest(&measureBig[k], FALSE) : MeasFilterTestTiny(&measure[k], FALSE);
-	if (!keepMeasure) {
-	  measure[k].dbFlags &= ~ID_MEAS_USED_OBJ;
-	  if (measureBig) { measureBig[k].dbFlags &= ~ID_MEAS_USED_OBJ; }
-	  continue;
-	}
-
-	// outlier rejection
-	if (FlagOutlier && (measure[k].dbFlags & ID_MEAS_POOR_ASTROM)) {
-	  measure[k].dbFlags &= ~ID_MEAS_USED_OBJ;
-	  if (measureBig) { measureBig[k].dbFlags &= ~ID_MEAS_USED_OBJ; }
-	  continue;
-	}
-
-	measure[k].dbFlags |= ID_MEAS_USED_OBJ;
-	if (measureBig) { measureBig[k].dbFlags |= ID_MEAS_USED_OBJ; }
-
-	R[N] = getMeanR (&measure[k], &catalog[i].average[j], &catalog[i].secfilt[j*Nsecfilt]);
-	D[N] = getMeanD (&measure[k], &catalog[i].average[j], &catalog[i].secfilt[j*Nsecfilt]);
-
-	// XXX I think this is a problem: T[] is time in years relative to J2000, but ParFactor expects
-	// to get Time in years relative to UNIX Tzero (1970/01/01)
-	T[N] = (measure[k].t - T2000) / (86400*365.25) ; // time relative to J2000 in years
-
-	// dX, dY : error in arcsec -- 
-	dX[N] = GetAstromErrorTiny (&measure[k], ERROR_MODE_RA);
-	dY[N] = GetAstromErrorTiny (&measure[k], ERROR_MODE_DEC);
-
-	// allow a given photcode or measurement to be
-	// ignored if the error is NAN (for photcode, set astromErrSys to NaN)
-	if (isnan(dX[N])) {
-	  measure[k].dbFlags &= ~ID_MEAS_USED_OBJ;
-	  if (measureBig) { measureBig[k].dbFlags &= ~ID_MEAS_USED_OBJ; }
-	  continue;
-	}
-	if (isnan(dY[N])) {
-	  measure[k].dbFlags &= ~ID_MEAS_USED_OBJ;
-	  if (measureBig) { measureBig[k].dbFlags &= ~ID_MEAS_USED_OBJ; }
-	  continue;
-	}
-
-	// add systematic error in quadrature, if desired
-	// only do this after the fit has converged (or you will never improve the poor images)
-	// if (INCLUDE_SYS_ERR) {
-	// float dRsys = FromShortPixels(measure[k].dRsys);
-	// dX[N] = hypot(dX[N], dRsys);
-	// dY[N] = hypot(dY[N], dRsys);
-	// }
-
-	// dX[N] = 0.1;
-	// dY[N] = 0.1;
-
-	dT[N] = measure[k].dt;
-
-	// XXX this is (slightly) inconsistent: dX,dY are the X and Y direction errors in
-	// arcseconds.  dR, dD are the errors in those directions in degrees.  IF we have
-	// non-circular errors (different values for X and Y), then dR and dD will be
-	// incorrect: they would need to be rotated to take out the position angle
-	dR[N] = dX[N] / 3600.0;
-	dD[N] = dY[N] / 3600.0;
-
-	N++;
-      }
-
-      // if we have too few good detections for the desired fit, or too limited a
-      // baseline, use a fit with fewer parameters.  XXX if we have too few measurements
-      // for even the average position, consider including the lower-quality detections?
-
-      catalog[i].average[j].flags &= ~ID_STAR_NO_ASTROM;
-
-      // find Tmin & Tmax from the list of accepted measurements
-      Tmean = 0;
-      Tmin = Tmax = T[0];
-      for (k = 0; k < N; k++) {
-	Tmin = MIN(Tmin, T[k]);
-	Tmax = MAX(Tmax, T[k]);
-	Tmean += T[k];
-      }
-      // XXX add the parallax factor range as a criterion as well
-      Trange = Tmax - Tmin;
-      if (Trange < PM_DT_MIN) mode = FIT_AVERAGE;
-      if (((mode == FIT_PM_ONLY) || (mode == FIT_PM_AND_PAR)) && (N <= PM_TOOFEW)) mode = FIT_AVERAGE;
-
-      if (RELASTRO_OP == OP_HIGH_SPEED) {
-	  Tmean = 0.5*(Tmax - Tmin);
-      } else {
-	  Tmean /= (float) N;
-      }
-
-      // too few measurements for average position (require 2 values)
-      if (N < SRC_MEAS_TOOFEW) {
-	// XXX need to define PHOTOM and ASTROM object flags
-	// XXX reset the average value fields?
-	catalog[i].average[j].flags |= ID_STAR_NO_ASTROM;
-	catalog[i].average[j].ChiSqAve  = NAN;
-	catalog[i].average[j].ChiSqPM   = NAN;
-	catalog[i].average[j].ChiSqPar  = NAN;
-	if (N < 2) continue;
-      }
-
-      /* we need to do the fit in a locally linear space; choose a ref coordinate */
-      coords.crval1 = R[0];
-      coords.crval2 = D[0];
-
-      // to judge the quality of the PM and PAR fits, we need to fit all three models and compare Chisq
-
-      if ((mode == FIT_PM_ONLY) || (mode == FIT_PM_AND_PAR)) {
-	// project all of the R,D coordinates to a plane centered on this coordinate. set
-	// the times to be relative to Tmean (this is required for parallax as well)
-	for (k = 0; k < N; k++) {
-	  RD_to_XY (&X[k], &Y[k], R[k], D[k], &coords);
-	  T[k] -= Tmean;
-	  if (XVERB) {
-	    fprintf (stderr, OFF_T_FMT" %f %f %f  %f %f +/- %f %f\n",  k, T[k], R[k], D[k], X[k], Y[k], dX[k], dY[k]);
-	  }
-	}	  
-
-	FitPM (&fitPM, X, dX, Y, dY, T, N, XVERB);
-
-	if (XVERB) fprintf (stderr, "fitted PM:  %f - %f : %f %f : %f %f : %f vs %f\n", Tmin, Tmax, fitPM.Ro, fitPM.Do, fitPM.uR, fitPM.uD, fitPM.chisq, fitAve.chisq);
-
-	// project Ro, Do back to RA,DEC
-	XY_to_RD (&fitPM.Ro, &fitPM.Do, fitPM.Ro, fitPM.Do, &coords);
-	if (XVERB) fprintf (stderr, "project: %f %f : %f %f : %f\n", fitPM.Ro, fitPM.Do, fitPM.uR, fitPM.uD, fitPM.p);
-
-	fitPM.p  = fitPM.dp  = 0.0;
-	catalog[i].average[j].flags |= ID_STAR_FIT_PM;
-	Npm ++;
-      }
-
-      if (mode == FIT_PM_AND_PAR) {
-	// fprintf (stderr, "parallax fitting is still untested (%s, %d)\n", __FILE__, __LINE__);
-
-	float pXmin = +2.0;
-	float pXmax = -2.0;
-	float pYmin = +2.0;
-	float pYmax = -2.0;
-	for (k = 0; k < N; k++) {
-	  ParFactor (&pX[k], &pY[k], R[k], D[k], T[k], Tmean);
-	  pXmin = MIN (pXmin, pX[k]);
-	  pXmax = MAX (pXmax, pX[k]);
-	  pYmin = MIN (pYmin, pY[k]);
-	  pYmax = MAX (pYmax, pY[k]);
-	}
-	float dXRange = pXmax - pXmin;
-	float dYRange = pYmax - pYmin;
-	float parRange = hypot (dXRange, dYRange);
-	
-# define PAR_TOOFEW 5
-	if ((parRange >= PAR_FACTOR_MIN) && (N > PAR_TOOFEW)) {
-	  FitPMandPar (&fitPAR, X, dX, Y, dY, T, pX, pY, N, XVERB);
-	  if (XVERB) fprintf (stderr, "fitted PM+PAR:  %f - %f : %f %f : %f %f : %f %f : %f vs %f vs %f\n", Tmin, Tmax, fitPAR.Ro, fitPAR.Do, fitPAR.uR, fitPAR.uD, fitPAR.p, fitPAR.dp, fitPAR.chisq, fitPM.chisq, fitAve.chisq);
-
-	  XY_to_RD (&fitPAR.Ro, &fitPAR.Do, fitPAR.Ro, fitPAR.Do, &coords);
-	  catalog[i].average[j].flags |= ID_STAR_FIT_PAR;
-	  Npar ++;
-	} else {
-	  // need to set mode = FIT_PM_ONLY if we do not fit for parallax
-	  mode = FIT_PM_ONLY;
-	}
-      }	  
-
-      // fit the average model
-      if ((mode == FIT_AVERAGE) || (mode == FIT_PM_ONLY) || (mode == FIT_PM_AND_PAR)) {
-	liststats_pos (R, dR, N, &statsR, XVERB); // WARNING: this function modifies R (do not use after here)
-	liststats_pos (D, dD, N, &statsD, XVERB); // WARNING: this function modifies D (do not use after here)
-
-	fitAve.Ro = statsR.mean;
-	fitAve.dRo = 3600.0*statsR.sigma;
-
-	fitAve.Do = statsD.mean;
-	fitAve.dDo = 3600.0*statsD.sigma;
-
-	fitAve.chisq = 0.5 * (statsR.chisq + statsD.chisq);
-	fitAve.Nfit = N;
-
-	fitAve.uR = fitAve.duR = 0.0;
-	fitAve.uD = fitAve.duD = 0.0;
-	fitAve.p  = fitAve.dp  = 0.0;
-	catalog[i].average[j].flags |= ID_STAR_FIT_AVE;
-	Nave ++;
-      }
-
-      /* choose the result based on the chisq values */
-      // XXXX for now, just use the mode as the result:
-      result = mode;
-
-      switch (result) {
-      case FIT_AVERAGE:
-	catalog[i].average[j].flags |= ID_STAR_USE_AVE;
-	fit = fitAve;
-	break;
-      case FIT_PM_ONLY:
-	catalog[i].average[j].flags |= ID_STAR_USE_PM;
-	fit = fitPM;
-	break;
-      case FIT_PM_AND_PAR:
-	catalog[i].average[j].flags |= ID_STAR_USE_PAR;
-	fit = fitPAR;
-	break;
-      }
-      if (XVERB) fprintf (stderr, "%f %f -> %f %f (%f,%f) pm=(%f %f) plx=(%f +/- %f)\n",
-			  catalog[i].average[j].R, 
-			  catalog[i].average[j].D, 
-			  fit.Ro, fit.Do, 
-			  3600*(catalog[i].average[j].R - fit.Ro), 
-			  3600*(catalog[i].average[j].D - fit.Do),
-			  fit.uR, fit.uD, fit.p, fit.dp);
-
-      // make sure that the fit succeeded
-      status = TRUE;
-      status &= finite(fit.Ro);
-      status &= finite(fit.Do);
-      status &= finite(fit.dRo);
-      status &= finite(fit.dDo);
-      status &= finite(fit.uR);
-      status &= finite(fit.uD);
-      status &= finite(fit.duR);
-      status &= finite(fit.duD);
-      status &= finite(fit.p);
-      status &= finite(fit.dp);
-      if (!status) {
-	Nskip ++;
+      Average *average = &catalog[i].average[j];
+      SecFilt *secfilt = &catalog[i].secfilt[j*Nsecfilt];
+
+      UpdateObjects_Stack(average, secfilt, measure, measureBig, Nsecfilt, &fitStatsStack);
+      UpdateObjects_Chips(average, secfilt, measure, measureBig, Nsecfilt, &fitStatsChips, i, m);
+    }
+    if (VERBOSE) fprintf (stderr, "catalog %d : chips "OFF_T_FMT" ave, "OFF_T_FMT" pm, "OFF_T_FMT" par : Nskip "OFF_T_FMT", Noffset "OFF_T_FMT"\n",  i,  fitStatsChips.Nave,  fitStatsChips.Npm,  fitStatsChips.Npar,  fitStatsChips.Nskip, fitStatsChips.Noffset);
+    if (VERBOSE) fprintf (stderr, "catalog %d : stack "OFF_T_FMT" ave, "OFF_T_FMT" pm, "OFF_T_FMT" par : Nskip "OFF_T_FMT", Noffset "OFF_T_FMT"\n",  i,  fitStatsStack.Nave,  fitStatsStack.Npm,  fitStatsStack.Npar,  fitStatsStack.Nskip, fitStatsStack.Noffset);
+    sumFitStats (&fitStatsChips, &sumStatsChips);
+    sumFitStats (&fitStatsStack, &sumStatsStack);
+  }
+  freeObjectData ();
+
+  if (VERBOSE) fprintf (stderr, "fitted "OFF_T_FMT" objects ("OFF_T_FMT" ave, "OFF_T_FMT" pm, "OFF_T_FMT" par), skipped "OFF_T_FMT", "OFF_T_FMT" have too large an offset\n",  (sumStatsChips.Nave + sumStatsChips.Npm + sumStatsChips.Npar),  sumStatsChips.Nave,  sumStatsChips.Npm,  sumStatsChips.Npar,  sumStatsChips.Nskip, sumStatsChips.Noffset);
+  if (VERBOSE) fprintf (stderr, "fitted "OFF_T_FMT" objects ("OFF_T_FMT" ave, "OFF_T_FMT" pm, "OFF_T_FMT" par), skipped "OFF_T_FMT", "OFF_T_FMT" have too large an offset\n",  (sumStatsStack.Nave + sumStatsStack.Npm + sumStatsStack.Npar),  sumStatsStack.Nave,  sumStatsStack.Npm,  sumStatsStack.Npar,  sumStatsStack.Nskip, sumStatsStack.Noffset);
+  return (TRUE);
+}
+
+// This function operates on both Measure and MeasureTiny.  In the big stages, this should
+// be called with just MeasureTiny set and Measure == NULL
+int UpdateObjects_Chips (Average *average, SecFilt *secfilt, MeasureTiny *measure, Measure *measureBig, int Nsecfilt, FitStats *fitStats, int i, off_t m) {
+
+  int setRefColor = areImagesMatched();
+
+  /* calculate the average value of R,D for a single star */
+
+  PMFit fit;    memset (&fit,    0, sizeof(fit));
+  PMFit fitAve; memset (&fitAve, 0, sizeof(fitAve)); fitAve.chisq = NAN;
+  PMFit fitPM;  memset (&fitPM,  0, sizeof(fitPM));  fitPM.chisq = NAN;
+  PMFit fitPAR; memset (&fitPAR, 0, sizeof(fitPAR)); fitPAR.chisq = NAN;
+
+  // if we fail to fit the astrometry for some reason, we need to set/reset these
+  average[0].flags |= ID_STAR_NO_ASTROM;
+  average[0].ChiSqAve  = NAN;
+  average[0].ChiSqPM   = NAN;
+  average[0].ChiSqPar  = NAN;
+  average[0].Npos = 0;
+
+  // an object with no measurements is externally supplied
+  if (average[0].Nmeasure == 0) return TRUE;
+
+  int NcBlue = 0;
+  int NcRed = 0;
+  int N = 0;
+
+  int mode = FIT_MODE; // start with the globally-defined fit mode
+
+  int XVERB = FALSE;
+  XVERB |= (average[0].objID == OBJ_ID_SRC) && (average[0].catID == CAT_ID_SRC);
+  XVERB |= (average[0].objID == OBJ_ID_DST) && (average[0].catID == CAT_ID_DST);
+
+  // find the basic properties of the detections for this object (Tmin, Tmax, Tmean)
+  off_t k;
+  for (k = 0; k < average[0].Nmeasure; k++) {
+
+    if (XVERB) {
+      char *date = ohana_sec_to_date (measure[k].t);
+      int dbFlagsBig = measureBig ? measureBig[k].dbFlags : 0;
+      fprintf (stderr, OFF_T_FMT" %f %f %s : 0x%08x : 0x%08x\n",  k, measure[k].R, measure[k].D, date, measure[k].dbFlags, dbFlagsBig);
+      free (date);
+    }
+
+    // SKIP gpc1 stack data
+    if (isGPC1stack(measure[k].photcode)) continue;
+
+    // SKIP gpc1 forced-warp data
+    if (isGPC1warp(measure[k].photcode)) continue;
+
+    // reset the bit to note that a detection was used (or not)
+    measure[k].dbFlags &= ~ID_MEAS_USED_OBJ;
+    if (measureBig) { measureBig[k].dbFlags &= ~ID_MEAS_USED_OBJ; }
+
+    // does the measurement pass the supplied filtering constraints?
+    // MeasFilterTestTiny does not test psfQF
+    // exclude bad detections based on: photcodes, psfQF, time range, photflags & astromBadMask, mag_inst
+    int keepMeasure = measureBig ? MeasFilterTest(&measureBig[k], FALSE) : MeasFilterTestTiny(&measure[k], FALSE);
+    if (!keepMeasure) {
+      continue;
+    }
+
+    double Ri = getMeanR (&measure[k], average, secfilt);
+    double Di = getMeanD (&measure[k], average, secfilt);
+
+    // mark (as POOR) any measurements which are deviant from the mean by > ExcludeBogusRadius
+    if (ExcludeBogus) {
+      coords.crval1 = average[0].R;
+      coords.crval2 = average[0].D;
+      double Xi, Yi;
+      RD_to_XY (&Xi, &Yi, Ri, Di, &coords);
+      double radius = hypot(Xi, Yi);
+      if (radius > ExcludeBogusRadius) {
+	measure[k].dbFlags |= ID_MEAS_POOR_ASTROM;
+	if (measureBig) { measureBig[k].dbFlags |= ID_MEAS_POOR_ASTROM; }
 	continue;
       }
-
-      // what is the offset relative to the mean fit position?
-      coords.crval1 = catalog[i].average[j].R;
-      coords.crval2 = catalog[i].average[j].D;
-
-      double dXoff, dYoff;
-      RD_to_XY (&dXoff, &dYoff, fit.Ro, fit.Do, &coords);
-      float dPos = hypot (dXoff, dYoff);
-      if (dPos > MaxMeanOffset) {
-	if (Noffset < 100) {
-	  fprintf (stderr, "(%f,%f) -> (%f,%f) (%f,%f)\n", coords.crval1, coords.crval2, fit.Ro, fit.Do, dXoff, dYoff);
-	}
-	Noffset ++;
-	continue;
+      measure[k].dbFlags &= ~ID_MEAS_POOR_ASTROM;
+      if (measureBig) { measureBig[k].dbFlags &= ~ID_MEAS_POOR_ASTROM; }
+    }
+
+    // outlier rejection
+    if (FALSE && FlagOutlier && (measure[k].dbFlags & ID_MEAS_POOR_ASTROM)) {
+      continue;
+    }
+
+    R[N] = Ri;
+    D[N] = Di;
+
+    // measure[k].t is UNIX seconds, T2000 is UNIX seconds for J2000.
+    // T[] is time in years since J2000 (jd = 2451545)
+    T[N] = (measure[k].t - T2000) / (86400*365.25) ; // time relative to J2000 in years
+
+    // dX, dY : error in arcsec -- 
+    dX[N] = GetAstromErrorTiny (&measure[k], ERROR_MODE_RA);
+    dY[N] = GetAstromErrorTiny (&measure[k], ERROR_MODE_DEC);
+
+    // allow a given photcode or measurement to be
+    // ignored if the error is NAN (for photcode, set astromErrSys to NaN)
+    if (isnan(dX[N])) continue;
+    if (isnan(dY[N])) continue;
+
+    // add systematic error in quadrature, if desired
+    // only do this after the fit has converged (or you will never improve the poor images)
+    // if (INCLUDE_SYS_ERR) {
+    // float dRsys = FromShortPixels(measure[k].dRsys);
+    // dX[N] = hypot(dX[N], dRsys);
+    // dY[N] = hypot(dY[N], dRsys);
+    // }
+
+    // dX[N] = 0.1;
+    // dY[N] = 0.1;
+
+    dT[N] = measure[k].dt;
+
+    // XXX this is (slightly) inconsistent: dX,dY are the X and Y direction errors in
+    // arcseconds.  dR, dD are the errors in those directions in degrees.  IF we have
+    // non-circular errors (different values for X and Y), then dR and dD will be
+    // incorrect: they would need to be rotated to take out the position angle
+    dR[N] = dX[N] / 3600.0;
+    dD[N] = dY[N] / 3600.0;
+
+    if (setRefColor) {
+      float colorBlue = getColorBlue (m+k, i);
+      if (!isnan(colorBlue)) {
+	C_blue[NcBlue] = colorBlue;
+	NcBlue++;
       }
-
-
-      // the measure fields must be updated before the average fields
-      for (k = 0; k < catalog[i].average[j].Nmeasure; k++) {
-	setMeanR (fit.Ro, &measure[k], &catalog[i].average[j], &catalog[i].secfilt[j*Nsecfilt]);
-	setMeanD (fit.Do, &measure[k], &catalog[i].average[j], &catalog[i].secfilt[j*Nsecfilt]);
-	if (measureBig) {
-	  setMeanR_Big (fit.Ro, &measureBig[k], &catalog[i].average[j], &catalog[i].secfilt[j*Nsecfilt]);
-	  setMeanD_Big (fit.Do, &measureBig[k], &catalog[i].average[j], &catalog[i].secfilt[j*Nsecfilt]);
-	}
-      }      
-
-      catalog[i].average[j].R  	= fit.Ro; // RA in degrees
-      catalog[i].average[j].D  	= fit.Do; // DEC in degrees
-      catalog[i].average[j].dR 	= fit.dRo; // RA scatter in arcsec
-      catalog[i].average[j].dD 	= fit.dDo; // DEC scatter in arcsec
-
-      catalog[i].average[j].uR  = fit.uR; // RA proper motion in arcsec/year
-      catalog[i].average[j].uD  = fit.uD; // DEC proper motion in arcsec/year
-      catalog[i].average[j].duR = fit.duR; // RA proper motion error in arcsec/year
-      catalog[i].average[j].duD = fit.duD; // DEC proper motion error in arcsec/year
-
-      catalog[i].average[j].P   = fit.p; // parallax in arcsec
-      catalog[i].average[j].dP  = fit.dp; // parallax error in arcsec
-
-      catalog[i].average[j].ChiSqAve  = fitAve.chisq;
-      catalog[i].average[j].ChiSqPM   = fitPM.chisq;
-      catalog[i].average[j].ChiSqPar  = fitPAR.chisq;
-      catalog[i].average[j].Tmean = (Tmean * 86400 * 365.25) + T2000;
-      catalog[i].average[j].Trange = (Trange * 86400 * 365.25);
-      catalog[i].average[j].Npos = fit.Nfit;
-      if (XVERB) fprintf (stderr, "%f %f -> %f %f (%f,%f) pm=(%f %f) chisq=(%f, %f, %f)\n",
-                          catalog[i].average[j].R,
-                          catalog[i].average[j].D,
-                          fit.Ro, fit.Do,
-                          3600*(catalog[i].average[j].R - fit.Ro),
-                          3600*(catalog[i].average[j].D - fit.Do),
-                          catalog[i].average[j].uR,
-                          catalog[i].average[j].uD,
-			  fitAve.chisq, fitPM.chisq, fitPAR.chisq);
-    }
-
-    NaveSum += Nave;
-    NpmSum += Npm;
-    NparSum += Npar;
-    NskipSum += Nskip;
-    NoffSum += Noffset;
-    if (VERBOSE) fprintf (stderr, "catalog %d : "OFF_T_FMT" ave, "OFF_T_FMT" pm, "OFF_T_FMT" par : Nskip "OFF_T_FMT", Noffset "OFF_T_FMT"\n",  i,  Nave,  Npm,  Npar,  Nskip, Noffset);
-  }
-
-  freeObjectData ();
-
-  if (VERBOSE) fprintf (stderr, "fitted "OFF_T_FMT" objects ("OFF_T_FMT" ave, "OFF_T_FMT" pm, "OFF_T_FMT" par), skipped "OFF_T_FMT", "OFF_T_FMT" have too large an offset\n",  (NaveSum + NpmSum + NparSum),  NaveSum,  NpmSum,  NparSum,  NskipSum, NoffSum);
+      float colorRed = getColorRed (m+k, i);
+      if (!isnan(colorRed)) {
+	C_red[NcRed] = colorRed;
+	NcRed++;
+      }
+    }
+
+    measure[k].dbFlags |= ID_MEAS_USED_OBJ;
+    if (measureBig) { measureBig[k].dbFlags |= ID_MEAS_USED_OBJ; }
+
+    N++;
+  } // loop over measurements : average[0].Nmeasure 
+
+  if (N < 1) { 
+    if (isfinite(average[0].Rstk) && isfinite(average[0].Dstk)) {
+      average[0].R  = average[0].Rstk;
+      average[0].D  = average[0].Dstk;
+      average[0].dR = average[0].dRstk;
+      average[0].dD = average[0].dDstk;
+    }
+    return FALSE;
+  }
+
+  // if we have too few good detections for the desired fit, or too limited a
+  // baseline, use a fit with fewer parameters.  XXX if we have too few measurements
+  // for even the average position, consider including the lower-quality detections?
+
+  // find Tmin & Tmax from the list of accepted measurements
+  double Tmean = 0.0;
+  double Tmin = T[0];
+  double Tmax = T[0];
+  for (k = 0; k < N; k++) {
+    Tmin = MIN(Tmin, T[k]);
+    Tmax = MAX(Tmax, T[k]);
+    Tmean += T[k];
+  }
+  double Trange = Tmax - Tmin;
+
+  if (RELASTRO_OP == OP_HIGH_SPEED) {
+    Tmean = 0.5*(Tmax - Tmin);
+  } else {
+    Tmean /= (float) N;
+  }
+
+  /* we need to do the fit in a locally linear space; choose a ref coordinate */
+  coords.crval1 = R[0];
+  coords.crval2 = D[0];
+
+  // to judge the quality of the PM and PAR fits, we need to fit all three models and compare Chisq
+
+  // *** first fit for the proper motion (skip fit if Trange or Npts is too small) ***
+  if ((mode == FIT_PM_ONLY) || (mode == FIT_PM_AND_PAR)) {
+    if (Trange < PM_DT_MIN) {
+      mode = FIT_AVERAGE;
+      goto skipPM;
+    }
+    if (N <= PM_TOOFEW) {
+      mode = FIT_AVERAGE;
+      goto skipPM;
+    }
+
+    // project all of the R,D coordinates to a plane centered on this coordinate. set
+    // the times to be relative to Tmean (this is required for parallax as well)
+    for (k = 0; k < N; k++) {
+      RD_to_XY (&X[k], &Y[k], R[k], D[k], &coords);
+      T[k] -= Tmean;
+      if (XVERB) {
+	fprintf (stderr, OFF_T_FMT" %f %f %f  %f %f +/- %f %f\n",  k, T[k], R[k], D[k], X[k], Y[k], dX[k], dY[k]);
+      }
+    }	  
+
+    FitPM (&fitPM, X, dX, Y, dY, T, N, XVERB);
+
+    if (XVERB) fprintf (stderr, "fitted PM:  %f - %f : %f %f : %f %f : %f vs %f\n", Tmin, Tmax, fitPM.Ro, fitPM.Do, fitPM.uR, fitPM.uD, fitPM.chisq, fitAve.chisq);
+
+    // project Ro, Do back to RA,DEC
+    XY_to_RD (&fitPM.Ro, &fitPM.Do, fitPM.Ro, fitPM.Do, &coords);
+    if (XVERB) fprintf (stderr, "project: %f %f : %f %f : %f\n", fitPM.Ro, fitPM.Do, fitPM.uR, fitPM.uD, fitPM.p);
+
+    fitPM.p  = fitPM.dp  = 0.0;
+    average[0].flags |= ID_STAR_FIT_PM;
+    fitStats->Npm ++;
+
+    // XXX a hard-wired hack...
+    if ((fabs(fitPM.uR) > 2.0) || (fabs(fitPM.uD) > 2.0)) {
+      mode = FIT_AVERAGE;
+      average[0].flags |= ID_STAR_BAD_PM;
+    }
+  }
+  
+skipPM:
+  // fit the parallax + proper-motion model
+  // NOTE : we only fit PAR if we have already fitted for proper motion. if we do not fit PM or we fail
+  // to fit PM, we do not attempt PAR.  thus failure to fit PAR falls back to PM-only
+  if (mode == FIT_PM_AND_PAR) {
+    if (Trange < PM_DT_MIN) {
+      mode = FIT_PM_ONLY;
+      goto skipPAR;
+    }
+    if (N <= PAR_TOOFEW) {
+      mode = FIT_PM_ONLY;
+      goto skipPAR;
+    }
+    float pXmin = +2.0;
+    float pXmax = -2.0;
+    float pYmin = +2.0;
+    float pYmax = -2.0;
+    for (k = 0; k < N; k++) {
+      ParFactor (&pX[k], &pY[k], R[k], D[k], T[k], Tmean);
+      pXmin = MIN (pXmin, pX[k]);
+      pXmax = MAX (pXmax, pX[k]);
+      pYmin = MIN (pYmin, pY[k]);
+      pYmax = MAX (pYmax, pY[k]);
+    }
+    float dXRange = pXmax - pXmin;
+    float dYRange = pYmax - pYmin;
+    float parRange = hypot (dXRange, dYRange);
+	
+    if (parRange < PAR_FACTOR_MIN) {
+      mode = FIT_PM_ONLY;
+      goto skipPAR;
+    }
+
+    FitPMandPar (&fitPAR, X, dX, Y, dY, T, pX, pY, N, XVERB);
+    if (XVERB) fprintf (stderr, "fitted PM+PAR:  %f - %f : %f %f : %f %f : %f %f : %f vs %f vs %f\n", Tmin, Tmax, fitPAR.Ro, fitPAR.Do, fitPAR.uR, fitPAR.uD, fitPAR.p, fitPAR.dp, fitPAR.chisq, fitPM.chisq, fitAve.chisq);
+
+    XY_to_RD (&fitPAR.Ro, &fitPAR.Do, fitPAR.Ro, fitPAR.Do, &coords);
+    average[0].flags |= ID_STAR_FIT_PAR;
+    fitStats->Npar ++;
+
+    // XXX a hard-wired hack...
+    if ((fabs(fitPAR.uR) > 2.0) || (fabs(fitPAR.uD) > 2.0)) {
+      mode = FIT_PM_ONLY;
+    }
+  }	  
+
+skipPAR:
+  {
+    // ALWAYS fit the average model
+    StatType statsR, statsD;
+    liststats_pos (R, dR, N, &statsR, XVERB); // WARNING: this function modifies R (do not use after here)
+    liststats_pos (D, dD, N, &statsD, XVERB); // WARNING: this function modifies D (do not use after here)
+
+    fitAve.Ro = statsR.mean;
+    fitAve.dRo = 3600.0*statsR.sigma;
+
+    fitAve.Do = statsD.mean;
+    fitAve.dDo = 3600.0*statsD.sigma;
+
+    fitAve.chisq = (N > 1) ? 0.5 * (statsR.chisq + statsD.chisq) : NAN;
+    fitAve.Nfit = N;
+
+    fitAve.uR = fitAve.duR = 0.0;
+    fitAve.uD = fitAve.duD = 0.0;
+    fitAve.p  = fitAve.dp  = 0.0;
+    average[0].flags |= ID_STAR_FIT_AVE;
+    fitStats->Nave ++;
+  }
+
+  if (setRefColor) {
+    float colorMedian;
+    dsort (C_blue, NcBlue);
+    colorMedian = (NcBlue > 0) ? C_blue[(int)(0.5*NcBlue)] : NAN;
+    average[0].refColorBlue = colorMedian;
+    dsort (C_red, NcRed);
+    colorMedian = (NcRed > 0) ? C_red[(int)(0.5*NcRed)] : NAN;
+    average[0].refColorRed = colorMedian;
+  }
+
+  /* choose the result based on the chisq values */
+  // XXXX for now, just use the mode as the result:
+  int result = mode;
+
+  switch (result) {
+    case FIT_AVERAGE:
+      average[0].flags |= ID_STAR_USE_AVE;
+      fit = fitAve;
+      break;
+    case FIT_PM_ONLY:
+      average[0].flags |= ID_STAR_USE_PM;
+      fit = fitPM;
+      break;
+    case FIT_PM_AND_PAR:
+      average[0].flags |= ID_STAR_USE_PAR;
+      fit = fitPAR;
+      break;
+  }
+  if (XVERB) fprintf (stderr, "%f %f -> %f %f (%f,%f) pm=(%f %f) plx=(%f +/- %f)\n",
+		      average[0].R, 
+		      average[0].D, 
+		      fit.Ro, fit.Do, 
+		      3600*(average[0].R - fit.Ro), 
+		      3600*(average[0].D - fit.Do),
+		      fit.uR, fit.uD, fit.p, fit.dp);
+
+  // make sure that the fit succeeded
+  int status = TRUE;
+  status &= finite(fit.Ro);
+  status &= finite(fit.Do);
+  status &= finite(fit.dRo);
+  status &= finite(fit.dDo);
+  status &= finite(fit.uR);
+  status &= finite(fit.uD);
+  status &= finite(fit.duR);
+  status &= finite(fit.duD);
+  status &= finite(fit.p);
+  status &= finite(fit.dp);
+  if (!status) {
+    fitStats->Nskip ++;
+    return FALSE; // XXX ??
+  }
+
+  // what is the offset relative to the mean fit position?
+  coords.crval1 = average[0].R;
+  coords.crval2 = average[0].D;
+
+  double dXoff, dYoff;
+  RD_to_XY (&dXoff, &dYoff, fit.Ro, fit.Do, &coords);
+  float dPos = hypot (dXoff, dYoff);
+  if (dPos > MaxMeanOffset) {
+    if (fitStats->Noffset < 100) {
+      fprintf (stderr, "(%f,%f) -> (%f,%f) (%f,%f)\n", coords.crval1, coords.crval2, fit.Ro, fit.Do, dXoff, dYoff);
+    }
+    fitStats->Noffset ++;
+    return FALSE; // XXX ??
+  }
+
+  average[0].R  	= fit.Ro; // RA in degrees
+  average[0].D  	= fit.Do; // DEC in degrees
+  average[0].dR 	= fit.dRo; // RA scatter in arcsec
+  average[0].dD 	= fit.dDo; // DEC scatter in arcsec
+
+  average[0].uR         = fit.uR; // RA proper motion in arcsec/year
+  average[0].uD         = fit.uD; // DEC proper motion in arcsec/year
+  average[0].duR        = fit.duR; // RA proper motion error in arcsec/year
+  average[0].duD        = fit.duD; // DEC proper motion error in arcsec/year
+
+  average[0].P          = fit.p; // parallax in arcsec
+  average[0].dP         = fit.dp; // parallax error in arcsec
+
+  average[0].ChiSqAve   = fitAve.chisq;
+  average[0].ChiSqPM    = fitPM.chisq;
+  average[0].ChiSqPar   = fitPAR.chisq;
+
+  average[0].Tmean      = (Tmean * 86400 * 365.25) + T2000;
+  average[0].Trange     = (Trange * 86400 * 365.25);
+  average[0].Npos       = fit.Nfit;
+
+  // unset the NO_ASTROM bit (not(NO_ASTROM) == HAVE_ASTROM)
+  average[0].flags &= ~ID_STAR_NO_ASTROM;
+
+  if (XVERB) fprintf (stderr, "%f %f -> %f %f (%f,%f) pm=(%f %f) chisq=(%f, %f, %f)\n",
+		      average[0].R,
+		      average[0].D,
+		      fit.Ro, fit.Do,
+		      3600*(average[0].R - fit.Ro),
+		      3600*(average[0].D - fit.Do),
+		      average[0].uR,
+		      average[0].uD,
+		      fitAve.chisq, fitPM.chisq, fitPAR.chisq);
+
   return (TRUE);
 }
+
+// This function operates on both Measure and MeasureTiny.  In the big stages, this should
+// be called with just MeasureTiny set and Measure == NULL
+int UpdateObjects_Stack (Average *average, SecFilt *secfilt, MeasureTiny *measure, Measure *measureBig, int Nsecfilt, FitStats *fitStats) {
+
+  off_t k;
+
+  // set the default values
+  average[0].Rstk  = NAN; // RA in degrees
+  average[0].Dstk  = NAN; // DEC in degrees
+  average[0].dRstk = NAN; // RA scatter in arcsec
+  average[0].dDstk = NAN; // DEC scatter in arcsec
+
+  /* calculate the average value of R,D for a single star */
+  PMFit fitAve;
+  memset (&fitAve, 0, sizeof(fitAve));
+  fitAve.chisq = NAN;
+
+  if (average[0].Nmeasure == 0) return TRUE;
+
+  int N = 0;
+
+  int XVERB = FALSE;
+  XVERB |= (average[0].objID == OBJ_ID_SRC) && (average[0].catID == CAT_ID_SRC);
+  XVERB |= (average[0].objID == OBJ_ID_DST) && (average[0].catID == CAT_ID_DST);
+
+  // find the basic properties of the detections for this object (Tmin, Tmax, Tmean)
+  for (k = 0; k < average[0].Nmeasure; k++) {
+
+    if (XVERB) {
+      char *date = ohana_sec_to_date (measure[k].t);
+      int dbFlagsBig = measureBig ? measureBig[k].dbFlags : 0;
+      fprintf (stderr, "stack: "OFF_T_FMT" %f %f %s : 0x%08x : 0x%08x\n",  k, measure[k].R, measure[k].D, date, measure[k].dbFlags, dbFlagsBig);
+      free (date);
+    }
+
+    // SKIP everything except gpc1 stack data
+    if (!isGPC1stack(measure[k].photcode)) continue;
+
+    // exclude bad detections based on: photcodes, psfQF, time range, photflags & astromBadMask, mag_inst
+    int keepMeasure = measureBig ? MeasFilterTest(&measureBig[k], FALSE) : MeasFilterTestTiny(&measure[k], FALSE);
+    if (!keepMeasure) {
+      continue;
+    }
+
+    R[N] = getMeanR (&measure[k], average, secfilt);
+    D[N] = getMeanD (&measure[k], average, secfilt);
+
+    // dX, dY : error in arcsec -- 
+    dX[N] = GetAstromErrorTiny (&measure[k], ERROR_MODE_RA);
+    dY[N] = GetAstromErrorTiny (&measure[k], ERROR_MODE_DEC);
+
+    // allow a given photcode or measurement to be
+    // ignored if the error is NAN (for photcode, set astromErrSys to NaN)
+    if (isnan(dX[N])) continue;
+    if (isnan(dY[N])) continue;
+
+    // XXX this is (slightly) inconsistent: dX,dY are the X and Y direction errors in
+    // arcseconds.  dR, dD are the errors in those directions in degrees.  IF we have
+    // non-circular errors (different values for X and Y), then dR and dD will be
+    // incorrect: they would need to be rotated to take out the position angle
+    dR[N] = dX[N] / 3600.0;
+    dD[N] = dY[N] / 3600.0;
+
+    // XXX use a different flag for stack measurements?
+    // measure[k].dbFlags |= ID_MEAS_USED_OBJ;
+    // if (measureBig) { measureBig[k].dbFlags |= ID_MEAS_USED_OBJ; }
+
+    N++;
+  } // loop over measurements : average[0].Nmeasure 
+
+  // if we have too few good detections for the desired fit, or too limited a
+  // baseline, use a fit with fewer parameters.  XXX if we have too few measurements
+  // for even the average position, consider including the lower-quality detections?
+
+  // too few measurements for average position (require 2 values)
+  if (N < 1) return FALSE; // XXX ?? 
+
+  // find the mean position
+  StatType statsR, statsD;
+  liststats_pos (R, dR, N, &statsR, XVERB); // WARNING: this function modifies R (do not use after here)
+  liststats_pos (D, dD, N, &statsD, XVERB); // WARNING: this function modifies D (do not use after here)
+
+  fitAve.Ro = statsR.mean;
+  fitAve.dRo = 3600.0*statsR.sigma;
+
+  fitAve.Do = statsD.mean;
+  fitAve.dDo = 3600.0*statsD.sigma;
+
+  fitAve.chisq = 0.5 * (statsR.chisq + statsD.chisq);
+  fitAve.Nfit = N;
+
+  // XXX choose stack flag? average[0].flags |= ID_STAR_FIT_AVE;
+  fitStats->Nave ++;
+
+  if (XVERB) fprintf (stderr, "%f %f -> %f %f (%f,%f)\n",
+		      average[0].R, 
+		      average[0].D, 
+		      fitAve.Ro, fitAve.Do, 
+		      3600*(average[0].R - fitAve.Ro), 
+		      3600*(average[0].D - fitAve.Do));
+
+  // make sure that the fit succeeded
+  int status = TRUE;
+  status &= finite(fitAve.Ro);
+  status &= finite(fitAve.Do);
+  status &= finite(fitAve.dRo);
+  status &= finite(fitAve.dDo);
+  if (!status) {
+    fitStats->Nskip ++;
+    return FALSE;
+  }
+
+  // what is the offset relative to the mean fit position?
+  coords.crval1 = average[0].R;
+  coords.crval2 = average[0].D;
+
+  double dXoff, dYoff;
+  RD_to_XY (&dXoff, &dYoff, fitAve.Ro, fitAve.Do, &coords);
+  float dPos = hypot (dXoff, dYoff);
+  if (dPos > MaxMeanOffset) {
+    if (fitStats->Noffset < 100) {
+      fprintf (stderr, "(%f,%f) -> (%f,%f) (%f,%f)\n", coords.crval1, coords.crval2, fitAve.Ro, fitAve.Do, dXoff, dYoff);
+    }
+    fitStats->Noffset ++;
+    return FALSE;
+  }
+
+  // set the stack position values
+  average[0].Rstk  = fitAve.Ro; // RA in degrees
+  average[0].Dstk  = fitAve.Do; // DEC in degrees
+  average[0].dRstk = fitAve.dRo; // RA scatter in arcsec
+  average[0].dDstk = fitAve.dDo; // DEC scatter in arcsec
+
+  return (TRUE);
+}
+
+
 
 /* fitting proper-motion and parallax:
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/args.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/args.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/args.c	(revision 37403)
@@ -179,8 +179,18 @@
   FlagOutlier = FALSE;
   if ((N = get_argument (argc, argv, "-clip"))) {
+    fprintf (stderr, "-clip is currently disabled\n");
     remove_argument (N, &argc, argv);
     CLIP_THRESH = atof (argv[N]);
     remove_argument (N, &argc, argv);
     FlagOutlier = TRUE;
+  }
+
+  ExcludeBogus = FALSE;
+  ExcludeBogusRadius = 0.0;
+  if ((N = get_argument (argc, argv, "-exclude-bogus"))) {
+    remove_argument (N, &argc, argv);
+    ExcludeBogusRadius = atof (argv[N]);
+    remove_argument (N, &argc, argv);
+    ExcludeBogus = TRUE;
   }
 
@@ -284,4 +294,33 @@
   }
 
+  // eg g - r or r - i
+  DCR_BLUE_COLOR_POS = NULL;
+  DCR_BLUE_COLOR_NEG = NULL;
+  if ((N = get_argument (argc, argv, "-dcr-blue-color"))) {
+    remove_argument (N, &argc, argv);
+    DCR_BLUE_COLOR_POS = strcreate(argv[N]);
+    remove_argument (N, &argc, argv);
+    DCR_BLUE_COLOR_NEG = strcreate(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  // eg, z - y or i - z
+  DCR_RED_COLOR_POS = NULL;
+  DCR_RED_COLOR_NEG = NULL;
+  if ((N = get_argument (argc, argv, "-dcr-red-color"))) {
+    remove_argument (N, &argc, argv);
+    DCR_RED_COLOR_POS = strcreate(argv[N]);
+    remove_argument (N, &argc, argv);
+    DCR_RED_COLOR_NEG = strcreate(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  PHOTCODE_RESET_LIST = NULL;
+  if ((N = get_argument (argc, argv, "-reset-to-photcode"))) {
+    remove_argument (N, &argc, argv);
+    PHOTCODE_RESET_LIST = strcreate(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
   PHOTCODE_KEEP_LIST = NULL;
   if ((N = get_argument (argc, argv, "+photcode"))) {
@@ -291,19 +330,21 @@
   }
 
-  PHOTCODE_SKIP_LIST = strcreate("SCOS.103a.E,SCOS.4414.OG590,SCOS.4415.OG590,SCOS.IIIaF.OG590,SCOS.IIIaF.RG610,SCOS.IIIaF.RG630,SCOS.IIIaJ.GG385,SCOS.IIIaJ.GG395,SCOS.IVN.RG715,SCOS.IVN.RG9");
+  char *SuperCOSMOS_SKIP = strcreate("SCOS.103a.E,SCOS.4414.OG590,SCOS.4415.OG590,SCOS.IIIaF.OG590,SCOS.IIIaF.RG610,SCOS.IIIaF.RG630,SCOS.IIIaJ.GG385,SCOS.IIIaJ.GG395,SCOS.IVN.RG715,SCOS.IVN.RG9");
+
+  PHOTCODE_SKIP_LIST = NULL;
   if ((N = get_argument (argc, argv, "-photcode"))) {
     remove_argument (N, &argc, argv);
-    char *tmp1 = strcreate(argv[N]);
-
-    int Ntotal = strlen(tmp1) + strlen(PHOTCODE_SKIP_LIST) + 5;
-
-    char *tmp2 = NULL;
-    ALLOCATE (tmp2, char, Ntotal);
-    snprintf (tmp2, Ntotal, "%s,%s", PHOTCODE_SKIP_LIST, tmp1);
-
-    free (tmp1);
-    free (PHOTCODE_SKIP_LIST);
-
-    PHOTCODE_SKIP_LIST = tmp2;
+    char *RawSkip = strcreate(argv[N]);
+
+    char *GotSkip = strstr (RawSkip, SuperCOSMOS_SKIP);
+    if (!GotSkip) {
+      int Ntotal = strlen(RawSkip) + strlen(SuperCOSMOS_SKIP) + 5;
+      ALLOCATE (PHOTCODE_SKIP_LIST, char, Ntotal);
+      snprintf (PHOTCODE_SKIP_LIST, Ntotal, "%s,%s", SuperCOSMOS_SKIP, RawSkip);
+      free (RawSkip);
+      free (SuperCOSMOS_SKIP);
+    } else {
+      PHOTCODE_SKIP_LIST = RawSkip;
+    }
     remove_argument (N, &argc, argv);
   }
@@ -582,8 +623,18 @@
   FlagOutlier = FALSE;
   if ((N = get_argument (argc, argv, "-clip"))) {
+    fprintf (stderr, "-clip is currently disabled\n");
     remove_argument (N, &argc, argv);
     CLIP_THRESH = atof (argv[N]);
     remove_argument (N, &argc, argv);
     FlagOutlier = TRUE;
+  }
+
+  ExcludeBogus = FALSE;
+  ExcludeBogusRadius = 0.0;
+  if ((N = get_argument (argc, argv, "-exclude-bogus"))) {
+    remove_argument (N, &argc, argv);
+    ExcludeBogusRadius = atof (argv[N]);
+    remove_argument (N, &argc, argv);
+    ExcludeBogus = TRUE;
   }
 
@@ -655,4 +706,30 @@
     remove_argument (N, &argc, argv);
     TimeSelect = TRUE;
+  }
+
+  DCR_BLUE_COLOR_POS = NULL;
+  DCR_BLUE_COLOR_NEG = NULL;
+  if ((N = get_argument (argc, argv, "-dcr-blue-color"))) {
+    remove_argument (N, &argc, argv);
+    DCR_BLUE_COLOR_POS = strcreate(argv[N]);
+    remove_argument (N, &argc, argv);
+    DCR_BLUE_COLOR_NEG = strcreate(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+  DCR_RED_COLOR_POS = NULL;
+  DCR_RED_COLOR_NEG = NULL;
+  if ((N = get_argument (argc, argv, "-dcr-red-color"))) {
+    remove_argument (N, &argc, argv);
+    DCR_RED_COLOR_POS = strcreate(argv[N]);
+    remove_argument (N, &argc, argv);
+    DCR_RED_COLOR_NEG = strcreate(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  PHOTCODE_RESET_LIST = NULL;
+  if ((N = get_argument (argc, argv, "-reset-to-photcode"))) {
+    remove_argument (N, &argc, argv);
+    PHOTCODE_RESET_LIST = strcreate(argv[N]);
+    remove_argument (N, &argc, argv);
   }
 
@@ -861,2 +938,15 @@
   exit (2);
 }
+
+int strextend (char *input, char *format,...) {
+
+  char tmpextra[1024], tmpline[1024];
+  va_list argp;
+
+  va_start (argp, format);
+  vsnprintf (tmpextra, 1024, format, argp);
+  snprintf (tmpline, 1024, "%s %s", input, tmpextra);
+  strcpy (input, tmpline);
+
+  return TRUE;
+}
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/bcatalog.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/bcatalog.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/bcatalog.c	(revision 37403)
@@ -1,8 +1,21 @@
 # include "relastro.h"
 
+static int Nkeep1 = 0;
+static int Nkeep2 = 0;
 static int Nskip1 = 0;
 static int Nskip2 = 0;
-static unsigned int Tref = 1323353985;
-static short Cref = 10355;
+
+FILE *fbogus = NULL;
+static int NskipBogus = 0;
+
+// test image: 2013/06/15,13:25:51, GPC1.r.XY50
+static int CHECK_TEST_IMAGE = FALSE;
+// static unsigned int Tref = 1378812312; 
+// static short Cref = 10001;
+
+static unsigned int Tref = 1379570672;
+static short Cref = 10341;
+
+int LimitDensityCatalog_ByNmeasureGrid (Catalog *subcatalog, Catalog *oldcatalog);
 
 int bcatalog (Catalog *subcatalog, Catalog *catalog) {
@@ -11,4 +24,16 @@
   off_t NAVERAGE, NMEASURE, Naverage, Nmeasure, Nm;
   int Nsecfilt;
+  Coords coords;
+
+  /* for outlier rejection, project coordinates to a plane centered on the object with units of arcsec */
+  coords.crval1 = 0;
+  coords.crval2 = 0;
+  coords.crpix1 = 0;
+  coords.crpix2 = 0;
+  coords.cdelt1 = coords.cdelt2 = 1.0 / 3600.0;
+  coords.pc1_1  = coords.pc2_2 = 1.0;
+  coords.pc1_2  = coords.pc2_1 = 0.0;
+  coords.Npolyterms = 1;
+  strcpy (coords.ctype, "DEC--SIN");
 
   // XXX in the future, use catalog[0].Nsecfilt only?  allow catalogs to have variable Nsecfilt?
@@ -34,4 +59,13 @@
     ID_STAR_NO_ASTROM ; 
 
+  if (VERBOSE2 && ExcludeBogus && (fbogus == NULL)) {
+    char name[1024];
+    snprintf (name, 1024, "%s/bogus.%02d.dat", CATDIR, HOST_ID);
+    fbogus = fopen (name, "w");
+    if (!fbogus) {
+      fprintf (stderr, "trouble opening bogus detection dump : %s\n", name);
+    }
+  }
+
   /* exclude stars not in range or with too few measurements */
   for (i = 0; i < catalog[0].Naverage; i++) {
@@ -60,12 +94,16 @@
       if (!MeasFilterTest(&catalog[0].measure[offset], TRUE)) {
 	catalog[0].measure[offset].dbFlags &= ~ID_MEAS_USED_CHIP;
-	if (FALSE && (abs(catalog[0].measure[offset].t - Tref) < 10) && (catalog[0].measure[offset].photcode == Cref)) {
+	if (CHECK_TEST_IMAGE && (abs(catalog[0].measure[offset].t - Tref) < 10) && (catalog[0].measure[offset].photcode == Cref)) {
 	  Nskip1 ++;
 	}
 	continue;
       }
-
-      // filter out outliers
-      if (FlagOutlier && (catalog[0].measure[offset].dbFlags & ID_MEAS_POOR_ASTROM)) {
+      if (CHECK_TEST_IMAGE && (abs(catalog[0].measure[offset].t - Tref) < 10) && (catalog[0].measure[offset].photcode == Cref)) {
+	Nkeep1 ++;
+      }
+
+      // filter out outliers - these are detections inconsistent with the offset distribution
+      // XXX disable this for now
+      if (FALSE && FlagOutlier && (catalog[0].measure[offset].dbFlags & ID_MEAS_POOR_ASTROM)) {
 	catalog[0].measure[offset].dbFlags &= ~ID_MEAS_USED_CHIP;
 	if (FALSE && (abs(catalog[0].measure[offset].t - Tref) < 10) && (catalog[0].measure[offset].photcode == Cref)) {
@@ -76,4 +114,25 @@
       catalog[0].measure[offset].dbFlags |= ID_MEAS_USED_CHIP;
 
+      // exclude bogus 
+      if (ExcludeBogus) {
+	  double Ri = getMeanR_Big (&catalog[0].measure[offset], &catalog[0].average[i], &catalog[0].secfilt[i*Nsecfilt]);
+	  double Di = getMeanD_Big (&catalog[0].measure[offset], &catalog[0].average[i], &catalog[0].secfilt[i*Nsecfilt]);
+	  coords.crval1 = catalog[0].average[i].R;
+	  coords.crval2 = catalog[0].average[i].D;
+	  double Xi, Yi;
+	  RD_to_XY (&Xi, &Yi, Ri, Di, &coords);
+	  double radius = hypot(Xi, Yi);
+	  if (radius > ExcludeBogusRadius) {
+	      NskipBogus ++;
+	      if (VERBOSE2) {
+		FILE *foutput = fbogus ? fbogus : stderr;
+		char *date = ohana_sec_to_date(catalog[0].measure[offset].t);
+		fprintf (foutput, "exclude bogus: %10.6f %10.6f : %10.6f %10.6f : %6.2f %6.2f : %6.2f : %5d %s\n", catalog[0].average[i].R, catalog[0].average[i].D, Ri, Di, Xi, Yi, radius, catalog[0].measure[offset].photcode, date);
+		free (date);
+	      }
+	      continue;
+	  }
+      }
+
       // re-assess on each run of relastro if a measurement should be used
 
@@ -87,4 +146,8 @@
       // but before the final average properties are calculated, these measurements may be
       // allowed.
+
+      if (CHECK_TEST_IMAGE && (abs(catalog[0].measure[offset].t - Tref) < 10) && (catalog[0].measure[offset].photcode == Cref)) {
+	Nkeep2 ++;
+      }
 
       CopyMeasureToTiny (&subcatalog[0].measureT[Nmeasure], &catalog[0].measure[offset]);
@@ -125,5 +188,5 @@
   // limit the total number of stars in the catalog
   if (MaxDensityUse) {
-    LimitDensityCatalog_ByNmeasure (subcatalog, catalog);
+    LimitDensityCatalog_ByNmeasureGrid (subcatalog, catalog);
   } else {
     if (VERBOSE2) {
@@ -134,9 +197,18 @@
     }
   }
+  if (CHECK_TEST_IMAGE && (Nkeep1 + Nkeep2 + Nskip1 + Nskip2 > 0)) {
+    fprintf (stderr, "kept %d %d, skipped %d %d\n", Nkeep1, Nkeep2, Nskip1, Nskip2);
+  }
+
   return (TRUE);
 }
 
 void bcatalog_show_skips () {
-  fprintf (stderr, "Nskip: %d, %d\n", Nskip1, Nskip2);
+  if (ExcludeBogus) {
+    if (fbogus) fclose (fbogus);
+    fprintf (stderr, "NskipBogus: %d\n", NskipBogus);
+    // fprintf (stderr, "Nskip: %d, %d\n", Nskip1, Nskip2);
+    // fprintf (stderr, "Nkeep: %d, %d\n", Nkeep1, Nkeep2);
+  }
 }
 
@@ -155,4 +227,270 @@
 # undef COMPARE
 
+}
+
+/* generate a grid in a locally-projected coordinate system, try to select average entries 
+   from each grid cell in decending Nmeasure order.
+ */ 
+int LimitDensityCatalog_ByNmeasureGrid (Catalog *subcatalog, Catalog *oldcatalog) {
+
+  off_t i, j;
+  int ix, iy;
+
+  Catalog tmpcatalog;
+
+  double Rmin, Rmax, Dmin, Dmax;
+
+  int Nsecfilt = GetPhotcodeNsecfilt ();
+
+  gfits_scan (&oldcatalog[0].header, "RA0",  "%lf", 1, &Rmin);
+  gfits_scan (&oldcatalog[0].header, "DEC0", "%lf", 1, &Dmin);
+  gfits_scan (&oldcatalog[0].header, "RA1",  "%lf", 1, &Rmax);
+  gfits_scan (&oldcatalog[0].header, "DEC1", "%lf", 1, &Dmax);
+
+  if (VERBOSE2) fprintf (stderr, "extracting from catalog covering region %f,%f to %f,%f\n", Rmin, Dmin, Rmax, Dmax);
+
+  float AREA = fabs(Dmax - Dmin) * fabs(Rmax - Rmin) * cos (0.5*RAD_DEG*(Dmax + Dmin));
+  assert (AREA > 0);
+
+  off_t Nmax = MaxDensityValue * AREA;
+  if (subcatalog[0].Naverage <= Nmax) {
+    if (VERBOSE) {
+      fprintf (stderr, "subcatalog has less than the max density\n");
+    }
+    return (TRUE);
+  }
+
+  off_t Naverage = subcatalog[0].Naverage;
+
+  // generate a grid in locally projected space
+  double Rc = 0.5*(Rmin + Rmax);
+  double Dc = 0.5*(Dmin + Dmax);
+
+  /* project coordinates to a plane centered on the object with units of arcsec */
+  Coords coords;
+  coords.crval1 = Rc;
+  coords.crval2 = Dc;
+  coords.crpix1 = 0;
+  coords.crpix2 = 0;
+  coords.cdelt1 = coords.cdelt2 = 1.0 / 3600.0;
+  coords.pc1_1  = coords.pc2_2 = 1.0;
+  coords.pc1_2  = coords.pc2_1 = 0.0;
+  coords.Npolyterms = 1;
+  strcpy (coords.ctype, "DEC--SIN");
+
+  // convert all average R,D values to X,Y:
+  double *X, *Y;
+  ALLOCATE (X, double, Naverage);
+  ALLOCATE (Y, double, Naverage);
+  float Xmin = +10000.0, Ymin = +10000.0;
+  float Xmax = -10000.0, Ymax = -10000.0;
+  for (i = 0; i < Naverage; i++) {
+    X[i] = NAN;
+    Y[i] = NAN;
+    // skip any stars which are outside of nominal catalog range
+    if (subcatalog[0].average[i].R < Rmin) continue;
+    if (subcatalog[0].average[i].R > Rmax) continue;
+    if (subcatalog[0].average[i].D < Dmin) continue;
+    if (subcatalog[0].average[i].D > Dmax) continue;
+    RD_to_XY (&X[i], &Y[i], subcatalog[0].average[i].R, subcatalog[0].average[i].D, &coords);
+    Xmin = MIN (Xmin, X[i]);
+    Xmax = MAX (Xmax, X[i]);
+    Ymin = MIN (Ymin, Y[i]);
+    Ymax = MAX (Ymax, Y[i]);
+  }
+
+  // how many grid cells? what is the grid spacing? 
+  float dX = Xmax - Xmin;
+  float dY = Ymax - Ymin;
+
+  // *** XXX for the moment, I'm using a hard-wired cell size (200 arcsec ~ 3.3 arcmin)
+  int NX = (int)(dX / 200) + 1;
+  int NY = (int)(dY / 200) + 1;
+  // fprintf (stderr, "Density Grid: %d x %d\n", NX, NY);
+  // XXX check that NX,NY are sensible (5 degrees / 200 arcsec seems like the absolute max)
+  if (NX > 1000) { 
+    fprintf (stderr, "serious problem with %s: NX = %d\n", subcatalog[0].filename, NX); 
+    exit (3); 
+  }
+  if (NY > 1000) { 
+    fprintf (stderr, "serious problem with %s: NY = %d\n", subcatalog[0].filename, NY); 
+    exit (3); 
+  }
+  
+  // kind of ugly : generate a grid of index, Nmeasure arrays
+  // to be filled below (I also need NN and Nn to track the number of 
+  // entries in each).
+  int    **NN_grid;
+  int    **Nn_grid;
+  int   ***Nm_grid;
+  off_t ***idxgrid;
+  ALLOCATE (NN_grid, int *, NX);
+  ALLOCATE (Nn_grid, int *, NX);
+  ALLOCATE (Nm_grid, int **, NX);
+  ALLOCATE (idxgrid, off_t **, NX);
+
+  for (ix = 0; ix < NX; ix++) {
+    ALLOCATE (NN_grid[ix], int, NY);
+    ALLOCATE (Nn_grid[ix], int, NY);
+    ALLOCATE (Nm_grid[ix], int *, NY);
+    ALLOCATE (idxgrid[ix], off_t *, NY);
+    for (iy = 0; iy < NY; iy++) {
+      Nn_grid[ix][iy] = 0;
+      NN_grid[ix][iy] = 100;
+      ALLOCATE (Nm_grid[ix][iy], int,   NN_grid[ix][iy]);
+      ALLOCATE (idxgrid[ix][iy], off_t, NN_grid[ix][iy]);
+    }
+  }
+
+  // assign all of the average entries to a grid cell
+  for (i = 0; i < Naverage; i++) {
+    if (isnan(X[i])) continue;
+    if (isnan(Y[i])) continue;
+    ix = (X[i] - Xmin) / 200.0;
+    iy = (Y[i] - Ymin) / 200.0;
+    int Nn = Nn_grid[ix][iy];
+    Nm_grid[ix][iy][Nn] = subcatalog[0].average[i].Nmeasure;
+    
+    // if we are resetting to a given photcode, we need to have that photcode...
+    if (NphotcodesReset) {
+      int k;
+      int foundReset = FALSE;
+      int m = subcatalog[0].average[i].measureOffset;
+      MeasureTiny *measure = &subcatalog[0].measureT[m];
+      for (j = 0; (j < subcatalog[0].average[i].Nmeasure) && !foundReset; j++) {
+	if (CHECK_TEST_IMAGE && (abs(measure[j].t - Tref) < 10) && (measure[j].photcode == Cref)) {
+	  fprintf (stderr, ".");
+	}
+	for (k = 0; (k < NphotcodesReset) && !foundReset; k++) {
+	  if (photcodesReset[k][0].code == measure[j].photcode) foundReset = TRUE;
+	}
+      }
+      if (!foundReset) {
+	Nm_grid[ix][iy][Nn] = 0;
+      }
+    }
+
+    idxgrid[ix][iy][Nn] = i;
+    Nn_grid[ix][iy] ++;
+    if (Nn_grid[ix][iy] >= NN_grid[ix][iy]) {
+      NN_grid[ix][iy] += 100;
+      REALLOCATE (Nm_grid[ix][iy], int,   NN_grid[ix][iy]);
+      REALLOCATE (idxgrid[ix][iy], off_t, NN_grid[ix][iy]);
+    }
+  }
+    
+  // sort all of the grid cells
+  for (ix = 0; ix < NX; ix++) {
+    for (iy = 0; iy < NY; iy++) {
+      sort_by_Nmeasure (Nm_grid[ix][iy], idxgrid[ix][iy], Nn_grid[ix][iy]);
+      NN_grid[ix][iy] = 0; // I'm going to use this array to track which element I've already selected
+    }
+  }
+
+  // cycle over the grid until we ready Nmax
+  off_t *keepidx = NULL;
+  ALLOCATE (keepidx, off_t, Naverage);
+  memset (keepidx, 0, Naverage*sizeof(off_t));
+  int Nkeep = 0;
+
+  for (i = 0; (i < 20) && (Nkeep < Nmax); i++) {
+    for (ix = 0; (ix < NX) && (Nkeep < Nmax); ix++) {
+      for (iy = 0; (iy < NY) && (Nkeep < Nmax); iy++) {
+	if (NN_grid[ix][iy] >= Nn_grid[ix][iy]) continue; // all used up!
+	int Nn = NN_grid[ix][iy];
+	keepidx[Nkeep] = idxgrid[ix][iy][Nn];
+	Nkeep ++;
+	NN_grid[ix][iy] ++;
+      }
+    }
+  }
+
+  // count the number of measurements this selection will yield
+  off_t ave, NMEASURE = 0;
+  for (i = 0; i < Nkeep; i++) {
+    ave = keepidx[i];
+    NMEASURE += subcatalog[0].average[ave].Nmeasure;
+  }
+
+  // test catID : 37262 37261 37257 37258
+  int dumpit = FALSE;
+  dumpit |= (oldcatalog[0].catID == 37007);
+  // dumpit |= (oldcatalog[0].catID == 37261);
+  // dumpit |= (oldcatalog[0].catID == 37257);
+  // dumpit |= (oldcatalog[0].catID == 37258);
+  if (dumpit) {
+    char name[64];
+    snprintf (name, 64, "cat.%05d.dump.dat", oldcatalog[0].catID);
+    FILE *fdump = fopen (name, "w");
+    for (i = 0; i < Nkeep; i++) {
+      ave = keepidx[i];
+      fprintf (fdump, "%10.6f %10.6f %d\n", subcatalog[0].average[ave].R, subcatalog[0].average[ave].D, subcatalog[0].average[ave].Nmeasure);
+    }
+    fclose (fdump);
+  }
+
+  // allocate the output data 
+  ALLOCATE (tmpcatalog.average,  Average,     Nkeep);
+  ALLOCATE (tmpcatalog.measureT, MeasureTiny, NMEASURE);
+  ALLOCATE (tmpcatalog.secfilt,  SecFilt,     Nkeep * Nsecfilt);
+
+  off_t Nmeasure = 0;
+
+  // copy the Nkeep selected entries from subcatalog to tmpcatalog (adjusting links)
+  for (i = 0; i < Nkeep; i++) {
+    ave = keepidx[i];
+    tmpcatalog.average[i] = subcatalog[0].average[ave];
+    tmpcatalog.average[i].measureOffset = Nmeasure;
+    for (j = 0; j < tmpcatalog.average[i].Nmeasure; j++) {
+      off_t offset = subcatalog[0].average[ave].measureOffset + j;
+      tmpcatalog.measureT[Nmeasure] = subcatalog[0].measureT[offset];
+      tmpcatalog.measureT[Nmeasure].averef = i;
+      Nmeasure ++;
+    }
+    for (j = 0; j < Nsecfilt; j++) {
+      tmpcatalog.secfilt[i*Nsecfilt + j] = subcatalog[0].secfilt[ave*Nsecfilt + j];
+    }
+  }
+
+  if (VERBOSE2) {
+    char *basename = filebasename (oldcatalog[0].filename);
+    fprintf (stderr, "limited to %d ("OFF_T_FMT" subset, "OFF_T_FMT" total) stars, "OFF_T_FMT" ("OFF_T_FMT" subset, "OFF_T_FMT" total) measures for catalog %s\n", 
+	     Nkeep, subcatalog[0].Naverage, oldcatalog[0].Naverage, Nmeasure, subcatalog[0].Nmeasure,  oldcatalog[0].Nmeasure, basename);
+    free (basename);
+  }
+
+  free (X);
+  free (Y);
+
+  for (ix = 0; ix < NX; ix++) {
+    for (iy = 0; iy < NY; iy++) {
+      free (Nm_grid[ix][iy]);
+      free (idxgrid[ix][iy]);
+    }
+    free (NN_grid[ix]);
+    free (Nn_grid[ix]);
+    free (Nm_grid[ix]);
+    free (idxgrid[ix]);
+  }
+  free (NN_grid);
+  free (Nn_grid);
+  free (Nm_grid);
+  free (idxgrid);
+
+  free (keepidx);
+
+  free (subcatalog[0].average);
+  free (subcatalog[0].measureT);
+  free (subcatalog[0].secfilt);
+
+  subcatalog[0].average = tmpcatalog.average;
+  subcatalog[0].measureT = tmpcatalog.measureT;
+  subcatalog[0].secfilt = tmpcatalog.secfilt;
+  subcatalog[0].Naverage = Nkeep;
+  subcatalog[0].Nmeasure = Nmeasure;
+  subcatalog[0].Nsecfilt = oldcatalog[0].Nsecfilt;
+  subcatalog[0].Nsecf_mem = Naverage * oldcatalog[0].Nsecfilt;
+
+  return (TRUE);
 }
 
@@ -205,4 +543,15 @@
     NMEASURE += subcatalog[0].average[ave].Nmeasure;
   }
+
+# if (0)
+  if (oldcatalog[0].catID == 59962) {
+    FILE *fdump = fopen ("cat.dump.dat", "w");
+    for (i = 0; i < Nmax; i++) {
+      ave = index[i];
+      fprintf (fdump, "%10.6f %10.6f %d\n", subcatalog[0].average[ave].R, subcatalog[0].average[ave].D, subcatalog[0].average[ave].Nmeasure);
+    }
+    fclose (fdump);
+  }
+# endif
 
   // allocate the output data 
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/dvo_astrom_ops.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/dvo_astrom_ops.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/dvo_astrom_ops.c	(revision 37403)
@@ -1,3 +1,4 @@
 # include "relastro.h"
+/* the Measure carries the instantaneous mean position at the epoch t */ 
 
 double getMeanR (MeasureTiny *measure, Average *average, SecFilt *secfilt) {
@@ -5,6 +6,79 @@
   double ra;
 
-  /* the measure carries the instantaneous mean position at the epoch t */ 
-  ra = average[0].R - measure[0].dR / 3600.0;
+  // old: ra = average[0].R - measure[0].dR / 3600.0;
+  if (!measure) return NAN;
+  ra = measure[0].R;
+
+  return (ra);
+}
+
+double getMeanD (MeasureTiny *measure, Average *average, SecFilt *secfilt) {
+
+  double dec;
+
+  // old: dec = average[0].D - measure[0].dD / 3600.0;
+  if (!measure) return NAN;
+  dec = measure[0].D;
+
+  return (dec);
+}
+
+int setMeanR (double ra_fit, MeasureTiny *measure, Average *average, SecFilt *secfilt) {
+
+  // old: measure[0].dR += (ra_fit - average[0].R) * 3600.0;
+  if (!measure) return FALSE;
+  measure[0].R = ra_fit;
+
+  return (TRUE);
+}
+
+int setMeanD (double dec_fit, MeasureTiny *measure, Average *average, SecFilt *secfilt) {
+
+  // old: measure[0].dD += (dec_fit - average[0].D) * 3600.0;
+  if (!measure) return FALSE;
+  measure[0].D = dec_fit;
+
+  return (TRUE);
+}
+
+double getMeanR_Big (Measure *measure, Average *average, SecFilt *secfilt) {
+
+  double ra;
+
+  // old: ra = average[0].R - measure[0].dR / 3600.0;
+  if (!measure) return NAN;
+  ra = measure[0].R;
+
+  return (ra);
+}
+
+double getMeanD_Big (Measure *measure, Average *average, SecFilt *secfilt) {
+
+  double dec;
+
+  // old: dec = average[0].D - measure[0].dD / 3600.0;
+  if (!measure) return NAN;
+  dec = measure[0].D;
+
+  return (dec);
+}
+
+int setMeanR_Big (double ra_fit, Measure *measure, Average *average, SecFilt *secfilt) {
+
+  // old: measure[0].dR += (ra_fit - average[0].R) * 3600.0;
+  if (!measure) return TRUE;
+  measure[0].R = ra_fit;
+
+  return (TRUE);
+}
+
+int setMeanD_Big (double dec_fit, Measure *measure, Average *average, SecFilt *secfilt) {
+
+  // measure[0].dD += (dec_fit - average[0].D) * 3600.0;
+  if (!measure) return TRUE;
+  measure[0].D = dec_fit;
+
+  return (TRUE);
+}
 
   /* possible corrections to mean ra:
@@ -18,128 +92,2 @@
   */
 
-  return (ra);
-}
-
-double getMeanD (MeasureTiny *measure, Average *average, SecFilt *secfilt) {
-
-  double dec;
-
-  /* the measure carries the instantaneous mean position at the epoch t */ 
-  dec = average[0].D - measure[0].dD / 3600.0;
-
-  /* possible corrections to mean ra:
-
-  - proper-motion and parallax
-  - abberation
-  - precession and nutation, etc
-  - refraction
-  - DCR
-
-  */
-
-  return (dec);
-}
-
-int setMeanR (double ra_fit, MeasureTiny *measure, Average *average, SecFilt *secfilt) {
-
-  /* math to get from new fitted position to new measure offset
-     ra_obs = average[0].R - measure[0].dR / 3600.0;
-     measure[0].dR = (ra_fit - ra_obs) * 3600.0;
-     measure[0].dR = (ra_fit - average[0].R + measure[0].dR/3600) * 3600.0
-     measure[0].dR = (ra_fit - average[0].R) * 3600.0 + measure[0].dR;
-  */
-
-  /* the measure carries the instantaneous mean position at the epoch t */ 
-  measure[0].dR += (ra_fit - average[0].R) * 3600.0;
-
-  /* possible corrections to mean ra:
-
-  - proper-motion and parallax
-  - abberation
-  - precession and nutation, etc
-  - refraction
-  - DCR
-
-  */
-
-  return (TRUE);
-}
-
-int setMeanD (double dec_fit, MeasureTiny *measure, Average *average, SecFilt *secfilt) {
-
-  /* math to get from new fitted position to new measure offset
-     dec_obs = average[0].D - measure[0].dD / 3600.0;
-     measure[0].dD = (dec_fit - dec_obs) * 3600.0;
-     measure[0].dD = (dec_fit - average[0].D + measure[0].dD/3600) * 3600.0
-     measure[0].dD = (dec_fit - average[0].D) * 3600.0 + measure[0].dD;
-  */
-
-  /* the measure carries the instantaneous mean position at the epoch t */ 
-  measure[0].dD += (dec_fit - average[0].D) * 3600.0;
-
-  /* possible corrections to mean ra:
-
-  - proper-motion and parallax
-  - abberation
-  - precession and nutation, etc
-  - refraction
-  - DCR
-
-  */
-
-  return (TRUE);
-}
-
-int setMeanR_Big (double ra_fit, Measure *measure, Average *average, SecFilt *secfilt) {
-
-  if (!measure) return TRUE;
-
-  /* math to get from new fitted position to new measure offset
-     ra_obs = average[0].R - measure[0].dR / 3600.0;
-     measure[0].dR = (ra_fit - ra_obs) * 3600.0;
-     measure[0].dR = (ra_fit - average[0].R + measure[0].dR/3600) * 3600.0
-     measure[0].dR = (ra_fit - average[0].R) * 3600.0 + measure[0].dR;
-  */
-
-  /* the measure carries the instantaneous mean position at the epoch t */ 
-  measure[0].dR += (ra_fit - average[0].R) * 3600.0;
-
-  /* possible corrections to mean ra:
-
-  - proper-motion and parallax
-  - abberation
-  - precession and nutation, etc
-  - refraction
-  - DCR
-
-  */
-
-  return (TRUE);
-}
-
-int setMeanD_Big (double dec_fit, Measure *measure, Average *average, SecFilt *secfilt) {
-
-  if (!measure) return TRUE;
-
-  /* math to get from new fitted position to new measure offset
-     dec_obs = average[0].D - measure[0].dD / 3600.0;
-     measure[0].dD = (dec_fit - dec_obs) * 3600.0;
-     measure[0].dD = (dec_fit - average[0].D + measure[0].dD/3600) * 3600.0
-     measure[0].dD = (dec_fit - average[0].D) * 3600.0 + measure[0].dD;
-  */
-
-  /* the measure carries the instantaneous mean position at the epoch t */ 
-  measure[0].dD += (dec_fit - average[0].D) * 3600.0;
-
-  /* possible corrections to mean ra:
-
-  - proper-motion and parallax
-  - abberation
-  - precession and nutation, etc
-  - refraction
-  - DCR
-
-  */
-
-  return (TRUE);
-}
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/extra.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/extra.c	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/extra.c	(revision 37403)
@@ -0,0 +1,40 @@
+# include "relastro.h"
+
+// for now (20140710) I need to identify gpc1 chips explicitly.  generalize in the future
+int isGPC1chip (int photcode) {
+
+  if ((photcode > 10000) && (photcode < 10077)) return TRUE; // g-band
+  if ((photcode > 10100) && (photcode < 10177)) return TRUE; // r-band
+  if ((photcode > 10200) && (photcode < 10277)) return TRUE; // i-band
+  if ((photcode > 10300) && (photcode < 10377)) return TRUE; // z-band
+  if ((photcode > 10400) && (photcode < 10477)) return TRUE; // y-band
+  if ((photcode > 10500) && (photcode < 10577)) return TRUE; // w-band
+
+  return FALSE;
+}
+
+// for now (20140710) I need to identify gpc1 stacks explicitly.  generalize in the future
+int isGPC1stack (int photcode) {
+
+  if (photcode == 11000) return TRUE; // g-band
+  if (photcode == 11100) return TRUE; // r-band
+  if (photcode == 11200) return TRUE; // i-band
+  if (photcode == 11300) return TRUE; // z-band
+  if (photcode == 11400) return TRUE; // y-band
+  if (photcode == 11500) return TRUE; // w-band
+
+  return FALSE;
+}
+
+// for now (20140710) I need to identify gpc1 stacks explicitly.  generalize in the future
+int isGPC1warp (int photcode) {
+
+  if (photcode == 12000) return TRUE; // g-band
+  if (photcode == 12100) return TRUE; // r-band
+  if (photcode == 12200) return TRUE; // i-band
+  if (photcode == 12300) return TRUE; // z-band
+  if (photcode == 12400) return TRUE; // y-band
+  if (photcode == 12500) return TRUE; // w-band
+
+  return FALSE;
+}
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/high_speed_objects.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/high_speed_objects.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/high_speed_objects.c	(revision 37403)
@@ -241,7 +241,7 @@
 	  for(i1=0;i1<catalog[0].average[nv[l]].Nmeasure;i1++) {
 	      catalogOut.measure[Nmatchmeas]=catalog[0].measure[m+i1];
-	      /*Set offset RA and Dec wrt correct average value*/
-	      catalogOut.measure[Nmatchmeas].dR=catalog[0].measure[m+i1].dR+3600.0*(catalog[0].average[nv[0]].R-catalog[0].average[nv[l]].R);
-	      catalogOut.measure[Nmatchmeas].dD=catalog[0].measure[m+i1].dD+3600.0*(catalog[0].average[nv[0]].D-catalog[0].average[nv[l]].D);
+	      // DROP no longer necessary to repoint R,D
+	      // catalogOut.measure[Nmatchmeas].dR=catalog[0].measure[m+i1].dR+3600.0*(catalog[0].average[nv[0]].R-catalog[0].average[nv[l]].R);
+	      // catalogOut.measure[Nmatchmeas].dD=catalog[0].measure[m+i1].dD+3600.0*(catalog[0].average[nv[0]].D-catalog[0].average[nv[l]].D);
 	      catalogOut.measure[Nmatchmeas].averef = Nmatch;
 	      Nmatchmeasobj++;
@@ -297,7 +297,7 @@
   // XXX require a set or not?  assert (Nset > 0);
 
-  if (!finite(measure[0].dR)) return FALSE;
-  if (!finite(measure[0].dD)) return FALSE;
-  if (!finite(measure[0].M))  return FALSE;
+  if (!finite(measure[0].R)) return FALSE;
+  if (!finite(measure[0].D)) return FALSE;
+  if (!finite(measure[0].M)) return FALSE;
   
   float dX = GetAstromError (measure, ERROR_MODE_RA);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/hpm_objects.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/hpm_objects.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/hpm_objects.c	(revision 37403)
@@ -240,7 +240,7 @@
       for (k = 0; k < catalog[0].average[nj].Nmeasure; k++) {
 	testcat.measure[Nmatchmeas] = catalog[0].measure[m+k];
-	/* Set offset RA and Dec wrt correct average value*/
-	testcat.measure[Nmatchmeas].dR = catalog[0].measure[m+k].dR + 3600.0*(catalog[0].average[ni].R - catalog[0].average[nj].R);
-	testcat.measure[Nmatchmeas].dD = catalog[0].measure[m+k].dD + 3600.0*(catalog[0].average[ni].D - catalog[0].average[nj].D);
+	// DROP: was needed when dR,dD were relative to average.R,D
+	// testcat.measure[Nmatchmeas].R = catalog[0].measure[m+k].R;
+	// testcat.measure[Nmatchmeas].D = catalog[0].measure[m+k].D;
 	testcat.measure[Nmatchmeas].averef = 0;
 	Nmatchmeas++;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/initialize.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/initialize.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/initialize.c	(revision 37403)
@@ -8,13 +8,56 @@
   if (RELASTRO_OP == OP_MERGE_SOURCE) return;
 
-  fprintf (stderr, "PHOTCODE_KEEP_LIST: %s\n", PHOTCODE_KEEP_LIST);
-  fprintf (stderr, "PHOTCODE_SKIP_LIST: %s\n", PHOTCODE_SKIP_LIST);
-  fprintf (stderr, "PHOTCODE_A_LIST: %s\n", PHOTCODE_A_LIST);
-  fprintf (stderr, "PHOTCODE_B_LIST: %s\n", PHOTCODE_B_LIST);
+  if (DCR_BLUE_COLOR_POS)  fprintf (stderr, "DCR_BLUE_COLOR_POS:  %s - %s\n", DCR_BLUE_COLOR_POS, DCR_BLUE_COLOR_NEG);
+  if (DCR_BLUE_COLOR_POS)  fprintf (stderr, "DCR_BLUE_COLOR_POS:  %s - %s\n", DCR_BLUE_COLOR_POS, DCR_BLUE_COLOR_NEG);
 
-  photcodesKeep = ParsePhotcodeList (PHOTCODE_KEEP_LIST, &NphotcodesKeep, FALSE);
-  photcodesSkip = ParsePhotcodeList (PHOTCODE_SKIP_LIST, &NphotcodesSkip, FALSE);
-  photcodesGroupA = ParsePhotcodeList (PHOTCODE_A_LIST, &NphotcodesGroupA, TRUE);
-  photcodesGroupB = ParsePhotcodeList (PHOTCODE_B_LIST, &NphotcodesGroupB, TRUE);
+  if (PHOTCODE_KEEP_LIST)  fprintf (stderr, "PHOTCODE_KEEP_LIST:  %s\n", PHOTCODE_KEEP_LIST);
+  if (PHOTCODE_SKIP_LIST)  fprintf (stderr, "PHOTCODE_SKIP_LIST:  %s\n", PHOTCODE_SKIP_LIST);
+  if (PHOTCODE_RESET_LIST) fprintf (stderr, "PHOTCODE_RESET_LIST: %s\n", PHOTCODE_RESET_LIST);
+  if (PHOTCODE_A_LIST)     fprintf (stderr, "PHOTCODE_A_LIST: 	  %s\n", PHOTCODE_A_LIST);
+  if (PHOTCODE_B_LIST)     fprintf (stderr, "PHOTCODE_B_LIST: 	  %s\n", PHOTCODE_B_LIST);
+
+  photcodesKeep   = ParsePhotcodeList (PHOTCODE_KEEP_LIST,  &NphotcodesKeep,   FALSE);
+  photcodesSkip   = ParsePhotcodeList (PHOTCODE_SKIP_LIST,  &NphotcodesSkip,   FALSE);
+  photcodesReset  = ParsePhotcodeList (PHOTCODE_RESET_LIST, &NphotcodesReset,  FALSE);
+  photcodesGroupA = ParsePhotcodeList (PHOTCODE_A_LIST,     &NphotcodesGroupA, TRUE);
+  photcodesGroupB = ParsePhotcodeList (PHOTCODE_B_LIST,     &NphotcodesGroupB, TRUE);
+
+  // blue color elements
+  DCR_BLUE_NSEC_POS = DCR_BLUE_NSEC_NEG = -1;
+  if (DCR_BLUE_COLOR_POS) {
+    DCR_BLUE_PHOTCODE_POS = GetPhotcodebyName (DCR_BLUE_COLOR_POS);
+    if (!DCR_BLUE_PHOTCODE_POS) {
+      fprintf (stderr, "ERROR: photcode %s not found in photcode table\n", DCR_BLUE_COLOR_POS);
+      exit (1);
+    }
+    DCR_BLUE_NSEC_POS = GetPhotcodeNsec (DCR_BLUE_PHOTCODE_POS[0].code);
+  }
+  if (DCR_BLUE_COLOR_NEG) {
+    DCR_BLUE_PHOTCODE_NEG = GetPhotcodebyName (DCR_BLUE_COLOR_NEG);
+    if (!DCR_BLUE_PHOTCODE_NEG) {
+      fprintf (stderr, "ERROR: photcode %s not found in photcode table\n", DCR_BLUE_COLOR_NEG);
+      exit (1);
+    }
+    DCR_BLUE_NSEC_NEG = GetPhotcodeNsec (DCR_BLUE_PHOTCODE_NEG[0].code);
+  }
+
+  // red color elements
+  DCR_RED_NSEC_POS = DCR_RED_NSEC_NEG = -1;
+  if (DCR_RED_COLOR_POS) {
+    DCR_RED_PHOTCODE_POS = GetPhotcodebyName (DCR_RED_COLOR_POS);
+    if (!DCR_RED_PHOTCODE_POS) {
+      fprintf (stderr, "ERROR: photcode %s not found in photcode table\n", DCR_RED_COLOR_POS);
+      exit (1);
+    }
+    DCR_RED_NSEC_POS = GetPhotcodeNsec (DCR_RED_PHOTCODE_POS[0].code);
+  }
+  if (DCR_RED_COLOR_NEG) {
+    DCR_RED_PHOTCODE_NEG = GetPhotcodebyName (DCR_RED_COLOR_NEG);
+    if (!DCR_RED_PHOTCODE_NEG) {
+      fprintf (stderr, "ERROR: photcode %s not found in photcode table\n", DCR_RED_COLOR_NEG);
+      exit (1);
+    }
+    DCR_RED_NSEC_NEG = GetPhotcodeNsec (DCR_RED_PHOTCODE_NEG[0].code);
+  }
 
   initstats (STATMODE);
@@ -42,13 +85,15 @@
   args_client (argc, argv);
 
-  fprintf (stderr, "PHOTCODE_KEEP_LIST: %s\n", PHOTCODE_KEEP_LIST);
-  fprintf (stderr, "PHOTCODE_SKIP_LIST: %s\n", PHOTCODE_SKIP_LIST);
-  fprintf (stderr, "PHOTCODE_A_LIST: %s\n", PHOTCODE_A_LIST);
-  fprintf (stderr, "PHOTCODE_B_LIST: %s\n", PHOTCODE_B_LIST);
+  if (PHOTCODE_KEEP_LIST)  fprintf (stderr, "PHOTCODE_KEEP_LIST:  %s\n", PHOTCODE_KEEP_LIST);
+  if (PHOTCODE_SKIP_LIST)  fprintf (stderr, "PHOTCODE_SKIP_LIST:  %s\n", PHOTCODE_SKIP_LIST);
+  if (PHOTCODE_RESET_LIST) fprintf (stderr, "PHOTCODE_RESET_LIST: %s\n", PHOTCODE_RESET_LIST);
+  if (PHOTCODE_A_LIST)     fprintf (stderr, "PHOTCODE_A_LIST:     %s\n", PHOTCODE_A_LIST);
+  if (PHOTCODE_B_LIST)     fprintf (stderr, "PHOTCODE_B_LIST:     %s\n", PHOTCODE_B_LIST);
 
-  photcodesKeep = ParsePhotcodeList (PHOTCODE_KEEP_LIST, &NphotcodesKeep, FALSE);
-  photcodesSkip = ParsePhotcodeList (PHOTCODE_SKIP_LIST, &NphotcodesSkip, FALSE);
-  photcodesGroupA = ParsePhotcodeList (PHOTCODE_A_LIST, &NphotcodesGroupA, TRUE);
-  photcodesGroupB = ParsePhotcodeList (PHOTCODE_B_LIST, &NphotcodesGroupB, TRUE);
+  photcodesKeep   = ParsePhotcodeList (PHOTCODE_KEEP_LIST,  &NphotcodesKeep,   FALSE);
+  photcodesSkip   = ParsePhotcodeList (PHOTCODE_SKIP_LIST,  &NphotcodesSkip,   FALSE);
+  photcodesReset  = ParsePhotcodeList (PHOTCODE_RESET_LIST, &NphotcodesReset,  FALSE);
+  photcodesGroupA = ParsePhotcodeList (PHOTCODE_A_LIST,     &NphotcodesGroupA, TRUE);
+  photcodesGroupB = ParsePhotcodeList (PHOTCODE_B_LIST,     &NphotcodesGroupB, TRUE);
 
   initstats (STATMODE);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/launch_region_hosts.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/launch_region_hosts.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/launch_region_hosts.c	(revision 37403)
@@ -1,17 +1,4 @@
 # include "relastro.h"
 # define DEBUG 0
-
-int strextend (char *input, char *format,...) {
-
-  char tmpextra[1024], tmpline[1024];
-  va_list argp;
-
-  va_start (argp, format);
-  vsnprintf (tmpextra, 1024, format, argp);
-  snprintf (tmpline, 1024, "%s %s", input, tmpextra);
-  strcpy (input, tmpline);
-
-  return TRUE;
-}
 
 int launch_region_hosts (RegionHostTable *regionHosts) {
@@ -22,21 +9,21 @@
   for (i = 0; i < regionHosts->Nhosts; i++) {
     char *syncfile = make_filename (CATDIR, regionHosts->hosts[i].hostname, regionHosts->hosts[i].hostID, "meanmags.sync");
-    truncate (syncfile, 0);
+    if (truncate (syncfile, 0)) fprintf (stderr, "trouble clearing syncfile %s\n", syncfile);
     free (syncfile);
 
     char *fitsfile = make_filename (CATDIR, regionHosts->hosts[i].hostname, regionHosts->hosts[i].hostID, "meanmags.fits");
-    truncate (fitsfile, 0);
+    if (truncate (fitsfile, 0)) fprintf (stderr, "trouble clearing fitsfile %s\n", fitsfile);
     free (fitsfile);
 
     char *imsyncfile = make_filename (CATDIR, regionHosts->hosts[i].hostname, regionHosts->hosts[i].hostID, "imagemags.sync");
-    truncate (imsyncfile, 0);
+    if (truncate (imsyncfile, 0)) fprintf (stderr, "trouble clearing imsyncfile %s\n", imsyncfile);
     free (imsyncfile);
 
     char *imfitsfile = make_filename (CATDIR, regionHosts->hosts[i].hostname, regionHosts->hosts[i].hostID, "imagemags.fits");
-    truncate (imfitsfile, 0);
+    if (truncate (imfitsfile, 0)) fprintf (stderr, "trouble clearing imfitsfile %s\n", imfitsfile);
     free (imfitsfile);
 
     char *loopsyncfile = make_filename (CATDIR, regionHosts->hosts[i].hostname, regionHosts->hosts[i].hostID, "loop.sync");
-    truncate (loopsyncfile, 0);
+    if (truncate (loopsyncfile, 0)) fprintf (stderr, "trouble clearing loopsyncfile %s\n", loopsyncfile);
     free (loopsyncfile);
   }
@@ -88,7 +75,17 @@
     if (PHOTCODE_KEEP_LIST) strextend (command, "+photcode %s", PHOTCODE_KEEP_LIST); 
     if (PHOTCODE_SKIP_LIST) strextend (command, "-photcode %s", PHOTCODE_SKIP_LIST);
+    if (PHOTCODE_RESET_LIST) strextend (command, "-reset-to-photcode %s", PHOTCODE_RESET_LIST);
 
     if (MaxDensityUse) 	    strextend (command, "-max-density %f", MaxDensityValue);
     if (ImagSelect)         strextend (command, "-instmag %f %f", ImagMin, ImagMax);
+    if (ExcludeBogus)       strextend (command, "-exclude-bogus %f", ExcludeBogusRadius);
+
+    if (DCR_BLUE_COLOR_POS && DCR_BLUE_COLOR_NEG) {
+      strextend (command, "-dcr-blue-color %s %s", DCR_BLUE_COLOR_POS, DCR_BLUE_COLOR_NEG); 
+    }
+    if (DCR_RED_COLOR_POS && DCR_RED_COLOR_NEG) {
+      strextend (command, "-dcr-red-color %s %s", DCR_RED_COLOR_POS, DCR_RED_COLOR_NEG); 
+    }
+
     if (PhotFlagSelect)     strextend (command, "+photflags"); 
     if (PhotFlagBad)        strextend (command, "+photflagbad %d", PhotFlagBad); 
@@ -97,4 +94,11 @@
     if (MinBadQF > 0.0)        strextend (command, "-min-bad-psfqf %f", MinBadQF);
     if (MaxMeanOffset != 10.0) strextend (command, "-max-mean-offset  %f", MaxMeanOffset);
+
+    strextend (command, "-D RELASTRO_SRC_MEAS_TOOFEW %d", SRC_MEAS_TOOFEW);
+    strextend (command, "-D RELASTRO_SIGMA_LIM %f", SIGMA_LIM);
+    strextend (command, "-D RELASTRO_DPOS_MAX %f", DPOS_MAX);
+    strextend (command, "-D ADDSTAR_RADIUS %f", ADDSTAR_RADIUS);
+
+    if (USE_FIXED_PIXCOORDS) strextend (command, "-D USE_FIXED_PIXCOORDS 1");
 
     if (TimeSelect) { 
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/load_catalogs.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/load_catalogs.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/load_catalogs.c	(revision 37403)
@@ -1,15 +1,16 @@
 # include "relastro.h"
 
-Catalog *load_catalogs_parallel (SkyList *sky, int *Ncatalog);
+Catalog *load_catalogs_parallel (SkyList *sky, int *Ncatalog, char *syncfile);
 void bcatalog_show_skips ();
 
-Catalog *load_catalogs (SkyList *skylist, int *Ncatalog, int subselect, int hostID, char *hostpath) {
-
-  int i, j, k, m, Nstar;
+Catalog *load_catalogs (SkyList *skylist, int *Ncatalog, int subselect, int hostID, char *hostpath, char *syncfile) {
+
+  int i, j, Nstar;
+  // int k, m;
   Catalog *catalog, *pcatalog, tcatalog;
 
   // XXX need to decide how to determine PARALLEL mode...
   if (PARALLEL && !hostID) {
-    catalog = load_catalogs_parallel (skylist, Ncatalog);
+    catalog = load_catalogs_parallel (skylist, Ncatalog, syncfile);
     return catalog;
   }
@@ -73,4 +74,5 @@
       if (RESET) {
 	for (j = 0; j < catalog[Ncat].Naverage; j++) {
+# if (0)	  
 	  catalog[Ncat].average[j].flags = 0;
 	  m = catalog[Ncat].average[j].measureOffset;
@@ -78,4 +80,5 @@
 	    catalog[Ncat].measure[m+k].dbFlags = 0;
 	  }
+# endif
 	}
       }
@@ -84,5 +87,5 @@
   }
 
-  // XXX TEST : bcatalog_show_skips();
+  bcatalog_show_skips();
 
   Nstar = 0;
@@ -99,4 +102,10 @@
   }
 
+  // if we are running with parallel_images but not a parallel database, we need to
+  // release the lock so the next image host can proceed
+  if (!hostID && syncfile) {
+    update_sync_file (syncfile, 1);
+  }
+
   // only return the populated catalogs
   REALLOCATE (catalog, Catalog, Ncat);
@@ -113,5 +122,5 @@
 // CATDIR is supplied globally
 # define DEBUG 1
-Catalog *load_catalogs_parallel (SkyList *sky, int *Ncatalog) {
+Catalog *load_catalogs_parallel (SkyList *sky, int *Ncatalog, char *syncfile) {
 
   char uniquer[12];
@@ -150,24 +159,29 @@
 	      table->hosts[i].results, table->hosts[i].hostID, CATDIR, table->hosts[i].pathname, UserPatch.Rmin, UserPatch.Rmax, UserPatch.Dmin, UserPatch.Dmax, STATMODE, MIN_ERROR, SIGMA_LIM);
 
-    char tmpline[1024];
-    if (FIT_MODE == FIT_PM_ONLY)  	 { snprintf (tmpline, 1024, "%s -pm",    command);           strcpy (command, tmpline); }
-    if (FIT_MODE == FIT_PAR_ONLY) 	 { snprintf (tmpline, 1024, "%s -par",   command);           strcpy (command, tmpline); }
-    if (FIT_MODE == FIT_PM_AND_PAR)      { snprintf (tmpline, 1024, "%s -pmpar", command);           strcpy (command, tmpline); }
-
-    if (VERBOSE)       { snprintf (tmpline, 1024, "%s -v",              command);                    strcpy (command, tmpline); }
-    if (VERBOSE2)      { snprintf (tmpline, 1024, "%s -vv",             command); 		     strcpy (command, tmpline); }
-    if (RESET)         { snprintf (tmpline, 1024, "%s -reset",          command); 		     strcpy (command, tmpline); }
-    if (ImagSelect)    { snprintf (tmpline, 1024, "%s -instmag %f %f",  command, ImagMin, ImagMax);  strcpy (command, tmpline); }
-    if (MaxDensityUse) { snprintf (tmpline, 1024, "%s -max-density %f", command, MaxDensityValue);   strcpy (command, tmpline); }
+    if (FIT_MODE == FIT_PM_ONLY)  	 strextend (command, "-pm");
+    if (FIT_MODE == FIT_PAR_ONLY) 	 strextend (command, "-par");
+    if (FIT_MODE == FIT_PM_AND_PAR)      strextend (command, "-pmpar");
+
+    if (VERBOSE)       strextend (command, "-v");
+    if (VERBOSE2)      strextend (command, "-vv");
+    if (RESET)         strextend (command, "-reset");
+    if (ImagSelect)    strextend (command, "-instmag %f %f", ImagMin, ImagMax);
+    if (MaxDensityUse) strextend (command, "-max-density %f", MaxDensityValue);
+    if (FlagOutlier)   strextend (command, "-clip %d", CLIP_THRESH);
+    if (ExcludeBogus)  strextend (command, "-exclude-bogus %f", ExcludeBogusRadius);
     
-    if (FlagOutlier)   { snprintf (tmpline, 1024, "%s -clip %d",        command, CLIP_THRESH);       strcpy (command, tmpline); }
-    
-    if (USE_FIXED_PIXCOORDS) { snprintf (tmpline, 1024, "%s -D USE_FIXED_PIXCOORDS 1", command);     strcpy (command, tmpline); }
-
-    if (PHOTCODE_KEEP_LIST) { snprintf (tmpline, 1024, "%s +photcode %s", command, PHOTCODE_KEEP_LIST); strcpy (command, tmpline); }
-    if (PHOTCODE_SKIP_LIST) { snprintf (tmpline, 1024, "%s -photcode %s", command, PHOTCODE_SKIP_LIST); strcpy (command, tmpline); }
-    if (PhotFlagSelect)    { snprintf (tmpline, 1024, "%s +photflags",   command);                     strcpy (command, tmpline); }
-    if (PhotFlagBad)       { snprintf (tmpline, 1024, "%s +photflagbad %d", command, PhotFlagBad);     strcpy (command, tmpline); }
-    if (PhotFlagPoor)      { snprintf (tmpline, 1024, "%s +photflagpoor %d", command, PhotFlagPoor);   strcpy (command, tmpline); }
+    if (DCR_BLUE_COLOR_POS && DCR_BLUE_COLOR_NEG) {
+      strextend (command, "-dcr-blue-color %s %s", DCR_BLUE_COLOR_POS, DCR_BLUE_COLOR_NEG); 
+    }
+    if (DCR_RED_COLOR_POS && DCR_RED_COLOR_NEG) {
+      strextend (command, "-dcr-red-color %s %s", DCR_RED_COLOR_POS, DCR_RED_COLOR_NEG); 
+    }
+
+    if (USE_FIXED_PIXCOORDS) strextend (command, "-D USE_FIXED_PIXCOORDS 1");
+    if (PHOTCODE_KEEP_LIST)  strextend (command, "+photcode %s", PHOTCODE_KEEP_LIST);
+    if (PHOTCODE_SKIP_LIST)  strextend (command, "-photcode %s", PHOTCODE_SKIP_LIST);
+    if (PhotFlagSelect)      strextend (command, "+photflags");
+    if (PhotFlagBad)         strextend (command, "+photflagbad %d", PhotFlagBad); 
+    if (PhotFlagPoor)        strextend (command, "+photflagpoor %d", PhotFlagPoor);
     // XXX note that the above pass in the flag as decimal -- also note that args.c cannot handle 0xHEX values
 
@@ -175,8 +189,7 @@
       char *tstart = ohana_sec_to_date (TSTART);
       char *tstop  = ohana_sec_to_date (TSTOP);
-      snprintf (tmpline, 1024, "%s -time %s %s", command, tstart, tstop); 
+      strextend (command, "-time %s %s", tstart, tstop); 
       free (tstart);
       free (tstop);
-      strcpy (command, tmpline); 
     }
 
@@ -211,4 +224,17 @@
   }
 
+  // update syncfile here (save lots of I/O time):
+
+  // at this point, the remote relastro_client jobs are done loading their data.  in a
+  // parallel_images mode, the next image host can be launched while this image host now
+  // reads that
+
+  // NOTE: if I let all hosts load blindly, I saturate the data clients with too many
+  // relastro_client requests.  I need to have the master mediate this.  the master
+  // will not launch the next remote job until this one says it is done
+  if (syncfile) {
+    update_sync_file (syncfile, 1);
+  }
+
   // each host generates a BrightCatalog structure, with the measure, average, etc value
   // loaded into a single set of arrays (of MeasureTiny, AverageTiny, Secfilt).  I need to
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/markObjects.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/markObjects.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/markObjects.c	(revision 37403)
@@ -8,6 +8,6 @@
   // How strongly do I own this object?
   for (i = 0; i < Ncatalog; i++) {
-    ALLOCATE (catalog[i].nOwn, int, catalog[i].Naverage);
-    memset (catalog[i].nOwn, 0, catalog[i].Naverage*sizeof(int));
+    ALLOCATE (catalog[i].nOwn_t, int, catalog[i].Naverage);
+    memset (catalog[i].nOwn_t, 0, catalog[i].Naverage*sizeof(int));
     for (j = 0; j < catalog[i].Naverage; j++) {
       int nOwn = 0;
@@ -17,5 +17,5 @@
 	nOwn ++;
       }
-      catalog[i].nOwn[j] = nOwn;
+      catalog[i].nOwn_t[j] = nOwn;
     }
   }
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/relastroVisual.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/relastroVisual.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/relastroVisual.c	(revision 37403)
@@ -431,6 +431,6 @@
   
   // populate vectors
-  ALLOCATE(Din, float, Nmeasure);
-  ALLOCATE(Rin, float, Nmeasure);
+  ALLOCATE(Din,  float, Nmeasure);
+  ALLOCATE(Rin,  float, Nmeasure);
   ALLOCATE(Dout, float, Nmeasure);
   ALLOCATE(Rout, float, Nmeasure);
@@ -451,17 +451,17 @@
     meas = catalog[0].measure[m];
     if (!MeasFilterTest(&meas, FALSE)) continue;
-    xmin = MIN(xmin, meas.dR);
-    xmax = MAX(xmax, meas.dR);
-    ymin = MIN(ymin, meas.dD);
-    ymax = MAX(ymax, meas.dD);
+    xmin = MIN(xmin, meas.R);
+    xmax = MAX(xmax, meas.R);
+    ymin = MIN(ymin, meas.D);
+    ymax = MAX(ymax, meas.D);
     
     if (meas.dbFlags & ID_MEAS_POOR_ASTROM) {
-      Rout[Nout] = (float)(meas.dR);
-      Dout[Nout] = (float)(meas.dD);
+      Rout[Nout] = (meas.R);
+      Dout[Nout] = (meas.D);
       fprintf(stderr, "r: %f\td: %f\t outlier: 1\n", Rout[Nout], Dout[Nout]);
       Nout++;
     } else {
-      Rin[Nin] = (float)(meas.dR);
-      Din[Nin] = (float)(meas.dD);
+      Rin[Nin] = (meas.R);
+      Din[Nin] = (meas.D);
       fprintf(stderr, "r: %f\td: %f\t outlier: 0\n", Rin[Nin], Din[Nin]);
       Nin++;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/relastro_client.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/relastro_client.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/relastro_client.c	(revision 37403)
@@ -33,5 +33,5 @@
       // USAGE: relastro_client -load-objects
       int Ncatalog;
-      Catalog *catalog = load_catalogs (skylist, &Ncatalog, TRUE, HOST_ID, HOSTDIR);
+      Catalog *catalog = load_catalogs (skylist, &Ncatalog, TRUE, HOST_ID, HOSTDIR, NULL);
       if (!catalog) {
 	fprintf (stderr, "ERROR loading catalogs from %s\n", CATDIR);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/relastro_images.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/relastro_images.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/relastro_images.c	(revision 37403)
@@ -28,6 +28,14 @@
   // XXX pass in the image table
   // XXX who carries the image grid?
-  catalog = load_catalogs (skylist, &Ncatalog, TRUE, 0, NULL);
+
+  // photcodesKeep is used here to allow measurements from the images being calibrated
+  // note if -reset-to-photcode is selected, photocodesKeep is replaced with below with photcodesReset
+  catalog = load_catalogs (skylist, &Ncatalog, TRUE, 0, NULL, NULL);
   MARKTIME("load catalog data: %f sec\n", dtime);
+
+  if (photcodesReset) {
+    photcodesKeep  = photcodesReset;
+    NphotcodesKeep = NphotcodesReset;
+  }
 
   if (Ncatalog == 0) {
@@ -50,4 +58,6 @@
   // set test points based on the starmap
   createStarMap (catalog, Ncatalog);
+
+  // XXX NOTE : for 2mass reset, photcodesKeep should now limit to 2MASS measurements
 
   /* major modes */
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/relastro_merge_source.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/relastro_merge_source.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/relastro_merge_source.c	(revision 37403)
@@ -100,11 +100,12 @@
       catalog_src.measure[m].averef = index_dst;
 
+      // OLD CODE: when measure.dR,dD were relative to average.R,D it was necessary to modify them
       // get the instantaneous positions:
-      double R = catalog_src.average[index_src].R - catalog_src.measure[m].dR / 3600.0;
-      double D = catalog_src.average[index_src].D - catalog_src.measure[m].dD / 3600.0;
+      // DROP double R = catalog_src.average[index_src].R - catalog_src.measure[m].dR / 3600.0;
+      // DROP double D = catalog_src.average[index_src].D - catalog_src.measure[m].dD / 3600.0;
 
       // update the offset coordinates to match the new source
-      catalog_src.measure[m].dR = 3600.0*(catalog_src.average[index_dst].R - R);
-      catalog_src.measure[m].dD = 3600.0*(catalog_src.average[index_dst].D - D);
+      // DROP catalog_src.measure[m].dR = 3600.0*(catalog_src.average[index_dst].R - R);
+      // DROP catalog_src.measure[m].dD = 3600.0*(catalog_src.average[index_dst].D - D);
     }
 
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/relastro_objects.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/relastro_objects.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/relastro_objects.c	(revision 37403)
@@ -40,4 +40,6 @@
     snprintf (hostfile, 1024, "%s/%s.cpt", hostpath, skylist[0].regions[i]->name);
     catalog.filename  = hostID ? hostfile : skylist[0].filename[i];
+
+    // set up the basic catalog info
     catalog.catformat = dvo_catalog_catformat (CATFORMAT);    // set the default catformat from config data
     catalog.catmode   = dvo_catalog_catmode (CATMODE);        // set the default catmode from config data
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/relastro_parallel_images.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/relastro_parallel_images.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/relastro_parallel_images.c	(revision 37403)
@@ -45,13 +45,14 @@
 
   /* load catalog data from region files (hostID is 0 since we are not a client */
-  catalog = load_catalogs (skylist, &Ncatalog, TRUE, 0, NULL);
+  char *syncfile = make_filename (CATDIR, regionHosts->hosts[myHost].hostname, REGION_HOST_ID, "loadcat.sync");
+  catalog = load_catalogs (skylist, &Ncatalog, TRUE, 0, NULL, syncfile);
   MARKTIME("-- load catalog data: %f sec\n", dtime);
+  free (syncfile);
   
-  // NOTE: if I let all hosts load blindly, I saturate the data clients with too many
-  // relastro_client requests.  I need to have the master mediate this.  the master
-  // will not launch the next remote job until this one says it is done
-  char *syncfile = make_filename (CATDIR, regionHosts->hosts[myHost].hostname, REGION_HOST_ID, "loadcat.sync");
-  update_sync_file (syncfile, 1);
-  
+  if (photcodesReset) {
+    photcodesKeep  = photcodesReset;
+    NphotcodesKeep = NphotcodesReset;
+  }
+
   // generate tables go from catID,objID -> catSeq,objSeq
   indexCatalogs (catalog, Ncatalog);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/share_mean_pos.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/share_mean_pos.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/share_mean_pos.c	(revision 37403)
@@ -33,5 +33,5 @@
       // XXX : sky objects without missing detections
       // XXX watch out for detections which are not associated with an image (REF)
-      if (catalog[i].nOwn[j] == catalog[i].average[j].Nmeasure) continue;
+      if (catalog[i].nOwn_t[j] == catalog[i].average[j].Nmeasure) continue;
 
       set_mean_pos (&meanpos[Nmeanpos], &catalog[i].average[j]);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/syncfile.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/syncfile.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relastro/src/syncfile.c	(revision 37403)
@@ -50,5 +50,5 @@
 int clear_sync_file (char *filename) {
   // delete file contents
-  truncate (filename, 0);
+  if (truncate (filename, 0)) fprintf (stderr, "trouble clearing file %s\n", filename);
 
   return TRUE;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/Makefile
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/Makefile	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/Makefile	(revision 37403)
@@ -34,4 +34,5 @@
 $(SRC)/args.$(ARCH).o		 \
 $(SRC)/help.$(ARCH).o		 \
+$(SRC)/extra.$(ARCH).o		 \
 $(SRC)/bcatalog.$(ARCH).o	 \
 $(SRC)/global_stats.$(ARCH).o	 \
@@ -82,8 +83,10 @@
 $(SRC)/args.$(ARCH).o		 \
 $(SRC)/help.$(ARCH).o		 \
+$(SRC)/extra.$(ARCH).o		 \
 $(SRC)/synthetic_mags.$(ARCH).o	 \
 $(SRC)/plotstuff.$(ARCH).o	 \
 $(SRC)/liststats.$(ARCH).o	 \
 $(SRC)/initialize.$(ARCH).o	 \
+$(SRC)/syncfile.$(ARCH).o	 \
 $(SRC)/load_catalogs.$(ARCH).o	 \
 $(SRC)/reload_catalogs.$(ARCH).o \
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/doc/mosaic.txt
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/doc/mosaic.txt	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/doc/mosaic.txt	(revision 37403)
@@ -1,2 +1,26 @@
+
+
+2014.07.09
+
+* trying to make sense of mosaic.Mcal vs image.Mcal in the context of UBERCAL:
+
+  * relphot_images:
+    * load_images (convert raw FITS table to Image structure, select subset matching selection)
+      * initMosaics (associate mosaics to images (gpc1 photcodes only))
+      	* initMosaicGrid (define spatial range of mosaics [only used by grid analysis]; set Mcal to <image.Mcal> and image.Mcal to 0.0)
+    --- calculate image or mosaic Mcal values
+    * setMcalFinal (set image.Mcal = mosaicMcal)
+
+  * relphot_parallel_regions:
+    * assign_images
+      * makeMosaics (equivalent to initMosaics, but works on full image table, not subset)
+      * setMosaicCenters (set Mcal to <image.Mcal> and image.Mcal to 0.0) <--- this is wrong!
+      (sends images ONLY, not mosaics, to remote machines)
+      (slurps back new image values, applies to db)
+      
+  * relphot_parallel_images:
+    * makeMosaics (associate mosaics to images, gpc1 photcodes only)
+      * initMosaicGrid (needed in this one)
+---
 
 For 'mosaic' zero points, I define the mosaics by grouping the images
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/doc/pv2.txt
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/doc/pv2.txt	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/doc/pv2.txt	(revision 37403)
@@ -0,0 +1,53 @@
+
+2014.07.03
+
+NOTE: 2 questions on these measurements: chisq and ubercal dist?
+
+I think I have worked out all of the issues in the mag / flux
+calibrations for stacks and forced warps.  It took me a few passes to
+get the right combinations of the 3.56 or the 8.9 offset to the mags.
+But now, the stack psf mags, warp psf mags, stack flux, warp flux, and
+mean psf mags all agree at the 0.1 mmag level.
+
+I still have some concerns regarding the flags and astrometry.  I am
+not set on my laptop to test the primary cell stuff (well, I could
+probably reproduce it, but easier to wait until I'm home).  I need to
+review the 'waterfall' and check that the choices make sense (and
+write it down for review).
+
+2014.07.02
+
+I am trying to run a (rather artificial) test of relphot
+specifically, I have taken a single smf and an associated warp cmf and
+modified the headers so I can load them in DVO and run relphot.  Some
+issues I've hit:
+
+* needed to specify PHOTCODE for the stack and fforce fake cmfs
+* needed to modify IMAGEID and MJD-OBS so the chips associated
+  correctly with different gpc1 images
+* modified relphot/MosaicOps.c to explicitly skip stack and warp by
+  photcode when matching chips into mosaics (kind of a hack as it
+  won't work with other cameras)
+
+2014.07.01
+
+thinking about the issues with relphot for the new PV2 / PV3 schema.
+I now have 3 separate sets of mean photometry for each of the stages
+cam/staticsky/warp.  I need to make sure I am handling everthing
+needed.
+
+Calibration sequence:
+
+* relphot_images / relphot_parallel_images : calculate the zero points
+
+Loop around with the standard sequence, but only fitting for the mean
+camera mags and camera zero points.   At the end of the iteration, fit
+the stacks and warps to the new mean object mags.  
+
+Some things I've started to worry about:
+
+1) QSOs & other variables.  Am I detecting and avoiding these well
+enough?
+
+2) what is the appropriate ubercal weight (10, 100, 1000?)
+
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/include/relphot.h
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/include/relphot.h	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/include/relphot.h	(revision 37403)
@@ -4,13 +4,4 @@
 # include <signal.h>
 # include <pthread.h>
-
-# define MARKTIME(MSG,...) {			\
-    gettimeofday (&stopTimer, (void *) NULL);	\
-    float dtime = DTIME (stopTimer, startTimer);	\
-    fprintf (stderr, MSG, __VA_ARGS__); }
-
-# define INITTIME \
-  struct timeval startTimer, stopTimer; \
-  gettimeofday (&startTimer, (void *) NULL);
 
 /* # define GRID_V1 */
@@ -119,5 +110,5 @@
   float M;
   float dM;
-  float Xm;
+  float Mchisq;
   int Nsec;
   unsigned int objID;
@@ -130,5 +121,5 @@
   float dMcal;
   float dMagSys;
-  float Xm;
+  short Xm;
   int nFitPhotom;
   int flags;
@@ -317,5 +308,5 @@
 int           findMosaics         PROTO((Catalog *catalog, int Ncatalog, int doMosaicList));
 
-void makeMosaics (Image *image, off_t Nimage);
+void makeMosaics (Image *image, off_t Nimage, int mergeMcal);
 Mosaic *getMosaicForImage (off_t im);
 void setMosaicCenters (Image *image, off_t Nimage);
@@ -360,6 +351,6 @@
 void          liststats_setmode   PROTO((StatType *stats, char *strmode));
 int           liststats           PROTO((double *value, double *dvalue, double *wvalue, int N, StatType *stats));
-Catalog      *load_catalogs       PROTO((SkyList *skylist, int *Ncatalog, int hostID, char *hostpath));
-Catalog      *load_catalogs_parallel PROTO((SkyList *sky, int *Ncatalog));
+Catalog      *load_catalogs       PROTO((SkyList *skylist, int *Ncatalog, int hostID, char *hostpath, char *syncfile));
+Catalog      *load_catalogs_parallel PROTO((SkyList *sky, int *Ncatalog, char *syncfile));
 
 SkyList      *load_images         PROTO((FITS_DB *db, char *regionName, SkyRegion *region));
@@ -449,4 +440,5 @@
 int MatchImageName (off_t meas, int cat, char *name);
 int MatchImageSkycellID (off_t meas, int cat, int myTessID, int myProjectionID, int mySkycellID);
+int FindImageSkycellID (off_t meas, int cat, int *myTessID, int *myProjectionID, int *mySkycellID);
 
 int load_tess (char *treefile);
@@ -460,5 +452,5 @@
 int setMrel_catalog_alt (Catalog *catalog, int Nc, int pass, FlatCorrectionTable *flatcorr, SetMrelInfo *results, int Nsecfilt);
 int setMrelAverageExposure (off_t meas, int cat, int pass, FlatCorrectionTable *flatcorr, SetMrelInfo *results, Average *average, AverageTiny *averageT, SecFilt *secfilt, Measure *measure, MeasureTiny *measureT, off_t *found);
-int setMrelAverageStack (off_t meas, int cat, FlatCorrectionTable *flatcorr, SetMrelInfo *results, Average *average, SecFilt *secfilt, Measure *measure, char *primaryCell);
+int setMrelAverageStack (off_t meas, int cat, FlatCorrectionTable *flatcorr, SetMrelInfo *results, Average *average, SecFilt *secfilt, Measure *measure);
 int setGlobalObjStats (Average *average, Measure *measure);
 
@@ -509,2 +501,9 @@
 int relphot_parallel_images ();
 int relphot_parallel_regions ();
+
+// in extra.c
+int isGPC1chip  (int photcode);
+int isGPC1stack (int photcode);
+int isGPC1warp  (int photcode);
+
+
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/BrightCatalog.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/BrightCatalog.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/BrightCatalog.c	(revision 37403)
@@ -63,6 +63,6 @@
  
     // need to create and assign to flat-field correction
-    GET_COLUMN(dR,        "RA_OFF",   	float);
-    GET_COLUMN(dD,        "DEC_OFF",  	float);
+    GET_COLUMN(R,         "RA",   	double);
+    GET_COLUMN(D,         "DEC",  	double);
     GET_COLUMN(M,         "MAG_SYS",  	float);
     GET_COLUMN(Mcal,      "MAG_CAL",  	float);
@@ -85,6 +85,6 @@
     ALLOCATE (measure, MeasureTiny, Nrow);
     for (i = 0; i < Nrow; i++) {
-      measure[i].dR        = dR[i];
-      measure[i].dD        = dD[i];
+      measure[i].R         = R[i];
+      measure[i].D         = D[i];
       measure[i].M         = M[i];
       measure[i].Mcal      = Mcal[i];
@@ -105,6 +105,6 @@
     fprintf (stderr, "loaded data for %lld measure\n", (long long) Nrow);
 
-    free (dR      );
-    free (dD      );
+    free (R       );
+    free (D       );
     free (M       );
     free (Mcal    );
@@ -136,6 +136,6 @@
  
     // need to create and assign to flat-field correction
-    GET_COLUMN(R,             "RA",   	   double);
-    GET_COLUMN(D,             "DEC",  	   double);
+    GET_COLUMN(R,             "RA",   	     double);
+    GET_COLUMN(D,             "DEC",  	     double);
     GET_COLUMN(Nmeasure,      "NMEAS",       int);
     GET_COLUMN(measureOffset, "MEASURE_OFF", int);
@@ -182,12 +182,12 @@
  
     // need to create and assign to flat-field correction
-    GET_COLUMN(M,     "MAG",      float);
-    GET_COLUMN(dM,    "MAG_ERR",  float);
-    GET_COLUMN(Xm,    "MAG_CHI",  float);
-    GET_COLUMN(flags, "FLAGS",    int);
-    GET_COLUMN(Ncode, "NCODE",    short);
-    GET_COLUMN(Nused, "NUSED",    short);
-    GET_COLUMN(M_20,  "MAG_20",   short);
-    GET_COLUMN(M_80,  "MAG_80",   short);
+    GET_COLUMN(M,      "MAG",      float);
+    GET_COLUMN(dM,     "MAG_ERR",  float);
+    GET_COLUMN(Mchisq, "MAG_CHI",  float);
+    GET_COLUMN(flags,  "FLAGS",    int);
+    GET_COLUMN(Ncode,  "NCODE",    short);
+    GET_COLUMN(Nused,  "NUSED",    short);
+    GET_COLUMN(Mmin,   "MAG_MIN",  float);
+    GET_COLUMN(Mmax,   "MAG_MAX",  float);
     gfits_free_header (&theader);
     gfits_free_table  (&ftable);
@@ -196,23 +196,23 @@
     ALLOCATE (secfilt, SecFilt, Nrow);
     for (i = 0; i < Nrow; i++) {
-      secfilt[i].M     = M[i];         
-      secfilt[i].dM    = dM[i];
-      secfilt[i].Xm    = Xm[i];
-      secfilt[i].flags = flags[i];
-      secfilt[i].Ncode = Ncode[i];
-      secfilt[i].Nused = Nused[i];
-      secfilt[i].M_20  = M_20[i];
-      secfilt[i].M_80  = M_80[i];
+      secfilt[i].M      = M[i];         
+      secfilt[i].dM     = dM[i];
+      secfilt[i].Mchisq = Mchisq[i];
+      secfilt[i].flags  = flags[i];
+      secfilt[i].Ncode  = Ncode[i];
+      secfilt[i].Nused  = Nused[i];
+      secfilt[i].Mmin   = Mmin[i];
+      secfilt[i].Mmax   = Mmax[i];
     }
     fprintf (stderr, "loaded data for %lld secfilt\n", (long long) Nrow);
 
-    free (M    );
-    free (dM   );
-    free (Xm   );
-    free (flags);
-    free (Ncode);
-    free (Nused);
-    free (M_20 );
-    free (M_80 );
+    free (M     );
+    free (dM    );
+    free (Mchisq);
+    free (flags );
+    free (Ncode );
+    free (Nused );
+    free (Mmin  );
+    free (Mmax  );
     catalog->secfilt = secfilt;
     // assert Nsecfilt * Naverage = Nrow?
@@ -265,6 +265,6 @@
     gfits_create_table_header (&theader, "BINTABLE", "MEASURE_TINY");
 
-    gfits_define_bintable_column (&theader, "E", "RA_OFF",   "ra offset",                  "arcsec", 1.0, 0.0);
-    gfits_define_bintable_column (&theader, "E", "DEC_OFF",  "dec offset",                 "arcsec", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "D", "RA",       "ra",                         "degree", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "D", "DEC",      "dec",                        "degree", 1.0, 0.0);
     gfits_define_bintable_column (&theader, "E", "MAG_SYS",  "magnitude (sys)",             NULL,    1.0, 0.0);
     gfits_define_bintable_column (&theader, "E", "MAG_CAL",  "magnitude (cal)",             NULL,    1.0, 0.0);
@@ -274,11 +274,11 @@
     gfits_define_bintable_column (&theader, "E", "Y_CCD",    "ccd y coord",            	   "pix",    1.0, 0.0);
     gfits_define_bintable_column (&theader, "E", "EXPTIME",  "-2.5 * log (exposure time)", "sec",    1.0, 0.0);
-    gfits_define_bintable_column (&theader, "J", "TIME",     "time of exp",                "sec",    1.0, 1.0*0x8000);
-    gfits_define_bintable_column (&theader, "J", "AVE_REF",  "pointer to average table",    NULL,    1.0, 1.0*0x8000);
-    gfits_define_bintable_column (&theader, "J", "IMAGE_ID", "image",                       NULL,    1.0, 1.0*0x8000);
-    gfits_define_bintable_column (&theader, "J", "DB_FLAGS", "flags",                       NULL,    1.0, 1.0*0x8000);
-    gfits_define_bintable_column (&theader, "J", "PHOT_FLAGS", "photflags",                 NULL,    1.0, 1.0*0x8000);
-    gfits_define_bintable_column (&theader, "J", "CAT_ID",   "catalog",                     NULL,    1.0, 1.0*0x8000);
-    gfits_define_bintable_column (&theader, "I", "PHOTCODE", "photcode",                    NULL,    1.0, 1.0*0x80);
+    gfits_define_bintable_column (&theader, "J", "TIME",     "time of exp",                "sec",    1.0, FT_BZERO_INT32);
+    gfits_define_bintable_column (&theader, "J", "AVE_REF",  "pointer to average table",    NULL,    1.0, FT_BZERO_INT32);
+    gfits_define_bintable_column (&theader, "J", "IMAGE_ID", "image",                       NULL,    1.0, FT_BZERO_INT32);
+    gfits_define_bintable_column (&theader, "J", "DB_FLAGS", "flags",                       NULL,    1.0, FT_BZERO_INT32);
+    gfits_define_bintable_column (&theader, "J", "PHOT_FLAGS", "photflags",                 NULL,    1.0, FT_BZERO_INT32);
+    gfits_define_bintable_column (&theader, "J", "CAT_ID",   "catalog",                     NULL,    1.0, FT_BZERO_INT32);
+    gfits_define_bintable_column (&theader, "I", "PHOTCODE", "photcode",                    NULL,    1.0, FT_BZERO_INT16);
 
     // generate the output array that carries the data
@@ -286,26 +286,26 @@
 
     // create intermediate storage arrays
-    float *dR        ; ALLOCATE (dR       ,  float, catalog->Nmeasure);
-    float *dD        ; ALLOCATE (dD       ,  float, catalog->Nmeasure);
-    float *M         ; ALLOCATE (M        ,  float, catalog->Nmeasure);
-    float *Mcal      ; ALLOCATE (Mcal     ,  float, catalog->Nmeasure);
-    float *dM        ; ALLOCATE (dM       ,  float, catalog->Nmeasure);
-    float *airmass   ; ALLOCATE (airmass  ,  float, catalog->Nmeasure);
-    float *Xccd      ; ALLOCATE (Xccd     ,  float, catalog->Nmeasure);
-    float *Yccd      ; ALLOCATE (Yccd     ,  float, catalog->Nmeasure);
-    float *dt        ; ALLOCATE (dt       ,  float, catalog->Nmeasure);
-    int   *t         ; ALLOCATE (t        ,  int  , catalog->Nmeasure);
-    int   *averef    ; ALLOCATE (averef   ,  int  , catalog->Nmeasure);
-    int   *imageID   ; ALLOCATE (imageID  ,  int  , catalog->Nmeasure);
-    int   *dbFlags   ; ALLOCATE (dbFlags  ,  int  , catalog->Nmeasure);
-    int   *photFlags ; ALLOCATE (photFlags,  int  , catalog->Nmeasure);
-    int   *catID     ; ALLOCATE (catID    ,  int  , catalog->Nmeasure);
-    short *photcode  ; ALLOCATE (photcode ,  short, catalog->Nmeasure);
+    double *R         ; ALLOCATE (R        ,  double, catalog->Nmeasure);
+    double *D         ; ALLOCATE (D        ,  double, catalog->Nmeasure);
+    float  *M         ; ALLOCATE (M        ,  float,  catalog->Nmeasure);
+    float  *Mcal      ; ALLOCATE (Mcal     ,  float,  catalog->Nmeasure);
+    float  *dM        ; ALLOCATE (dM       ,  float,  catalog->Nmeasure);
+    float  *airmass   ; ALLOCATE (airmass  ,  float,  catalog->Nmeasure);
+    float  *Xccd      ; ALLOCATE (Xccd     ,  float,  catalog->Nmeasure);
+    float  *Yccd      ; ALLOCATE (Yccd     ,  float,  catalog->Nmeasure);
+    float  *dt        ; ALLOCATE (dt       ,  float,  catalog->Nmeasure);
+    int    *t         ; ALLOCATE (t        ,  int  ,  catalog->Nmeasure);
+    int    *averef    ; ALLOCATE (averef   ,  int  ,  catalog->Nmeasure);
+    int    *imageID   ; ALLOCATE (imageID  ,  int  ,  catalog->Nmeasure);
+    int    *dbFlags   ; ALLOCATE (dbFlags  ,  int  ,  catalog->Nmeasure);
+    int    *photFlags ; ALLOCATE (photFlags,  int  ,  catalog->Nmeasure);
+    int    *catID     ; ALLOCATE (catID    ,  int  ,  catalog->Nmeasure);
+    short  *photcode  ; ALLOCATE (photcode ,  short,  catalog->Nmeasure);
 
     // assign the storage arrays
     MeasureTiny *measure = catalog->measure;
     for (i = 0; i < catalog->Nmeasure; i++) {
-      dR[i]       = measure[i].dR       ;
-      dD[i]       = measure[i].dD       ;
+      R[i]        = measure[i].R       ;
+      D[i]        = measure[i].D       ;
       M[i]  	  = measure[i].M        ;
       Mcal[i]     = measure[i].Mcal     ;
@@ -325,6 +325,6 @@
 
     // add the columns to the output array
-    gfits_set_bintable_column (&theader, &ftable, "RA_OFF",   	dR,        catalog->Nmeasure);
-    gfits_set_bintable_column (&theader, &ftable, "DEC_OFF",  	dD,        catalog->Nmeasure);
+    gfits_set_bintable_column (&theader, &ftable, "RA",   	R,         catalog->Nmeasure);
+    gfits_set_bintable_column (&theader, &ftable, "DEC",  	D,         catalog->Nmeasure);
     gfits_set_bintable_column (&theader, &ftable, "MAG_SYS",  	M,         catalog->Nmeasure);
     gfits_set_bintable_column (&theader, &ftable, "MAG_CAL",  	Mcal,      catalog->Nmeasure);
@@ -342,6 +342,6 @@
     gfits_set_bintable_column (&theader, &ftable, "PHOTCODE",   photcode,  catalog->Nmeasure);
 
-    free (dR      );
-    free (dD      );
+    free (R       );
+    free (D       );
     free (M       );
     free (Mcal    );
@@ -428,12 +428,12 @@
     gfits_create_table_header (&theader, "BINTABLE", "SECFILT");
 
-    gfits_define_bintable_column (&theader, "E", "MAG",      "ra offset",                "arcsec", 1.0, 0.0);
-    gfits_define_bintable_column (&theader, "E", "MAG_ERR",  "dec offset",               "arcsec", 1.0, 0.0);
-    gfits_define_bintable_column (&theader, "E", "MAG_CHI",  "magnitude (sys)",           NULL,    1.0, 0.0);
-    gfits_define_bintable_column (&theader, "J", "FLAGS",    "magnitude (cal)",           NULL,    1.0, 0.0);
-    gfits_define_bintable_column (&theader, "I", "NCODE",    "magnitude (err)",           NULL,    1.0, 0.0);
-    gfits_define_bintable_column (&theader, "I", "NUSED",    "airmass",                   NULL,    1.0, 0.0);
-    gfits_define_bintable_column (&theader, "I", "MAG_20",   "ccd x coord",              "pix",    1.0, 0.0);
-    gfits_define_bintable_column (&theader, "I", "MAG_80",   "ccd y coord",              "pix",    1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "MAG",      "",              "arcsec", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "MAG_ERR",  "",              "arcsec", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "MAG_CHI",  "",              NULL,    1.0, 0.0);
+    gfits_define_bintable_column (&theader, "J", "FLAGS",    "",              NULL,    1.0, 0.0);
+    gfits_define_bintable_column (&theader, "I", "NCODE",    "",              NULL,    1.0, 0.0);
+    gfits_define_bintable_column (&theader, "I", "NUSED",    "",              NULL,    1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "MAG_MIN",  "min valid mag", "mag",   1.0, 0.0);
+    gfits_define_bintable_column (&theader, "E", "MAG_MAX",  "max valid mag", "mag",   1.0, 0.0);
 
     // generate the output array that carries the data
@@ -447,42 +447,42 @@
     float *M        ; ALLOCATE (M      ,  float, Nsec);
     float *dM       ; ALLOCATE (dM     ,  float, Nsec);
-    float *Xm       ; ALLOCATE (Xm     ,  float, Nsec);
+    float *Mchisq   ; ALLOCATE (Mchisq ,  float, Nsec);
     int   *flags    ; ALLOCATE (flags  ,  int,   Nsec);
     short *Ncode    ; ALLOCATE (Ncode  ,  short, Nsec);
     short *Nused    ; ALLOCATE (Nused  ,  short, Nsec);
-    short *M_20     ; ALLOCATE (M_20   ,  short, Nsec);
-    short *M_80     ; ALLOCATE (M_80   ,  short, Nsec);
+    float *Mmin     ; ALLOCATE (Mmin   ,  float, Nsec);
+    float *Mmax     ; ALLOCATE (Mmax   ,  float, Nsec);
 
     // assign the storage arrays
     SecFilt *secfilt = catalog->secfilt;
     for (i = 0; i < Nsec; i++) {
-      M     [i]       = secfilt[i]. M      ;
-      dM    [i]       = secfilt[i]. dM     ;
-      Xm    [i]       = secfilt[i]. Xm     ;
-      flags [i]       = secfilt[i]. flags  ;
-      Ncode [i]       = secfilt[i]. Ncode  ;
-      Nused [i]       = secfilt[i]. Nused  ;
-      M_20  [i]       = secfilt[i]. M_20   ;
-      M_80  [i]       = secfilt[i]. M_80   ;
+      M     [i]       = secfilt[i].M      ;
+      dM    [i]       = secfilt[i].dM     ;
+      Mchisq[i]       = secfilt[i].Mchisq ;
+      flags [i]       = secfilt[i].flags  ;
+      Ncode [i]       = secfilt[i].Ncode  ;
+      Nused [i]       = secfilt[i].Nused  ;
+      Mmin  [i]       = secfilt[i].Mmin   ;
+      Mmax  [i]       = secfilt[i].Mmax   ;
     }
 
     // add the columns to the output array
-    gfits_set_bintable_column (&theader, &ftable, "MAG",      M    , Nsec);
-    gfits_set_bintable_column (&theader, &ftable, "MAG_ERR",  dM   , Nsec);
-    gfits_set_bintable_column (&theader, &ftable, "MAG_CHI",  Xm   , Nsec);
-    gfits_set_bintable_column (&theader, &ftable, "FLAGS",    flags, Nsec);
-    gfits_set_bintable_column (&theader, &ftable, "NCODE",    Ncode, Nsec);
-    gfits_set_bintable_column (&theader, &ftable, "NUSED",    Nused, Nsec);
-    gfits_set_bintable_column (&theader, &ftable, "MAG_20",   M_20 , Nsec);
-    gfits_set_bintable_column (&theader, &ftable, "MAG_80",   M_80 , Nsec);
+    gfits_set_bintable_column (&theader, &ftable, "MAG",      M     , Nsec);
+    gfits_set_bintable_column (&theader, &ftable, "MAG_ERR",  dM    , Nsec);
+    gfits_set_bintable_column (&theader, &ftable, "MAG_CHI",  Mchisq, Nsec);
+    gfits_set_bintable_column (&theader, &ftable, "FLAGS",    flags , Nsec);
+    gfits_set_bintable_column (&theader, &ftable, "NCODE",    Ncode , Nsec);
+    gfits_set_bintable_column (&theader, &ftable, "NUSED",    Nused , Nsec);
+    gfits_set_bintable_column (&theader, &ftable, "MAG_MIN",  Mmin  , Nsec);
+    gfits_set_bintable_column (&theader, &ftable, "MAG_MAX",  Mmax  , Nsec);
 
     free (M      );
     free (dM     );
-    free (Xm     );
+    free (Mchisq );
     free (flags  );
     free (Ncode  );
     free (Nused  );
-    free (M_20   );
-    free (M_80   );
+    free (Mmin   );
+    free (Mmax   );
 
     gfits_fwrite_Theader (f, &theader);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/GridOps.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/GridOps.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/GridOps.c	(revision 37403)
@@ -414,5 +414,5 @@
 	// select the color- and airmass-corrected observed magnitude for this star
 	// XXX need to be able to turn off the color-correction until initial average mags are found
-	Msys = PhotCatTiny (&catalog[c].measureT[m]);
+	Msys = PhotCatTiny (&catalog[c].measureT[m], MAG_CLASS_PSF);
 	if (isnan(Msys)) {
 	  Nsys++;
@@ -573,5 +573,5 @@
       
       n = catalog[c].measureT[m].averef;
-      Msys = PhotSysTiny (&catalog[c].measureT[m], &catalog[c].averageT[n], &catalog[c].secfilt[n*Nsecfilt]);
+      Msys = PhotSysTiny (&catalog[c].measureT[m], &catalog[c].averageT[n], &catalog[c].secfilt[n*Nsecfilt], MAG_CLASS_PSF);
       if (isnan(Msys)) {
 	Nsys++;
@@ -651,5 +651,5 @@
 
       n = catalog[c].measureT[m].averef;
-      Msys = PhotSysTiny (&catalog[c].measureT[m], &catalog[c].averageT[n], &catalog[c].secfilt[n*Nsecfilt]);
+      Msys = PhotSysTiny (&catalog[c].measureT[m], &catalog[c].averageT[n], &catalog[c].secfilt[n*Nsecfilt], MAG_CLASS_PSF);
 
       xlist[N] = Xmeas[c][m];
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/ImageMagIO.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/ImageMagIO.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/ImageMagIO.c	(revision 37403)
@@ -61,9 +61,9 @@
   GET_COLUMN (dMcal,             "MCAL_ERR",       float);
   GET_COLUMN (dMagSys,           "MCAL_SYSERR",    float);
-  GET_COLUMN (Xm,                "CHISQ",          float);
   GET_COLUMN (nFitPhotom,        "NFIT",             int);
   GET_COLUMN (flags,             "FLAGS",            int);
   GET_COLUMN (ubercalDist,       "UDIST",            int);
   GET_COLUMN (imageID,           "ID",               int);
+  GET_COLUMN (Xm,                "CHISQ",          short);
 
   // free the memory associated with the FITS files
@@ -121,12 +121,12 @@
   gfits_create_table_header (&theader, "BINTABLE", "IMAGE_MAGS");
 
-  gfits_define_bintable_column (&theader, "E", "MCAL",           "cal offset", "magnitudes", 1.0, 0.0);
-  gfits_define_bintable_column (&theader, "E", "MCAL_ERR",       "cal error", "magnitudes", 1.0, 0.0);
-  gfits_define_bintable_column (&theader, "E", "MCAL_SYSERR",    "systematic error", "magnitudes", 1.0, 0.0);
-  gfits_define_bintable_column (&theader, "E", "CHISQ",          "cal chisq", "unitless", 1.0, 0.0);
-  gfits_define_bintable_column (&theader, "J", "NFIT",           "number of fitted stars", "unitless", 1.0, 0.0);
-  gfits_define_bintable_column (&theader, "J", "FLAGS",          "analysis flags", "unitless", 1.0, 0.0);
-  gfits_define_bintable_column (&theader, "J", "UDIST",          "distance to ubercal images", "images", 1.0, 0.0);
-  gfits_define_bintable_column (&theader, "J", "ID",             "image ID", "unitless", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E", "MCAL",           "cal offset", 		       "magnitudes", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E", "MCAL_ERR",       "cal error",  		       "magnitudes", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E", "MCAL_SYSERR",    "systematic error", 	       "magnitudes", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "J", "NFIT",           "number of fitted stars",     "unitless",   1.0, 0.0);
+  gfits_define_bintable_column (&theader, "J", "FLAGS",          "analysis flags", 	       "unitless",   1.0, 0.0);
+  gfits_define_bintable_column (&theader, "J", "UDIST",          "distance to ubercal images", "images",     1.0, 0.0);
+  gfits_define_bintable_column (&theader, "J", "ID",             "image ID",  		       "unitless",   1.0, 0.0);
+  gfits_define_bintable_column (&theader, "I", "CHISQ",          "cal chisq", 		       "unitless",   1.0, FT_BZERO_INT16);
 
   // generate the output array that carries the data
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/ImageOps.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/ImageOps.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/ImageOps.c	(revision 37403)
@@ -495,4 +495,27 @@
 }
 
+// returns image.Mcal - ff(x,y)
+int FindImageSkycellID (off_t meas, int cat, int *myTessID, int *myProjectionID, int *mySkycellID) {
+
+  off_t i;
+
+  if (!MeasureToImage) return FALSE;
+
+  if (meas < 0) return FALSE;
+
+  i = MeasureToImage[cat][meas];
+  if (i == -1) return FALSE;
+
+  if (tessID[i]    == -1) return FALSE;
+  if (projectID[i] == -1) return FALSE;
+  if (skycellID[i] == -1) return FALSE;
+
+  *myTessID = tessID[i];
+  *myProjectionID = projectID[i];
+  *mySkycellID =  skycellID[i];
+  
+  return TRUE;
+}
+
 float getMflat (off_t meas, int cat, FlatCorrectionTable *flatcorr, Catalog *catalog) {
 
@@ -531,5 +554,5 @@
   liststats_setmode (&stats, STATMODE);
 
-  if (FREEZE_IMAGES) return;
+  // FREEZE_IMAGES only applies to mosaic data (eg, gpc1)
 
   fprintf (stderr, "limiting negative clouds to %f\n", CLOUD_TOLERANCE);
@@ -561,4 +584,6 @@
       if (!bad) continue;
     }      
+
+    if (FREEZE_IMAGES && isGPC1chip(image[i].photcode)) continue;
 
     // UBERCAL image: if this is an ubercal image, set minUbercalDist to 0:
@@ -608,5 +633,5 @@
 
       n = catalog[c].measureT[m].averef;
-      Msys = PhotSysTiny (&catalog[c].measureT[m], &catalog[c].averageT[n], &catalog[c].secfilt[n*Nsecfilt]);
+      Msys = PhotSysTiny (&catalog[c].measureT[m], &catalog[c].averageT[n], &catalog[c].secfilt[n*Nsecfilt], MAG_CLASS_PSF);
       if (isnan(Msys)) {
 	Nsys++;
@@ -695,5 +720,5 @@
   double MaxOffset, MaxScatter, MedOffset;
 
-  if (FREEZE_IMAGES) return;
+  // if (FREEZE_IMAGES) return;
 
   if (VERBOSE) fprintf (stderr, "marking poor images\n");
@@ -706,4 +731,7 @@
   for (i = N = 0; i < Nimage; i++) {
     if (image[i].flags & IMAGE_BAD) continue;
+
+    if (FREEZE_IMAGES && isGPC1chip(image[i].photcode)) continue;
+
     mlist[N] = image[i].Mcal;
     slist[N] = image[i].dMcal;
@@ -797,5 +825,5 @@
   Graphdata graphdata;
 
-  if (FREEZE_IMAGES) return;
+  // if (FREEZE_IMAGES) return;
 
   ALLOCATE (xlist, double, Nimage);
@@ -810,8 +838,14 @@
   float mindMcal    = +100.0;
   float maxdMcal    = -100.0;
-  for (i = 0; i < Nimage; i++) {
-    Mlist[i] = image[i].Mcal;
-    dlist[i] = image[i].dMcal;
-    xlist[i] = image[i].secz;
+
+  int Nplot = 0;
+
+  for (i = 0; i < Nimage; i++) {
+
+    if (FREEZE_IMAGES && isGPC1chip(image[i].photcode)) continue;
+
+    Mlist[Nplot] = image[i].Mcal;
+    dlist[Nplot] = image[i].dMcal;
+    xlist[Nplot] = image[i].secz;
     minAirmass = MIN (image[i].secz, minAirmass);
     maxAirmass = MAX (image[i].secz, maxAirmass);
@@ -820,4 +854,6 @@
     mindMcal = MIN (image[i].dMcal, mindMcal);
     maxdMcal = MAX (image[i].dMcal, maxdMcal);
+    
+    Nplot ++;
   }
 
@@ -852,5 +888,8 @@
   for (i = 0; i < NBIN; i++) xlist[i] = 0.00025*i;
   bzero (Mlist, NBIN*sizeof(double));
-  for (i = 0; i < Nimage; i++) {
+
+  for (i = 0; i < Nimage; i++) {
+    if (FREEZE_IMAGES && isGPC1chip(image[i].photcode)) continue;
+
     bin = image[i].dMcal / 0.00025;
     bin = MAX (0, MIN (NBIN - 1, bin));
@@ -877,5 +916,7 @@
   StatType stats;
   bzero (&stats, sizeof (StatType));
-  if (FREEZE_IMAGES) return (stats);
+
+  // we no longer blindly apply FREEZE_IMAGES to all images, only to mosaics
+  // if (FREEZE_IMAGES) return (stats);
 
   ALLOCATE (list, double, Nimage);
@@ -885,4 +926,6 @@
   for (i = 0; i < Nimage; i++) {
     if (image[i].flags & IMAGE_BAD)  continue;
+
+    if (FREEZE_IMAGES && isGPC1chip(image[i].photcode)) continue;
 
     N = 0;
@@ -920,5 +963,5 @@
 
   bzero (&stats, sizeof (StatType));
-  if (FREEZE_IMAGES) return (stats);
+  // if (FREEZE_IMAGES) return (stats);
 
   ALLOCATE (list, double, Nimage);
@@ -929,4 +972,6 @@
 
     if (image[i].flags & IMAGE_BAD)  continue;
+
+    if (FREEZE_IMAGES && isGPC1chip(image[i].photcode)) continue;
 
     list[n] = pow (10.0, 0.01*image[i].Xm);
@@ -950,5 +995,5 @@
 
   bzero (&stats, sizeof (StatType));
-  if (FREEZE_IMAGES) return (stats);
+  // if (FREEZE_IMAGES) return (stats);
 
   ALLOCATE (list, double, Nimage);
@@ -959,4 +1004,6 @@
 
     if (image[i].flags & IMAGE_BAD)  continue;
+
+    if (FREEZE_IMAGES && isGPC1chip(image[i].photcode)) continue;
 
     list[n] = image[i].Mcal;
@@ -980,5 +1027,5 @@
 
   bzero (&stats, sizeof (StatType));
-  if (FREEZE_IMAGES) return (stats);
+  // if (FREEZE_IMAGES) return (stats);
 
   ALLOCATE (list, double, Nimage);
@@ -989,4 +1036,6 @@
 
     if (image[i].flags & IMAGE_BAD)  continue;
+
+    if (FREEZE_IMAGES && isGPC1chip(image[i].photcode)) continue;
 
     list[n] = image[i].dMcal;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/ImageSubset.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/ImageSubset.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/ImageSubset.c	(revision 37403)
@@ -126,19 +126,15 @@
   gfits_create_table_header (&theader, "BINTABLE", "IMAGE_SUBSET");
 
-  gfits_define_bintable_column (&theader, "E", "MCAL", "zero point offset", "magnitudes", 1.0, 0.0);
-  gfits_define_bintable_column (&theader, "E", "MCAL_ERR", "zero point error", "magnitudes", 1.0, 0.0);
-
-  gfits_define_bintable_column (&theader, "J", "IMAGE_ID", "image ID", NULL, 1.0, 1.0*0x8000);
-  gfits_define_bintable_column (&theader, "J", "PHOTOM_MAP", "map", NULL, 1.0, 1.0*0x8000);
-  gfits_define_bintable_column (&theader, "J", "FLAGS", "flags", NULL, 1.0, 1.0*0x8000);
-
-  gfits_define_bintable_column (&theader, "J", "TESS_ID", "ID", NULL, 1.0, 0.0);
-  gfits_define_bintable_column (&theader, "J", "PROJ_ID", "ID", NULL, 1.0, 0.0);
-  gfits_define_bintable_column (&theader, "J", "SKYCELL_ID", "ID", NULL, 1.0, 0.0);
-
-  gfits_define_bintable_column (&theader, "J", "TZERO", "exposure start", NULL, 1.0, 1.0*0x8000);
-  gfits_define_bintable_column (&theader, "I", "TRATE", "tti rate", NULL, 1.0, 0.0);
-
-  gfits_define_bintable_column (&theader, "I", "UBERCAL_DIST", "ubercal distance", NULL, 1.0, 1.0*0x80);
+  gfits_define_bintable_column (&theader, "E", "MCAL",         "zero point offset", "magnitudes", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E", "MCAL_ERR",     "zero point error",  "magnitudes", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "J", "IMAGE_ID",     "image ID", 	    NULL,         1.0, FT_BZERO_INT32);
+  gfits_define_bintable_column (&theader, "J", "PHOTOM_MAP",   "map",      	    NULL,         1.0, FT_BZERO_INT32);
+  gfits_define_bintable_column (&theader, "J", "FLAGS",        "flags",    	    NULL,         1.0, FT_BZERO_INT32);
+  gfits_define_bintable_column (&theader, "J", "TESS_ID",      "ID", 	   	    NULL,         1.0, 0.0);
+  gfits_define_bintable_column (&theader, "J", "PROJ_ID",      "ID", 	   	    NULL,         1.0, 0.0);
+  gfits_define_bintable_column (&theader, "J", "SKYCELL_ID",   "ID", 	   	    NULL,         1.0, 0.0);
+  gfits_define_bintable_column (&theader, "J", "TZERO",        "exposure start",    NULL,         1.0, FT_BZERO_INT32);
+  gfits_define_bintable_column (&theader, "I", "TRATE",        "tti rate",          NULL,         1.0, FT_BZERO_INT16);
+  gfits_define_bintable_column (&theader, "I", "UBERCAL_DIST", "ubercal distance",  NULL,         1.0, 0.0);
 
   // generate the output array that carries the data
@@ -152,6 +148,6 @@
 
   // create intermediate storage arrays
-  ALLOCATE (Mcal,      float, 	     Nimage);
-  ALLOCATE (dMcal,     float, 	     Nimage);
+  ALLOCATE (Mcal,      float, 	       Nimage);
+  ALLOCATE (dMcal,     float, 	       Nimage);
   ALLOCATE (imageID,   unsigned int,   Nimage);
   ALLOCATE (map,       unsigned int,   Nimage);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/MeanMagIO.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/MeanMagIO.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/MeanMagIO.c	(revision 37403)
@@ -60,5 +60,5 @@
   GET_COLUMN (M,    	 "MAG",          float);
   GET_COLUMN (dM,   	 "MAG_ERR",      float);
-  GET_COLUMN (Xm,   	 "MAG_CHISQ",    float);
+  GET_COLUMN (Mchisq, 	 "MAG_CHISQ",    float);
   GET_COLUMN (Nsec, 	 "NSEC",         int);
   GET_COLUMN (objID, 	 "OBJ_ID",       int);
@@ -73,19 +73,19 @@
   ALLOCATE (meanmags, MeanMag, Nrow);
   for (i = 0; i < Nrow; i++) {
-    meanmags[i].M              = M    [i];
-    meanmags[i].dM             = dM   [i];
-    meanmags[i].Xm             = Xm   [i];
-    meanmags[i].Nsec           = Nsec [i];
-    meanmags[i].objID          = objID[i];
-    meanmags[i].catID          = catID[i];
+    meanmags[i].M              = M    	[i];
+    meanmags[i].dM             = dM   	[i];
+    meanmags[i].Mchisq         = Mchisq [i];
+    meanmags[i].Nsec           = Nsec   [i];
+    meanmags[i].objID          = objID  [i];
+    meanmags[i].catID          = catID  [i];
   }
   fprintf (stderr, "loaded data for %lld objects (* filters)\n", (long long) Nrow);
 
-  free (M    );
-  free (dM   );
-  free (Xm   );
-  free (Nsec );
-  free (objID);
-  free (catID);
+  free (M     );
+  free (dM    );
+  free (Mchisq);
+  free (Nsec  );
+  free (objID );
+  free (catID );
 
   *nmeanmags = Nrow;
@@ -118,12 +118,12 @@
   gfits_define_bintable_column (&theader, "E", "MAG_ERR",   "mean magnitude error", "magnitudes", 1.0, 0.0);
   gfits_define_bintable_column (&theader, "E", "MAG_CHISQ", "mean magnitude chisq", "unitless", 1.0, 0.0);
-  gfits_define_bintable_column (&theader, "J", "NSEC",      "secfilt sequence", NULL, 1.0, 1.0*0x8000);
-  gfits_define_bintable_column (&theader, "J", "OBJ_ID",    "object ID",        NULL, 1.0, 1.0*0x8000);
-  gfits_define_bintable_column (&theader, "J", "CAT_ID",    "catalog ID",       NULL, 1.0, 1.0*0x8000);
+  gfits_define_bintable_column (&theader, "J", "NSEC",      "secfilt sequence", NULL, 1.0, FT_BZERO_INT32);
+  gfits_define_bintable_column (&theader, "J", "OBJ_ID",    "object ID",        NULL, 1.0, FT_BZERO_INT32);
+  gfits_define_bintable_column (&theader, "J", "CAT_ID",    "catalog ID",       NULL, 1.0, FT_BZERO_INT32);
 
   // generate the output array that carries the data
   gfits_create_table (&theader, &ftable);
 
-  float *M, *dM, *Xm;
+  float *M, *dM, *Mchisq;
   int *Nsec;
   unsigned int *objID, *catID;
@@ -132,5 +132,5 @@
   ALLOCATE (M,         float, 	       Nmeanmags);
   ALLOCATE (dM,        float, 	       Nmeanmags);
-  ALLOCATE (Xm,        float, 	       Nmeanmags);
+  ALLOCATE (Mchisq,    float, 	       Nmeanmags);
   ALLOCATE (Nsec,      int,            Nmeanmags);
   ALLOCATE (objID,     unsigned int,   Nmeanmags);
@@ -139,10 +139,10 @@
   // assign the storage arrays
   for (i = 0; i < Nmeanmags; i++) {
-    M    [i]   = meanmags[i].M    ;
-    dM   [i]   = meanmags[i].dM   ;
-    Xm   [i]   = meanmags[i].Xm   ;
-    Nsec [i]   = meanmags[i].Nsec ;
-    objID[i]   = meanmags[i].objID;
-    catID[i]   = meanmags[i].catID;
+    M     [i]   = meanmags[i].M     ;
+    dM    [i]   = meanmags[i].dM    ;
+    Mchisq[i]   = meanmags[i].Mchisq;
+    Nsec  [i]   = meanmags[i].Nsec  ;
+    objID [i]   = meanmags[i].objID ;
+    catID [i]   = meanmags[i].catID ;
   }
 
@@ -150,15 +150,15 @@
   gfits_set_bintable_column (&theader, &ftable, "MAG",       M,         Nmeanmags);
   gfits_set_bintable_column (&theader, &ftable, "MAG_ERR",   dM,        Nmeanmags);
-  gfits_set_bintable_column (&theader, &ftable, "MAG_CHISQ", Xm,        Nmeanmags);
+  gfits_set_bintable_column (&theader, &ftable, "MAG_CHISQ", Mchisq,    Nmeanmags);
   gfits_set_bintable_column (&theader, &ftable, "NSEC",      Nsec,      Nmeanmags);
   gfits_set_bintable_column (&theader, &ftable, "OBJ_ID",    objID,     Nmeanmags);
   gfits_set_bintable_column (&theader, &ftable, "CAT_ID",    catID,     Nmeanmags);
 
-  free (M    );
-  free (dM   );
-  free (Xm   );
-  free (Nsec );
-  free (objID);
-  free (catID);
+  free (M     );
+  free (dM    );
+  free (Mchisq);
+  free (Nsec  );
+  free (objID );
+  free (catID );
 
   FILE *f = fopen (filename, "w");
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/MosaicOps.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/MosaicOps.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/MosaicOps.c	(revision 37403)
@@ -1,4 +1,5 @@
 # include "relphot.h"
 void plot_setMcal (double *list, int Npts, StatType *stats, float clouds);
+off_t findMosaic (unsigned int *startTimes, off_t Nmosaic, unsigned int start);
 
 // see discussion in ImagesOps.c re: IDX_T
@@ -36,4 +37,18 @@
 // MosaicN_image was 'Nimlist'
 // MosaicToImage was 'imlist'
+
+void sort_times (unsigned int *T, int N) {
+
+# define SWAPFUNC(A,B){ unsigned int tmp; \
+  tmp = T[A]; T[A] = T[B]; T[B] = tmp; \
+}
+# define COMPARE(A,B)(T[A] < T[B])
+
+  OHANA_SORT (N, COMPARE, SWAPFUNC);
+
+# undef SWAPFUNC
+# undef COMPARE
+
+}
 
 /* find mosaic frames (unique time periods & photcode name matches mosaic) */
@@ -96,12 +111,12 @@
     
     /* a new mosaic, define ranges -- preserve the original values incase this image is not used */
-    mosaic[Nmosaic].start = start;
-    mosaic[Nmosaic].stop  = stop;
-    mosaic[Nmosaic].Mcal  = 0.0; // note : mosaic stores only offsets relative to the original image values
-    mosaic[Nmosaic].dMcal = 0.0; // note : at the end, mosaic.Mcal is added back to the input images
-    mosaic[Nmosaic].dMsys = 0.0;
-    mosaic[Nmosaic].Xm    = 0.0;
+    mosaic[Nmosaic].start  = start;
+    mosaic[Nmosaic].stop   = stop;
+    mosaic[Nmosaic].Mcal   = 0.0; // note : mosaic stores only offsets relative to the original image values
+    mosaic[Nmosaic].dMcal  = 0.0; // note : at the end, mosaic.Mcal is added back to the input images
+    mosaic[Nmosaic].dMsys  = 0.0;
+    mosaic[Nmosaic].Xm = 0.0;
     mosaic[Nmosaic].flags  = image[i].flags;
-    mosaic[Nmosaic].secz  = image[i].secz;
+    mosaic[Nmosaic].secz   = image[i].secz;
     mosaic[Nmosaic].photcode = GetPhotcodeEquivCodebyCode (image[i].photcode);
 
@@ -136,20 +151,4 @@
 }
 
-off_t findMosaic (unsigned int *startTimes, off_t Nmosaic, unsigned int start);
-
-void sort_times (unsigned int *T, int N) {
-
-# define SWAPFUNC(A,B){ unsigned int tmp; \
-  tmp = T[A]; T[A] = T[B]; T[B] = tmp; \
-}
-# define COMPARE(A,B)(T[A] < T[B])
-
-  OHANA_SORT (N, COMPARE, SWAPFUNC);
-
-# undef SWAPFUNC
-# undef COMPARE
-
-}
-
 /* find mosaic frames (unique time periods) (NOTE : we do NOT require matching photcodes...)
    this function will also identify the images NOT in the subset which belong to a selected mosaic
@@ -157,7 +156,6 @@
 void initMosaics (Image *subset, off_t Nsubset, Image *image, char *inSubset, off_t Nimage) {
 
-  off_t i, j, status, found, NMOSAIC, *MosaicN_IMAGE;
+  off_t i, j, found, NMOSAIC, *MosaicN_IMAGE;
   unsigned int start, stop, *startTimes, *startTimesMosaic;
-  char *pname;
 
   if (!MOSAIC_ZEROPT) return;
@@ -172,8 +170,11 @@
   // generate a list of all subset image start times
   ALLOCATE (startTimes, unsigned int, Nsubset);
+  int Nmoschip = 0;
   for (i = 0; i < Nsubset; i++) {
-    startTimes[i] = subset[i].tzero;
-  }
-  sort_times (startTimes, Nsubset);
+    if (!isGPC1chip(subset[i].photcode)) continue;
+    startTimes[Nmoschip] = subset[i].tzero;
+    Nmoschip ++;
+  }
+  sort_times (startTimes, Nmoschip);
   MARKTIME("create array of all image obstimes: %f sec\n", dtime);
   
@@ -184,9 +185,6 @@
 
   // generate a list of the unique start times (these define the mosaics)
-  for (i = 0; i < Nsubset; i++) {
-    if (startTimes[i] < startTimesMosaic[Nmosaic]) {
-      fprintf (stderr, "error?\n");
-      abort();
-    }
+  for (i = 0; i < Nmoschip; i++) {
+    myAssert (startTimes[i] >= startTimesMosaic[Nmosaic], "times out of order?");
     if (startTimes[i] == startTimesMosaic[Nmosaic]) continue;
     Nmosaic ++;
@@ -210,14 +208,14 @@
   for (i = 0; i < Nmosaic; i++) {
     /* a new mosaic, define ranges */
-    mosaic[i].start = startTimesMosaic[i];
-    mosaic[i].stop  = 0;
-    mosaic[i].Mcal  = 0.0;
-    mosaic[i].dMcal = 0.0;
-    mosaic[i].dMsys = 0.0;
-    mosaic[i].Xm    = 0.0;
-    mosaic[i].flags = 0;
-    mosaic[i].secz  = NAN;
+    mosaic[i].start    = startTimesMosaic[i];
+    mosaic[i].stop     = 0;
+    mosaic[i].Mcal     = 0.0;
+    mosaic[i].dMcal    = 0.0;
+    mosaic[i].dMsys    = 0.0;
+    mosaic[i].Xm       = 0.0;
+    mosaic[i].flags    = 0;
+    mosaic[i].secz     = NAN;
     mosaic[i].photcode = 0;
-    mosaic[i].skipCal = FALSE;
+    mosaic[i].skipCal  = FALSE;
     
     memset (&mosaic[i].coords, 0, sizeof(Coords));
@@ -238,9 +236,5 @@
     }
     
-    /* select valid mosaic images by photcode */
-    pname = GetPhotcodeNamebyCode (image[i].photcode);
-    if (!pname) continue;
-    status = strncmp (pname, MOSAICNAME, strlen (MOSAICNAME));
-    if (status) continue;
+    if (!isGPC1chip(image[i].photcode)) continue;
 
     /* set image time range */
@@ -262,11 +256,12 @@
 
   // assign each image to a mosaic
+  int Nsimple = 0;
   for (i = 0; i < Nsubset; i++) {
     ImageToMosaic[i] = -1;
 
-    /* select valid mosaic images by photcode */
-    pname = GetPhotcodeNamebyCode (subset[i].photcode);
-    status = strncmp (pname, MOSAICNAME, strlen (MOSAICNAME));
-    if (status) continue;
+    if (!isGPC1chip(subset[i].photcode)) {
+      Nsimple ++;
+      continue;
+    }
 
     start = subset[i].tzero;
@@ -299,11 +294,11 @@
       abort();
     }
-    mosaic[j].stop  = stop;
-    mosaic[j].Mcal  = 0.0;
-    mosaic[j].dMcal = 0.0;
-    mosaic[j].Xm    = 0.0;
-    mosaic[j].dMsys = subset[i].flags;
-    mosaic[j].flags = subset[i].flags;
-    mosaic[j].secz  = subset[i].secz;
+    mosaic[j].stop     = stop;
+    mosaic[j].Mcal     = 0.0;
+    mosaic[j].dMcal    = 0.0;
+    mosaic[j].Xm       = 0.0;
+    mosaic[j].dMsys    = subset[i].flags;
+    mosaic[j].flags    = subset[i].flags;
+    mosaic[j].secz     = subset[i].secz;
     mosaic[j].photcode = GetPhotcodeEquivCodebyCode (subset[i].photcode);
   }
@@ -316,17 +311,15 @@
   initMosaicGrid (subset, Nsubset);
 
-  fprintf (stderr, "matched %d images to %d mosaics\n", (int) Nsubset, (int) Nmosaic);
+  fprintf (stderr, "matched %d images to %d mosaics, %d simple chips not matched to mosaics\n", (int) (Nsubset - Nsimple), (int) Nmosaic, (int) Nsimple);
   return;
 }
 
-/* find mosaic frames (unique time periods) (NOTE : we do NOT require matching photcodes but we 
-   match images by MOSAICNAME.  this last point is weak: it forces a single camera at a time.
-   we can extend the logic to multiple cameras if we make list of MOSAICNAMES (better to assign a camera ID)
+/* find mosaic frames (unique time periods) (NOTE : require gpc1 chips, which is pretty limiting)
+   if mergeMcal is TRUE, <image.Mcal> values will be saved on Mosaic.Mcal
  */
-void makeMosaics (Image *image, off_t Nimage) {
-
-  off_t i, j, status, found, NMOSAIC, *MosaicN_IMAGE;
+void makeMosaics (Image *image, off_t Nimage, int mergeMcal) {
+
+  off_t i, j, found, NMOSAIC, *MosaicN_IMAGE;
   unsigned int start, stop, *startTimes, *startTimesMosaic;
-  char *pname;
 
   if (!MOSAIC_ZEROPT) return;
@@ -341,8 +334,11 @@
   // generate a list of all image start times
   ALLOCATE (startTimes, unsigned int, Nimage);
+  int Nmoschip = 0;
   for (i = 0; i < Nimage; i++) {
-    startTimes[i] = image[i].tzero;
-  }
-  sort_times (startTimes, Nimage);
+    if (!isGPC1chip(image[i].photcode)) continue;
+    startTimes[Nmoschip] = image[i].tzero;
+    Nmoschip ++;
+  }
+  sort_times (startTimes, Nmoschip);
   MARKTIME("create array of all image obstimes: %f sec\n", dtime);
   
@@ -353,9 +349,6 @@
 
   // generate a list of the unique start times (these define the mosaics)
-  for (i = 0; i < Nimage; i++) {
-    if (startTimes[i] < startTimesMosaic[Nmosaic]) {
-      fprintf (stderr, "error?\n");
-      abort();
-    }
+  for (i = 0; i < Nmoschip; i++) {
+    myAssert (startTimes[i] >= startTimesMosaic[Nmosaic], "times out of order?");
     if (startTimes[i] == startTimesMosaic[Nmosaic]) continue;
     Nmosaic ++;
@@ -379,14 +372,14 @@
   // init the mosaic array values
   for (i = 0; i < Nmosaic; i++) {
-    mosaic[i].start = startTimesMosaic[i];
-    mosaic[i].stop  = 0;
-    mosaic[i].Mcal  = 0.0;
-    mosaic[i].dMcal = 0.0;
-    mosaic[i].dMsys = 0.0;
-    mosaic[i].Xm    = 0.0;
-    mosaic[i].flags = 0;
-    mosaic[i].secz  = NAN;
+    mosaic[i].start    = startTimesMosaic[i];
+    mosaic[i].stop     = 0;
+    mosaic[i].Mcal     = 0.0;
+    mosaic[i].dMcal    = 0.0;
+    mosaic[i].dMsys    = 0.0;
+    mosaic[i].Xm       = 0.0;
+    mosaic[i].flags    = 0;
+    mosaic[i].secz     = NAN;
     mosaic[i].photcode = 0;
-    mosaic[i].skipCal = FALSE;
+    mosaic[i].skipCal  = FALSE;
     
     memset (&mosaic[i].coords, 0, sizeof(Coords));
@@ -401,13 +394,12 @@
 
   // assign each image to a mosaic
+  int Nsimple = 0;
   for (i = 0; i < Nimage; i++) {
     ImageToMosaic[i] = -1;
 
-    /* select valid mosaic images by photcode */
-    pname = GetPhotcodeNamebyCode (image[i].photcode);
-    if (!pname) continue;
-
-    status = strncmp (pname, MOSAICNAME, strlen (MOSAICNAME));
-    if (status) continue;
+    if (!isGPC1chip(image[i].photcode)) {
+      Nsimple ++;
+      continue;
+    }
 
     start = image[i].tzero;
@@ -440,11 +432,11 @@
       abort();
     }
-    mosaic[j].stop  = stop;
-    mosaic[j].Mcal  = 0.0;
-    mosaic[j].dMcal = 0.0;
-    mosaic[j].Xm    = 0.0;
-    mosaic[j].dMsys = image[i].flags;
-    mosaic[j].flags = image[i].flags;
-    mosaic[j].secz  = image[i].secz;
+    mosaic[j].stop     = stop;
+    mosaic[j].Mcal     = 0.0;
+    mosaic[j].dMcal    = 0.0;
+    mosaic[j].Xm       = 0.0;
+    mosaic[j].dMsys    = image[i].flags;
+    mosaic[j].flags    = image[i].flags;
+    mosaic[j].secz     = image[i].secz;
     mosaic[j].photcode = GetPhotcodeEquivCodebyCode (image[i].photcode);
   }
@@ -456,6 +448,9 @@
   free (startTimesMosaic);
 
+  if (mergeMcal) {
+    initMosaicGrid (image, Nimage);
+  }
+
   fprintf (stderr, "matched %d images to %d mosaics\n", (int) Nimage, (int) Nmosaic);
-
   return;
 }
@@ -513,5 +508,4 @@
   off_t i, j, m, NX, NY, NC, Nc;
   double R, D, Rmid, Dmid;
-  double Mcal, dMcal, Xm;
   double *Rc, *Dc;
 
@@ -523,5 +517,4 @@
     Nc = 0;
     Rmid = Dmid = NAN;
-    Mcal = dMcal = Xm = 0;
     for (j = 0; j < MosaicN_Image[i]; j++) {
       m = MosaicToImage[i][j];
@@ -563,15 +556,4 @@
 	REALLOCATE (Dc, double, NC);
       }
-
-      Mcal  += image[m].Mcal;
-      dMcal += image[m].dMcal;
-      Xm    += image[m].Xm;
-
-      // for ubercal images, we (elsewhere) keep Mcal frozen
-
-      /* we are using mosaic.Mcal, not image.Mcal. reset image.Mcal */
-      image[m].Mcal  = 0.0;
-      image[m].dMcal = NAN;
-      image[m].Xm    = NAN_S_SHORT;
     }
 
@@ -617,7 +599,7 @@
     mosaic[i].coords.pc2_1  = 0.0;
 
-    mosaic[i].Mcal  = Mcal / MosaicN_Image[i];
-    mosaic[i].dMcal = dMcal / MosaicN_Image[i];
-    mosaic[i].Xm    = Xm / MosaicN_Image[i];
+    mosaic[i].Mcal   = 0.0;
+    mosaic[i].dMcal  = 0.0;
+    mosaic[i].Xm     = 0.0;
   }
   return;
@@ -635,4 +617,6 @@
   double R, D, Rmin, Rmax, Dmin, Dmax;
   double Mcal, dMcal, Xm;
+
+  fprintf (stderr, "*** moving Mcal from image.Mcal to mosaic.Mcal ***\n");
 
   dXmax = dYmax = 0.0;
@@ -667,19 +651,19 @@
       Dmin = MIN (Dmin, D);
       Dmax = MAX (Dmax, D);
+
+      /* we are using mosaic.Mcal, not image.Mcal. reset image.Mcal */
+
+      // XXX: how does this work with UBERCAL?  We want to keep the Mcal values supplied by ubercal, but 
+      // solve for a single offset for each exposure (Mosaic.Mcal).  
+      // we also want to keep the flat-field terms for each exposure (regardless of ubercal or not)
+      // if it helps, note that ubercal uses a single zp per exposure, so the mean of those values is the same as the value
+
       Mcal  += image[m].Mcal;
       dMcal += image[m].dMcal;
       Xm    += image[m].Xm;
 
-      // XXX: how does this work with UBERCAL?  We want to keep the Mcal values supplied by ubercal, but 
-      // solve for a single offset for each exposure (Mosaic.Mcal).  
-
-      // we also want to keep the flat-field terms for each exposure (regardless of ubercal or not)
-
-      // if it helps, note that ubercal uses a single zp per exposure, so the mean of those values is the same as the value
-
-      /* we are using mosaic.Mcal, not image.Mcal. reset image.Mcal */
-      image[m].Mcal  = 0.0;
-      image[m].dMcal = NAN;
-      image[m].Xm    = NAN_S_SHORT;
+      image[m].Mcal   = 0.0;
+      image[m].dMcal  = NAN;
+      image[m].Xm     = NAN_S_SHORT;
     }
     dS /= MosaicN_Image[i];
@@ -697,7 +681,7 @@
     RD_to_XY (&dX, &dY, Rmax, Dmax, &mosaic[i].coords);
 
-    mosaic[i].Mcal  = Mcal / MosaicN_Image[i];
-    mosaic[i].dMcal = dMcal / MosaicN_Image[i];
-    mosaic[i].Xm    = Xm / MosaicN_Image[i];
+    mosaic[i].Mcal   = Mcal / MosaicN_Image[i];
+    mosaic[i].dMcal  = dMcal / MosaicN_Image[i];
+    mosaic[i].Xm     = Xm / MosaicN_Image[i];
   }
   if (!USE_GRID) return;
@@ -709,5 +693,4 @@
 }
 
-// XXX : what about mosaics with skipCal == TRUE?
 void setMcalFinal () {
 
@@ -719,6 +702,5 @@
   image = getimages (&Nimage, NULL);
 
-  // XXX I think this is OK in the ubercal context, but probably need to skip UBERCAL
-  // images? (no need to update them)
+  fprintf (stderr, "*** return Mcal from mosaic.Mcal to image.Mcal ***\n");
 
   // copy the mosaic results to the images.  set the mosaic Mcal to 0.0 since we have moved its
@@ -840,6 +822,7 @@
   mosID = ImageToMosaic[idx];
   if (mosID < 0) {
-    Image *image = getimage(idx);
-    fprintf (stderr, "unmatched image %s\n", image[0].name);
+    // Image *image = getimage(idx);
+    // fprintf (stderr, "unmatched image %s\n", image[0].name);
+    // skip measurements from simple chips (not matched to a mosaic by definition)
     return;
   }
@@ -882,6 +865,7 @@
   if (!MOSAIC_ZEROPT) return (0);
 
+  // unassigned measurements belong to simple chips
   i = MeasureToMosaic[cat][meas];
-  if (i == -1) return (NAN);
+  if (i == -1) return (0.0);
 
   if (mosaic[i].flags & IMAGE_BAD) return (NAN);  
@@ -1127,5 +1111,5 @@
 
       off_t n = catalog[c].measureT[m].averef;
-      Msys = PhotSysTiny (&catalog[c].measureT[m], &catalog[c].averageT[n], &catalog[c].secfilt[n*Nsecfilt]);
+      Msys = PhotSysTiny (&catalog[c].measureT[m], &catalog[c].averageT[n], &catalog[c].secfilt[n*Nsecfilt], MAG_CLASS_PSF);
 
       float delta = Msys - Mrel - Mcal - Mgrid + Mflat;
@@ -1164,5 +1148,5 @@
 
     off_t n = catalog[c].measureT[m].averef;
-    Msys = PhotSysTiny (&catalog[c].measureT[m], &catalog[c].averageT[n], &catalog[c].secfilt[n*Nsecfilt]);
+    Msys = PhotSysTiny (&catalog[c].measureT[m], &catalog[c].averageT[n], &catalog[c].secfilt[n*Nsecfilt], MAG_CLASS_PSF);
     if (isnan(Msys)) {
       info->Nsys++;
@@ -1239,5 +1223,5 @@
 
   if (testImage) {
-    fprintf (stderr, "%f %f  :  %d %f\n", myMosaic[0].Mcal, myMosaic[0].dMsys, myMosaic[0].Xm, pow(10.0, 0.01*myMosaic[0].Xm));
+    fprintf (stderr, "%f %f  :  %f\n", myMosaic[0].Mcal, myMosaic[0].dMsys, pow (10.0, 0.01*myMosaic[0].Xm));
   }
 
@@ -1592,4 +1576,6 @@
     if (mosaic[i].flags & IMAGE_BAD) continue;
     if (mosaic[i].skipCal) continue;
+    if (KEEP_UBERCAL && (mosaic[i].flags & ID_IMAGE_PHOTOM_UBERCAL)) continue;
+
     list[n] = mosaic[i].Mcal;
     dlist[n] = 1;
@@ -1622,4 +1608,6 @@
     if (mosaic[i].flags & IMAGE_BAD) continue;
     if (mosaic[i].skipCal) continue;
+    if (KEEP_UBERCAL && (mosaic[i].flags & ID_IMAGE_PHOTOM_UBERCAL)) continue;
+
     list[n] = mosaic[i].dMcal;
     dlist[n] = 1;
@@ -1653,4 +1641,5 @@
     if (mosaic[i].flags & IMAGE_BAD)  continue;
     if (mosaic[i].skipCal) continue;
+    if (KEEP_UBERCAL && (mosaic[i].flags & ID_IMAGE_PHOTOM_UBERCAL)) continue;
 
     N = 0;
@@ -1699,5 +1688,7 @@
     if (mosaic[i].flags & IMAGE_BAD) continue;
     if (mosaic[i].skipCal) continue;
-    list[n] = pow(10.0, 0.01*mosaic[i].Xm);
+    if (KEEP_UBERCAL && (mosaic[i].flags & ID_IMAGE_PHOTOM_UBERCAL)) continue;
+
+    list[n]  = pow (10.0, 0.01*mosaic[i].Xm);
     dlist[n] = 1;
     n++;
@@ -1782,7 +1773,6 @@
 void plot_mosaic_fields (Catalog *catalog) {
 
-  off_t i, j, m, c, N, ave, Nimage;
+  off_t i, j, m, c, N, Nimage;
   double *xlist, *ylist;
-  // double Xmin, Xmax, Ymin, Ymax;
   char string[64];
   Graphdata graphdata;
@@ -1803,6 +1793,4 @@
   for (i = 0; i < Nmosaic; i++) {
     N = 0;
-    // Xmin = Ymin = +360.0;
-    // Xmax = Ymax = -360.0;
     for (j = 0; j < N_onMosaic[i]; j++) {
       
@@ -1812,7 +1800,7 @@
       if (catalog[c].measureT[m].dbFlags & (ID_MEAS_AREA | ID_MEAS_NOCAL)) continue;
 
-      ave = catalog[c].measureT[m].averef;
-      xlist[N] = catalog[c].averageT[ave].R - catalog[c].measureT[m].dR / 3600.0;
-      ylist[N] = catalog[c].averageT[ave].D - catalog[c].measureT[m].dD / 3600.0;
+      // ave = catalog[c].measureT[m].averef;
+      xlist[N] = catalog[c].measureT[m].R;
+      ylist[N] = catalog[c].measureT[m].D;
       N++;
     }
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/Shutdown.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/Shutdown.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/Shutdown.c	(revision 37403)
@@ -23,5 +23,5 @@
   SetProtect (TRUE);
   if (db) gfits_db_close (db);
-  fprintf (stderr, "ERROR: addstar halted\n");
+  fprintf (stderr, "ERROR: relphot halted\n");
   exit (1);
 }
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/StarOps.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/StarOps.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/StarOps.c	(revision 37403)
@@ -153,4 +153,7 @@
   int i;
 
+  // fprintf (stderr, "this version of setMrel is invalid for now\n");
+  // exit (1);
+	
   int Nsecfilt = GetPhotcodeNsecfilt ();
 
@@ -407,5 +410,5 @@
 
       /* star/photcodes already calibrated */
-      if ( isSetMrelFinal && catalog[Nc].found[Nsecfilt*j+Nsec]) continue;  
+      if ( isSetMrelFinal && catalog[Nc].found_t[Nsecfilt*j+Nsec]) continue;  
       
       // skip bad stars
@@ -467,5 +470,5 @@
 
 	// skip some absurd values NAN, < 0.0, > 30.0
-	Msys = PhotSysTiny (&catalog[Nc].measureT[m], &catalog[Nc].averageT[j], &catalog[Nc].secfilt[j*Nsecfilt]);
+	Msys = PhotSysTiny (&catalog[Nc].measureT[m], &catalog[Nc].averageT[j], &catalog[Nc].secfilt[j*Nsecfilt], MAG_CLASS_PSF);
 	if (isnan(Msys)) SKIP_THIS_MEAS(Nsys);
 	if (Msys <  0.0) SKIP_THIS_MEAS(Nsys);
@@ -670,7 +673,7 @@
       liststats (list, dlist, wlist, N, &stats);
 
-      catalog[Nc].secfilt[Nsecfilt*j+Nsec].M  = stats.mean;
-      catalog[Nc].secfilt[Nsecfilt*j+Nsec].dM = stats.error;
-      catalog[Nc].secfilt[Nsecfilt*j+Nsec].Xm = (stats.Nmeas > 1) ? 100.0*log10(stats.chisq + 1e-4) : NAN_S_SHORT;
+      catalog[Nc].secfilt[Nsecfilt*j+Nsec].M      = stats.mean;
+      catalog[Nc].secfilt[Nsecfilt*j+Nsec].dM     = stats.error;
+      catalog[Nc].secfilt[Nsecfilt*j+Nsec].Mchisq = (stats.Nmeas > 1) ? stats.chisq : NAN;
 
       // when running -averages, we have no information about the images, so we cannot set this
@@ -680,5 +683,5 @@
 
       if (isSetMrelFinal) {
-	catalog[Nc].found[Nsecfilt*j+Nsec] = TRUE;
+	catalog[Nc].found_t[Nsecfilt*j+Nsec] = TRUE;
 
 	catalog[Nc].secfilt[Nsecfilt*j+Nsec].Mstdev = 1000.0*stats.sigma; // Mstdev is in millimags (not enough space for more precision)
@@ -950,6 +953,6 @@
 
   int i, j, Ndel, Nave, Ntot, mark, Ns, Nscat, Nchi, Nnan;
-  float dM, Xm;
-  double Chisq, MaxScatter, MaxChisq;
+  float dM;
+  double MaxScatter, MaxChisq;
   double *xlist, *slist, *dlist;
 
@@ -978,8 +981,7 @@
       for (j = 0; j < catalog[i].Naverage; j++) {
 	if ( catalog[i].secfilt[Nsecfilt*j+Nsec].flags & STAR_BAD ) continue;
-	Xm = catalog[i].secfilt[Nsecfilt*j+Nsec].Xm;
-	if (Xm == -1) continue;
-	Chisq = pow (10.0, 0.01*Xm);
-	xlist[Ntot] = Chisq;
+	float Mchisq = catalog[i].secfilt[Nsecfilt*j+Nsec].Mchisq;
+	if (isnan(Mchisq)) continue;
+	xlist[Ntot] = Mchisq;
 	slist[Ntot] = catalog[i].secfilt[Nsecfilt*j+Nsec].dM;
 	dlist[Ntot] = 1;
@@ -999,13 +1001,12 @@
       for (j = 0; j < catalog[i].Naverage; j++) {
 	dM = catalog[i].secfilt[Nsecfilt*j+Nsec].dM;
-	Xm = catalog[i].secfilt[Nsecfilt*j+Nsec].Xm;
-	Chisq = pow (10.0, 0.01*Xm);
-	mark = (dM > MaxScatter) || (Xm == NAN_S_SHORT) || (Chisq > MaxChisq);
+	float Mchisq = catalog[i].secfilt[Nsecfilt*j+Nsec].Mchisq;
+	mark = (dM > MaxScatter) || (isnan(Mchisq)) || (Mchisq > MaxChisq);
 	if (mark) {
 	  catalog[i].secfilt[Nsecfilt*j+Nsec].flags |= ID_STAR_POOR;
 	  Ndel ++;
-	  if (dM > MaxScatter) { Nscat ++; }
-	  if (Xm == NAN_S_SHORT) { Nnan ++; }
-	  if (Chisq > MaxChisq) { Nchi ++; }
+	  if (dM > MaxScatter)   { Nscat ++; }
+	  if (isnan(Mchisq))     { Nnan ++; }
+	  if (Mchisq > MaxChisq) { Nchi ++; }
 	} else {
 	  catalog[i].secfilt[Nsecfilt*j+Nsec].flags &= ~ID_STAR_POOR;
@@ -1072,5 +1073,5 @@
 	
 	/* on final processing, skip stars already measured */
-	if (final && catalog[i].found[Nsecfilt*j + Nsec]) continue;  
+	if (final && catalog[i].found_t[Nsecfilt*j + Nsec]) continue;  
 
 	/* skip bad stars to prevent them from becoming good (on inner sample) */
@@ -1085,4 +1086,10 @@
 	  if (ecode != thisCode) { continue; }
 
+	  // SKIP gpc1 stack data
+	  if (isGPC1stack(catalog[i].measureT[m].photcode)) continue;
+	  
+	  // SKIP gpc1 forced-warp data
+	  if (isGPC1warp(catalog[i].measureT[m].photcode)) continue;
+	  
 	  // NOTE: we do not skip MEAS_BAD because this measurement is just an internal assessment of the outliers
 	  Mcal  = getMcal  (m, i, flatcorr, catalog);
@@ -1093,5 +1100,5 @@
 	  if (isnan(Mgrid)) { Ngrid ++; continue; }
 
-	  Msys = PhotSysTiny (&catalog[i].measureT[m], &catalog[i].averageT[j], &catalog[i].secfilt[j*Nsecfilt]);
+	  Msys = PhotSysTiny (&catalog[i].measureT[m], &catalog[i].averageT[j], &catalog[i].secfilt[j*Nsecfilt], MAG_CLASS_PSF);
 	  list[N] = Msys - Mcal - Mmos - Mgrid;
 	  dlist[N] = MAX (catalog[i].measureT[m].dM, MIN_ERROR);
@@ -1130,4 +1137,10 @@
 	  if (ecode != thisCode) { continue; }
 
+	  // SKIP gpc1 stack data
+	  if (isGPC1stack(catalog[i].measureT[m].photcode)) continue;
+	  
+	  // SKIP gpc1 forced-warp data
+	  if (isGPC1warp(catalog[i].measureT[m].photcode)) continue;
+	  
 	  // NOTE: we do not skip MEAS_BAD because this measurement is just an internal assessment of the outliers
 	  Mcal  = getMcal  (m, i, flatcorr, catalog);
@@ -1138,5 +1151,5 @@
 	  if (isnan(Mgrid)) continue;
 
-	  Msys = PhotSysTiny (&catalog[i].measureT[m], &catalog[i].averageT[j], &catalog[i].secfilt[j*Nsecfilt]);
+	  Msys = PhotSysTiny (&catalog[i].measureT[m], &catalog[i].averageT[j], &catalog[i].secfilt[j*Nsecfilt], MAG_CLASS_PSF);
 	  list[N] = Msys - Mcal - Mmos - Mgrid;
 	  dlist[N] = MAX (catalog[i].measureT[m].dM, MIN_ERROR);
@@ -1233,5 +1246,5 @@
 
   off_t j, Ntot;
-  int i, n, Xm;
+  int i, n;
   double *list, *dlist;
   StatType stats;
@@ -1254,7 +1267,7 @@
       if (catalog[i].secfilt[Nsecfilt*j+Nsec].flags & STAR_BAD) continue;  
 	
-      Xm = catalog[i].secfilt[Nsecfilt*j+Nsec].Xm;
-      if (Xm == NAN_S_SHORT) continue;
-      list[n] = pow (10.0, 0.01*Xm);
+      float Mchisq = catalog[i].secfilt[Nsecfilt*j+Nsec].Mchisq;
+      if (isnan(Mchisq)) continue;
+      list[n] = Mchisq;
       dlist[n] = 1;
       n++;
@@ -1377,7 +1390,7 @@
 	if (catalog[i].secfilt[Nsecfilt*j+Nsec].flags & STAR_BAD) continue;
 	xlist[N] = catalog[i].secfilt[Nsecfilt*j+Nsec].M;
-	value    = catalog[i].secfilt[Nsecfilt*j+Nsec].Xm;
-	if (value == NAN_S_SHORT) continue;
-	ylist[N] = 0.01*value;
+	value    = catalog[i].secfilt[Nsecfilt*j+Nsec].Mchisq;
+	if (isnan(value)) continue;
+	ylist[N] = value;
 	N++;
       }
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/args.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/args.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/args.c	(revision 37403)
@@ -227,8 +227,8 @@
   }
 
-  SHOW_PARAMS = FALSE;
+  SHOW_PARAMS = TRUE;
   if ((N = get_argument (argc, argv, "-params"))) {
     remove_argument (N, &argc, argv);
-    SHOW_PARAMS = TRUE;
+    SHOW_PARAMS = FALSE;
   }
 
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/assign_images.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/assign_images.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/assign_images.c	(revision 37403)
@@ -25,7 +25,7 @@
 
   if (MOSAIC_ZEROPT) {
-    makeMosaics (image, Nimage);
-
-    // center coords and Mcal, dMcal, Xm for the mosaics
+    makeMosaics (image, Nimage, FALSE);
+
+    // center coords and Mcal, dMcal, Mchisq for the mosaics
     setMosaicCenters (image, Nimage);
     MARKTIME("set mosaic coordinates and Mcal values: %f sec\n", dtime);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/bcatalog.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/bcatalog.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/bcatalog.c	(revision 37403)
@@ -23,4 +23,7 @@
   Nmeasure = Naverage = 0;
 
+  int NmMax = 0;
+  int NmMin = catalog[0].Nmeasure;
+
   Ncode = Ntime = Ndophot = Nmag = Nsigma = Nimag = Nfew = Npsfqf = Ngalaxy = Nnan = Nbad = Npoor = 0;
 
@@ -55,4 +58,6 @@
     if (RESET) {
       int Ns;
+
+# if (0)      
       DVOSecfiltFlags secfiltBits = 
 	ID_SECF_STAR_FEW | 
@@ -66,4 +71,6 @@
 	ID_SECF_USE_UBERCAL |
 	ID_SECF_OBJ_EXT;
+# endif
+
       for (Ns = 0; Ns < Nphotcodes; Ns++) {
 
@@ -71,15 +78,18 @@
 	int Nsec = GetPhotcodeNsec(thisCode);
 
-	subcatalog[0].secfilt[Nsecfilt*Naverage+Nsec].M      = NAN;
-	subcatalog[0].secfilt[Nsecfilt*Naverage+Nsec].Map    = NAN;
-	subcatalog[0].secfilt[Nsecfilt*Naverage+Nsec].dM     = NAN;
-	subcatalog[0].secfilt[Nsecfilt*Naverage+Nsec].Mstdev = NAN_S_SHORT;
-	subcatalog[0].secfilt[Nsecfilt*Naverage+Nsec].Xm     = NAN;
-	subcatalog[0].secfilt[Nsecfilt*Naverage+Nsec].M_20   = NAN_S_SHORT;
-	subcatalog[0].secfilt[Nsecfilt*Naverage+Nsec].M_80   = NAN_S_SHORT;
-	subcatalog[0].secfilt[Nsecfilt*Naverage+Nsec].Ncode  = 0;
-	subcatalog[0].secfilt[Nsecfilt*Naverage+Nsec].Nused  = 0;
-	subcatalog[0].secfilt[Nsecfilt*Naverage+Nsec].flags &= ~secfiltBits;
-	subcatalog[0].secfilt[Nsecfilt*Naverage+Nsec].ubercalDist = 1000;
+	// fprintf (stderr, "really use dvo_secfilt_init?");
+	dvo_secfilt_init (&subcatalog[0].secfilt[Nsecfilt*Naverage+Nsec]);
+
+	// subcatalog[0].secfilt[Nsecfilt*Naverage+Nsec].M      = NAN;
+	// subcatalog[0].secfilt[Nsecfilt*Naverage+Nsec].Map    = NAN;
+	// subcatalog[0].secfilt[Nsecfilt*Naverage+Nsec].dM     = NAN;
+	// subcatalog[0].secfilt[Nsecfilt*Naverage+Nsec].Mstdev = NAN_S_SHORT;
+	// subcatalog[0].secfilt[Nsecfilt*Naverage+Nsec].Mchisq = NAN;
+	// subcatalog[0].secfilt[Nsecfilt*Naverage+Nsec].M_20   = NAN_S_SHORT;
+	// subcatalog[0].secfilt[Nsecfilt*Naverage+Nsec].M_80   = NAN_S_SHORT;
+	// subcatalog[0].secfilt[Nsecfilt*Naverage+Nsec].Ncode  = 0;
+	// subcatalog[0].secfilt[Nsecfilt*Naverage+Nsec].Nused  = 0;
+	// subcatalog[0].secfilt[Nsecfilt*Naverage+Nsec].flags &= ~secfiltBits;
+	// subcatalog[0].secfilt[Nsecfilt*Naverage+Nsec].ubercalDist = 1000;
       }
     }
@@ -136,5 +146,5 @@
 
       /* select measurements by mag limit */
-      mag = PhotCat (&catalog[0].measure[offset]);
+      mag = PhotCat (&catalog[0].measure[offset], MAG_CLASS_PSF);
       if (mag > MAG_LIM) { Nmag ++; continue; } 
 
@@ -144,5 +154,5 @@
       /* select measurements by mag limit */
       if (ImagSelect) {
-	mag = PhotInst (&catalog[0].measure[offset]);
+	mag = PhotInst (&catalog[0].measure[offset], MAG_CLASS_PSF);
 	if (mag < ImagMin) { Nimag ++; continue; }
 	if (mag > ImagMax) { Nimag ++; continue; }
@@ -180,5 +190,5 @@
       }
       myAssert (Nmeasure < NMEASURE, "realloc failure");
-    }
+    } // end of catalog.average.Nmeasure loop
 
     // skip object if it is likely to be a galaxy
@@ -205,4 +215,6 @@
       continue; 
     }
+    NmMin = MIN (Nm, NmMin);
+    NmMax = MAX (Nm, NmMax);
 
     // for w-band photometry (& other cases?) convert gri photometry
@@ -235,4 +247,11 @@
   subcatalog[0].Nsecf_mem = Naverage * catalog[0].Nsecfilt;
 
+  if (VERBOSE) {
+    fprintf (stderr, "using "OFF_T_FMT" stars ("OFF_T_FMT" measures) of "OFF_T_FMT" ("OFF_T_FMT" measures) for catalog %s, %d < Nm < %d\n", 
+	     subcatalog[0].Naverage,  subcatalog[0].Nmeasure,  catalog[0].Naverage, catalog[0].Nmeasure, catalog[0].filename, NmMin, NmMax);
+    fprintf (stderr, "rejections: %d stars have too few measures:\n   %d code, %d time, %d dophot, %d mag, %d sigma, %d imag, %d psfqf, %d Nnan, %d galaxies, %d bad, %d poor\n", 
+	     Nfew, Ncode, Ntime, Ndophot, Nmag, Nsigma, Nimag, Npsfqf, Nnan, Ngalaxy, Nbad, Npoor);
+  }
+
   // limit the total number of stars in the catalog
   if (MaxDensityUse) {
@@ -240,10 +259,4 @@
   }
 
-  if (VERBOSE) {
-    fprintf (stderr, "using "OFF_T_FMT" stars ("OFF_T_FMT" measures) of "OFF_T_FMT" for catalog %s\n", 
-	     subcatalog[0].Naverage,  subcatalog[0].Nmeasure,  i, catalog[0].filename);
-    fprintf (stderr, "rejections: %d code, %d time, %d dophot, %d mag, %d sigma, %d imag, %d few, %d psfqf, %d Nnan, %d galaxies, %d bad, %d poor\n", 
-	     Ncode, Ntime, Ndophot, Nmag, Nsigma, Nimag, Nfew, Npsfqf, Nnan, Ngalaxy, Nbad, Npoor);
-  }
   return (TRUE);
 }
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/extra.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/extra.c	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/extra.c	(revision 37403)
@@ -0,0 +1,40 @@
+# include "relphot.h"
+
+// for now (20140710) I need to identify gpc1 chips explicitly.  generalize in the future
+int isGPC1chip (int photcode) {
+
+  if ((photcode > 10000) && (photcode < 10077)) return TRUE; // g-band
+  if ((photcode > 10100) && (photcode < 10177)) return TRUE; // r-band
+  if ((photcode > 10200) && (photcode < 10277)) return TRUE; // i-band
+  if ((photcode > 10300) && (photcode < 10377)) return TRUE; // z-band
+  if ((photcode > 10400) && (photcode < 10477)) return TRUE; // y-band
+  if ((photcode > 10500) && (photcode < 10577)) return TRUE; // w-band
+
+  return FALSE;
+}
+
+// for now (20140710) I need to identify gpc1 stacks explicitly.  generalize in the future
+int isGPC1stack (int photcode) {
+
+  if (photcode == 11000) return TRUE; // g-band
+  if (photcode == 11100) return TRUE; // r-band
+  if (photcode == 11200) return TRUE; // i-band
+  if (photcode == 11300) return TRUE; // z-band
+  if (photcode == 11400) return TRUE; // y-band
+  if (photcode == 11500) return TRUE; // w-band
+
+  return FALSE;
+}
+
+// for now (20140710) I need to identify gpc1 stacks explicitly.  generalize in the future
+int isGPC1warp (int photcode) {
+
+  if (photcode == 12000) return TRUE; // g-band
+  if (photcode == 12100) return TRUE; // r-band
+  if (photcode == 12200) return TRUE; // i-band
+  if (photcode == 12300) return TRUE; // z-band
+  if (photcode == 12400) return TRUE; // y-band
+  if (photcode == 12500) return TRUE; // w-band
+
+  return FALSE;
+}
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/initialize.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/initialize.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/initialize.c	(revision 37403)
@@ -36,5 +36,14 @@
 
   if (SHOW_PARAMS) {
-    fprintf (stderr, "current parameter settings:\n");
+    int Ns;
+    fprintf (stderr, "subset selection criteria:\n");
+    fprintf (stderr, "  photcodes ");
+    for (Ns = 0; Ns < Nphotcodes; Ns++) {
+      if (Ns == Nphotcodes - 1) {
+	fprintf (stderr, "%s\n", photcodes[Ns][0].name);
+      } else {
+	fprintf (stderr, "%s, ", photcodes[Ns][0].name);
+      }
+    }
     if (TimeSelect) {
       fprintf (stderr, "TimeSelect: TRUE (%s - %s)\n", ohana_sec_to_date (TSTART), ohana_sec_to_date (TSTOP));
@@ -42,4 +51,18 @@
       fprintf (stderr, "TimeSelect: FALSE\n");
     }
+    if (DophotSelect) {
+      fprintf (stderr, "DophotSelect: TRUE (%d)\n", DophotValue);
+    } else {
+      fprintf (stderr, "DophotSelect: FALSE\n");
+    }
+    fprintf (stderr, "PSF_QF limit: 0.85 (hardwired)\n");
+
+    // fprintf (stderr, "Photom Bad Mask: 0x%08x, Photom Poor Mask: 0x%08x\n");
+
+    fprintf (stderr, "MAG_LIM: %f, SIGMA_LIM: %f\n", MAG_LIM, SIGMA_LIM);
+    fprintf (stderr, "INST_MAG_MIN: %f, INST_MAG_MAX: %f\n", ImagMin, ImagMax);
+
+    fprintf (stderr, "STAR_TOOFEW: %d\n", STAR_TOOFEW);
+
     fprintf (stderr, "VERBOSE: %d, PLOTSTUFF: %d\n", VERBOSE, PLOTSTUFF);
     fprintf (stderr, "GRID_X: %d, GRID_Y: %d, BINNING: %d == Nmx: %d, Nmy: %d\n", 
@@ -49,5 +72,4 @@
 	     (int)(RELPHOT_GRID_X/RELPHOT_GRID_BINNING), (int)(RELPHOT_GRID_Y/RELPHOT_GRID_BINNING));
 
-    fprintf (stderr, "MAG_LIM                %lf\n", MAG_LIM);
     fprintf (stderr, "STAR_SCATTER           %lf\n", STAR_SCATTER);
     fprintf (stderr, "IMAGE_SCATTER          %lf\n", IMAGE_SCATTER);
@@ -56,5 +78,4 @@
     fprintf (stderr, "GSCFILE                %s\n",  GSCFILE);
     fprintf (stderr, "CATDIR                 %s\n",  CATDIR);
-    exit (0);
   }
 
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/launch_region_hosts.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/launch_region_hosts.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/launch_region_hosts.c	(revision 37403)
@@ -22,21 +22,21 @@
   for (i = 0; i < regionHosts->Nhosts; i++) {
     char *syncfile = make_filename (CATDIR, regionHosts->hosts[i].hostname, regionHosts->hosts[i].hostID, "meanmags.sync");
-    truncate (syncfile, 0);
+    if (truncate (syncfile, 0)) fprintf (stderr, "trouble clearing syncfile %s\n", syncfile);
     free (syncfile);
 
     char *fitsfile = make_filename (CATDIR, regionHosts->hosts[i].hostname, regionHosts->hosts[i].hostID, "meanmags.fits");
-    truncate (fitsfile, 0);
+    if (truncate (fitsfile, 0)) fprintf (stderr, "trouble clearing fitsfile %s\n", fitsfile );
     free (fitsfile);
 
     char *imsyncfile = make_filename (CATDIR, regionHosts->hosts[i].hostname, regionHosts->hosts[i].hostID, "imagemags.sync");
-    truncate (imsyncfile, 0);
+    if (truncate (imsyncfile, 0)) fprintf (stderr, "trouble clearing imsyncfile %s\n", imsyncfile);
     free (imsyncfile);
 
     char *imfitsfile = make_filename (CATDIR, regionHosts->hosts[i].hostname, regionHosts->hosts[i].hostID, "imagemags.fits");
-    truncate (imfitsfile, 0);
+    if (truncate (imfitsfile, 0)) fprintf (stderr, "trouble clearing imfitsfile %s\n", imfitsfile);
     free (imfitsfile);
 
     char *loopsyncfile = make_filename (CATDIR, regionHosts->hosts[i].hostname, regionHosts->hosts[i].hostID, "loop.sync");
-    truncate (loopsyncfile, 0);
+    if (truncate (loopsyncfile, 0)) fprintf (stderr, "trouble clearing loopsyncfile %s\n", loopsyncfile);
     free (loopsyncfile);
   }
@@ -55,6 +55,15 @@
 
     char command[1024];
-    snprintf (command, 1024, "relphot %s -parallel-images %s -region-hosts %s -region-hostID %d -D CATDIR %s -region %f %f %f %f -statmode %s -D CAMERA %s -D STAR_TOOFEW %d -minerror %f", 
-	      PhotcodeList, filename, REGION_FILE, host->hostID, CATDIR, host->RminCat, host->RmaxCat, host->DminCat, host->DmaxCat, STATMODE, CAMERA, STAR_TOOFEW, MIN_ERROR);
+    snprintf (command, 1024, "relphot %s", PhotcodeList);
+    strextend (command, "-parallel-images %s", filename);
+    strextend (command, "-region-hosts %s", REGION_FILE);
+    strextend (command, "-region-hostID %d", host->hostID);
+    strextend (command, "-D CATDIR %s", CATDIR);
+    strextend (command, "-region %f %f %f %f", host->RminCat, host->RmaxCat, host->DminCat, host->DmaxCat);
+    strextend (command, "-statmode %s", STATMODE);
+    strextend (command, "-D CAMERA %s", CAMERA);
+    strextend (command, "-D STAR_TOOFEW %d", STAR_TOOFEW);
+    strextend (command, "-minerror %f", MIN_ERROR);
+    strextend (command, "-cloud-limit %f", CLOUD_TOLERANCE);
 
     if (VERBOSE)       	     strextend (command, "-v");
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/load_catalogs.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/load_catalogs.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/load_catalogs.c	(revision 37403)
@@ -12,5 +12,5 @@
 // if this function is called with a specified hostID, then only the fraction of the
 // database hosted by that hostID is loaded
-Catalog *load_catalogs (SkyList *skylist, int *Ncatalog, int hostID, char *hostpath) {
+Catalog *load_catalogs (SkyList *skylist, int *Ncatalog, int hostID, char *hostpath, char *syncfile) {
 
   off_t i, Nmeas, Nstar, Nmeas_total, Nstar_total;
@@ -19,5 +19,5 @@
   // XXX need to decide how to determine PARALLEL mode...
   if (PARALLEL && !hostID) {
-    catalog = load_catalogs_parallel (skylist, Ncatalog);
+    catalog = load_catalogs_parallel (skylist, Ncatalog, syncfile);
     return catalog;
   }
@@ -92,4 +92,10 @@
   // in regular relphot, we shutdown here; in relphot_client, we generate and return an empty table (for consistency)
 
+  // if we are running with parallel_images but not a parallel database, we need to
+  // release the lock so the next image host can proceed
+  if (!hostID && syncfile) {
+    update_sync_file (syncfile, 1);
+  }
+
   // XXX consider only returning the populated catalogs
   *Ncatalog = skylist[0].Nregions;
@@ -105,5 +111,5 @@
 // CATDIR is supplied globally
 # define DEBUG 1
-Catalog *load_catalogs_parallel (SkyList *sky, int *Ncatalog) {
+Catalog *load_catalogs_parallel (SkyList *sky, int *Ncatalog, char *syncfile) {
 
   char uniquer[12];
@@ -206,4 +212,17 @@
   }
 
+  // update syncfile here (save lots of I/O time):
+
+  // at this point, the remote relastro_client jobs are done loading their data.  in a
+  // parallel_images mode, the next image host can be launched while this image host now
+  // reads that
+
+  // NOTE: if I let all hosts load blindly, I saturate the data clients with too many
+  // relphot_client requests.  I need to have the master mediate this.  the master
+  // will not launch the next remote job until this one says it is done
+  if (syncfile) {
+    update_sync_file (syncfile, 1);
+  }
+
   // each host generates a BrightCatalog structure, with the measure, average, etc value
   // loaded into a single set of arrays (of MeasureTiny, AverageTiny, Secfilt).  I need to
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/plot_scatter.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/plot_scatter.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/plot_scatter.c	(revision 37403)
@@ -51,6 +51,6 @@
 
 		xlist[N] = Mrel;
-		ylist[N] = PhotSysTiny (&catalog[i].measureT[m], &catalog[i].averageT[j], &catalog[i].secfilt[j*Nsecfilt]) - Mcal - Mmos - Mgrid - Mrel;
-		ilist[N] = PhotInstTiny (&catalog[i].measureT[m]);
+		ylist[N] = PhotSysTiny (&catalog[i].measureT[m], &catalog[i].averageT[j], &catalog[i].secfilt[j*Nsecfilt], MAG_CLASS_PSF) - Mcal - Mmos - Mgrid - Mrel;
+		ilist[N] = PhotInstTiny (&catalog[i].measureT[m], MAG_CLASS_PSF);
 		N++;
 	    }
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/relphot_client.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/relphot_client.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/relphot_client.c	(revision 37403)
@@ -39,5 +39,5 @@
     case MODE_LOAD: {
       int Ncatalog;
-      Catalog *catalog = load_catalogs (skylist, &Ncatalog, HOST_ID, HOSTDIR);
+      Catalog *catalog = load_catalogs (skylist, &Ncatalog, HOST_ID, HOSTDIR, NULL);
       if (!catalog) {
 	  fprintf (stderr, "ERROR loading catalogs from %s\n", CATDIR);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/relphot_images.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/relphot_images.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/relphot_images.c	(revision 37403)
@@ -52,5 +52,5 @@
   if (NLOOP > 0) {
     /* load catalog data from region files (hostID is 0 since we are not a client */
-    catalog = load_catalogs (skylist, &Ncatalog, 0, NULL);
+    catalog = load_catalogs (skylist, &Ncatalog, 0, NULL, NULL);
     MARKTIME("-- load catalog data: %f sec\n", dtime);
   
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/relphot_parallel_images.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/relphot_parallel_images.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/relphot_parallel_images.c	(revision 37403)
@@ -38,6 +38,5 @@
   // unlink (IMAGE_TABLE); // XXX a bit risky, add some protection?
 
-  // XXX need to deal with mosaic vs image...
-  makeMosaics (image, Nimage);
+  makeMosaics (image, Nimage, TRUE);
 
   initImages (image, NULL, Nimage);
@@ -56,14 +55,11 @@
 
   /* load catalog data from region files (hostID is 0 since we are not a client */
-  catalog = load_catalogs (skylist, &Ncatalog, 0, NULL);
+  char *syncfile = make_filename (CATDIR, regionHosts->hosts[myHost].hostname, REGION_HOST_ID, "loadcat.sync");
+  catalog = load_catalogs (skylist, &Ncatalog, 0, NULL, syncfile);
   MARKTIME("-- load catalog data: %f sec\n", dtime);
+  free (syncfile);
+
   client_logger_message ("loaded catalog data\n");
 
-  // NOTE: if I let all hosts load blindly, I saturate the data clients with too many
-  // relphot_client requests.  I need to have the master mediate this.  the master
-  // will not launch the next remote job until this one says it is done
-  char *syncfile = make_filename (CATDIR, regionHosts->hosts[myHost].hostname, REGION_HOST_ID, "loadcat.sync");
-  update_sync_file (syncfile, 1);
-  
   // generate tables go from catID,objID -> catSeq,objSeq
   indexCatalogs (catalog, Ncatalog);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/relphot_parallel_regions.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/relphot_parallel_regions.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/relphot_parallel_regions.c	(revision 37403)
@@ -1,3 +1,4 @@
 # include "relphot.h"
+int save_images_backup (FITS_DB *db);
 
 int relphot_parallel_regions () {
@@ -63,4 +64,7 @@
   SkyList *skylist = SkyListByBounds (sky, -1, regionHosts->Rmin, regionHosts->Rmax, regionHosts->Dmin, regionHosts->Dmax);
 
+  // I have to save a copy because dvo_image_save and _unlock swap and free the data
+  save_images_backup (&db);
+
   /* update catalogs (in parallel) */
   reload_catalogs (skylist, flatcorr, 0, NULL);
@@ -74,2 +78,37 @@
 }
 
+int save_images_backup (FITS_DB *db) {
+
+  FITS_DB dbX;
+  char filename[1024];
+
+  INITTIME;
+
+  gfits_db_init (&dbX);
+  dbX.lockstate = LCK_XCLD;
+  dbX.timeout   = 60.0;
+  dbX.mode      = db->mode;
+  dbX.format    = db->format;
+
+  snprintf (filename, 1024, "%s.bck", ImageCat);
+  if (!gfits_db_lock (&dbX, filename)) {
+    fprintf (stderr, "can't lock backup image image catalog\n");
+    return (FALSE);
+  }
+    
+  // copy Images.dat data (all or only the subset / vtable elements?)  I think I need to dump
+  // the entire Image table, but with the updates in place I think this says: re-work the
+  // ftable/vtable usage in this program to be more sensible...
+  gfits_copy_header (&db->header,  &dbX.header);
+  gfits_copy_matrix (&db->matrix,  &dbX.matrix);
+  gfits_copy_header (&db->theader, &dbX.theader);
+  gfits_copy_ftable (&db->ftable,  &dbX.ftable);
+
+  dbX.ftable.header = &dbX.theader;
+
+  dvo_image_save (&dbX, VERBOSE);
+  dvo_image_unlock (&dbX); 
+  MARKTIME("-- save Image.dat.bck: %f sec\n", dtime);
+
+  return TRUE;
+}
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/setExclusions.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/setExclusions.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/setExclusions.c	(revision 37403)
@@ -35,6 +35,6 @@
 	/* select measurements by mag limit */
 	if (AreaSelect) {
-	  r = catalog[i].averageT[j].R + catalog[i].measureT[m].dR / 3600.0;
-	  d = catalog[i].averageT[j].D + catalog[i].measureT[m].dD / 3600.0;
+	  r = catalog[i].measureT[m].R;
+	  d = catalog[i].measureT[m].D;
 	  if ((coords = getCoords (m, i)) == NULL) goto markbad;
 	  RD_to_XY (&x, &y, r, d, coords);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/setMrelCatalog.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/setMrelCatalog.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/setMrelCatalog.c	(revision 37403)
@@ -1,3 +1,4 @@
 # include "relphot.h"
+# define UBERCAL_WEIGHT 100.0
 
 # define SKIP_THIS_MEAS(REASON) {				\
@@ -13,4 +14,9 @@
     continue; }
 
+static float MagToFlux (float Mag) {
+  float Flux = pow(10.0, -0.4*(Mag));
+  return (Flux);
+}
+
 int print_measure_set_alt (Average *average, SecFilt *secfilt, Measure *measure) {
 
@@ -29,4 +35,6 @@
   return (TRUE);
 }
+
+int setMrelAverageForcedWarp (off_t measureOffset, int cat, int pass, SetMrelInfo *results, Average *average, SecFilt *secfilt, Measure *measure, off_t *found);
 
 int setMrel_catalog_alt (Catalog *catalog, int Nc, int pass, FlatCorrectionTable *flatcorr, SetMrelInfo *results, int Nsecfilt) {
@@ -42,8 +50,8 @@
   int isSetMrelFinal = (pass >= 0);
 
-  char *primaryCell = NULL;
-  if (isSetMrelFinal) {
-    ALLOCATE (primaryCell, char, DVO_MAX_PATH);
-  }
+  // XX char *primaryCell = NULL;
+  // XX if (isSetMrelFinal) {
+  // XX   ALLOCATE (primaryCell, char, DVO_MAX_PATH);
+  // XX }
 
   for (j = 0; j < catalog[Nc].Naverage; j++) {
@@ -52,16 +60,23 @@
     Average *average = catalog[Nc].average ? &catalog[Nc].average[j] : NULL;
     Measure *measure = catalog[Nc].measure ? &catalog[Nc].measure[m] : NULL;
-    setMrelAverageExposure (m, Nc, pass, flatcorr, results, average, &catalog[Nc].averageT[j], &catalog[Nc].secfilt[j*Nsecfilt], measure, &catalog[Nc].measureT[m], &catalog[Nc].found[Nsecfilt*j]);
+    setMrelAverageExposure (m, Nc, pass, flatcorr, results, average, &catalog[Nc].averageT[j], &catalog[Nc].secfilt[j*Nsecfilt], measure, &catalog[Nc].measureT[m], &catalog[Nc].found_t[Nsecfilt*j]);
 
     // only apply Stack operation on setMrelFinal in first pass 
     if (isSetMrelFinal && (pass == 0)) {
-      setMrelAverageStack (m, Nc, flatcorr, results, &catalog[Nc].average[j], &catalog[Nc].secfilt[j*Nsecfilt], &catalog[Nc].measure[m], primaryCell);
+      setMrelAverageStack (m, Nc, flatcorr, results, &catalog[Nc].average[j], &catalog[Nc].secfilt[j*Nsecfilt], &catalog[Nc].measure[m]);
       setGlobalObjStats (&catalog[Nc].average[j], &catalog[Nc].measure[m]);
     }
-  }
-  if (primaryCell) free (primaryCell);
+
+    // only measure force-warp mean values if issetMrelFinal (make it optional?)
+    if (isSetMrelFinal) {
+      setMrelAverageForcedWarp (m, Nc, pass, results, &catalog[Nc].average[j], &catalog[Nc].secfilt[j*Nsecfilt], &catalog[Nc].measure[m], &catalog[Nc].foundWarp_t[Nsecfilt*j]);
+      setGlobalObjStats (&catalog[Nc].average[j], &catalog[Nc].measure[m]);
+    }
+  }
+  // if (primaryCell) free (primaryCell);
   return (TRUE);
 }
 
+// set mean of chip measurements (selected by photcode range for now):
 int setMrelAverageExposure (off_t measureOffset, int cat, int pass, FlatCorrectionTable *flatcorr, SetMrelInfo *results, Average *average, AverageTiny *averageT, SecFilt *secfilt, Measure *measure, MeasureTiny *measureT, off_t *found) {
 
@@ -132,4 +147,7 @@
     off_t meas = measureOffset;
 
+    float psfQfMax = 0.0;
+    float psfQfPerfMax = 0.0;
+
     int Nap = 0;
     int Npsf = 0;
@@ -144,6 +162,15 @@
 
       // are we a PS1 exposure photcode?
-      if ((measureT[k].photcode >= 10000) && (measureT[k].photcode <= 10500)) {
-	NexpPS1 ++;
+      if (isGPC1chip(measureT[k].photcode)) NexpPS1 ++;
+
+      // SKIP gpc1 stack data
+      if (isGPC1stack(measureT[k].photcode)) continue;
+
+      // SKIP gpc1 forced-warp data
+      if (isGPC1warp(measureT[k].photcode)) continue;
+
+      if (isSetMrelFinal) {
+	if (measure[k].psfQF     > psfQfMax)     psfQfMax     = measure[k].psfQF;
+	if (measure[k].psfQFperf > psfQfPerfMax) psfQfPerfMax = measure[k].psfQFperf;
       }
 
@@ -166,5 +193,5 @@
 
       // skip some absurd values NAN, < 0.0, > 30.0
-      Msys = PhotSysTiny (&measureT[k], &averageT[0], &secfilt[0]);
+      Msys = PhotSysTiny (&measureT[k], &averageT[0], &secfilt[0], MAG_CLASS_PSF);
       if (isnan(Msys)) SKIP_THIS_MEAS(Nsys);
       if (Msys <  0.0) SKIP_THIS_MEAS(Nsys);
@@ -197,9 +224,4 @@
 	  }
 	  havePS1 = TRUE;
-	}
-
-	// gpc1 stack data
-	if ((measure[k].photcode >= 11000) && (measure[k].photcode <= 11400)) {
-	  continue;
 	}
 
@@ -255,17 +277,17 @@
 
 	// Map (Maplist) and Mkron (Mkronlist,dkronlist) are used to calculate mean mags per filter
-	float Map = PhotAperCat (&measure[k]);
+	float Map = PhotCat (&measure[k], MAG_CLASS_APER);
 	if (!isnan(Map)) {
 	    Maplist[Nap] = Map - Mcal - Mmos - Mgrid;
-	    daplist[Nap] = dMpsf;
-	    waplist[Nap] = isUbercal ? 10.0 : 1.0;
+	    daplist[Nap] = dMpsf;// XXX check on this...
+	    waplist[Nap] = isUbercal ? UBERCAL_WEIGHT : 1.0;
 	    Nap ++;
 	}
 
-	float Mkron = PhotKronCat (&measure[k]);
+	float Mkron = PhotCat (&measure[k], MAG_CLASS_KRON);
 	if (!isnan(Mkron)) {
 	  Mkronlist[Nkron] = Mkron - Mcal - Mmos - Mgrid;
 	  dkronlist[Nkron] = measure[k].dMkron;
-	  wkronlist[Nkron] = isUbercal ? 10.0 : 1.0;
+	  wkronlist[Nkron] = isUbercal ? UBERCAL_WEIGHT : 1.0;
 	  Nkron ++;
 	}
@@ -280,5 +302,5 @@
       Mpsflist[Npsf] = Msys - Mcal - Mmos - Mgrid;
       dpsflist[Npsf] = dMpsf;
-      wpsflist[Npsf] = isUbercal ? 10.0 : 1.0;
+      wpsflist[Npsf] = isUbercal ? UBERCAL_WEIGHT : 1.0;
 
       // NOTE: 
@@ -293,5 +315,5 @@
       if (refPhotcode) {
 	if (code->code == refPhotcode->code) {
-	  wpsflist[Npsf] = 100.0;
+	  wpsflist[Npsf] = UBERCAL_WEIGHT;
 	}
       }
@@ -304,5 +326,5 @@
     if (isSetMrelFinal && (pass == 0)) {
       if ((thisCode < 6) || (thisCode == 9)) {
-	secfilt[Nsec].Ncode = NexpPS1;
+	secfilt[Nsec].Ncode = NexpPS1; 
       } else {
 	secfilt[Nsec].Ncode = Ncode; // 2MASS data if it exists
@@ -334,7 +356,7 @@
     liststats (Mpsflist, dpsflist, wpsflist, Npsf, psfstats);
 
-    secfilt[Nsec].M  = psfstats->mean;
-    secfilt[Nsec].dM = psfstats->error;
-    secfilt[Nsec].Xm = (psfstats->Nmeas > 1) ? 100.0*log10(psfstats->chisq + 1e-4) : NAN_S_SHORT;
+    secfilt[Nsec].M  	 = psfstats->mean;
+    secfilt[Nsec].dM 	 = psfstats->error;
+    secfilt[Nsec].Mchisq = (psfstats->Nmeas > 1) ? psfstats->chisq : NAN;
 
     // when running -averages, we have no information about the images, so we cannot set this
@@ -346,18 +368,26 @@
       found[Nsec] = TRUE;
 
-      secfilt[Nsec].Mstdev = 1000.0*psfstats->sigma; // Mstdev is in millimags (not enough space for more precision)
+      secfilt[Nsec].Mstdev = psfstats->sigma; // Mstdev is in millimags (not enough space for more precision)
       // secfilt[Nsec].Ncode = Ncode;
       secfilt[Nsec].Nused = psfstats->Nmeas;
 
-      secfilt[Nsec].M_80 = 1000 * psfstats->Upper80;
-      secfilt[Nsec].M_20 = 1000 * psfstats->Lower20;
+      secfilt[Nsec].Mmax = psfstats->max;
+      secfilt[Nsec].Mmin = psfstats->min;
+
+      secfilt[Nsec].psfQfMax     = psfQfMax;
+      secfilt[Nsec].psfQfPerfMax = psfQfPerfMax;
 
       // NOTE : use the modified weight for apmags as well as psf mags
       liststats (Maplist, daplist, waplist, Nap, apstats);
       secfilt[Nsec].Map  = Nap > 0 ? apstats->mean : NAN; 
+      secfilt[Nsec].dMap  = Nap > 0 ? apstats->error : NAN; 
+      secfilt[Nsec].sMap  = Nap > 0 ? apstats->sigma : NAN; 
+      secfilt[Nsec].NusedAp  = Nap;
 
       liststats (Mkronlist, dkronlist, wkronlist, Nkron, kronstats);
       secfilt[Nsec].Mkron  = Nkron > 0 ? kronstats->mean  : NAN; 
       secfilt[Nsec].dMkron = Nkron > 0 ? kronstats->error : NAN; 
+      secfilt[Nsec].sMkron = Nkron > 0 ? kronstats->sigma : NAN; 
+      secfilt[Nsec].NusedKron  = Nkron;
 
       // NOTE: for 2MASS measurements, Next should be 1, as should N
@@ -422,9 +452,13 @@
 
 // only apply Stack operation on setMrelFinal in first pass 
-int setMrelAverageStack (off_t measureOffset, int cat, FlatCorrectionTable *flatcorr, SetMrelInfo *results, Average *average, SecFilt *secfilt, Measure *measure, char *primaryCell) {
-
-  off_t k, ID;
-
-  float Msys = 0, Mcal= 0, Mmos = 0, Mgrid = 0;
+// this function has 3 goals, not to be confused:
+// 1) find and mark the PRIMARY detections (regardless of the quality of the detection)
+// 2) select the BEST detections per filter (regardless of PRIMARY)
+// 3) apply the zero point and AB->Jy transformations
+int setMrelAverageStack (off_t measureOffset, int cat, FlatCorrectionTable *flatcorr, SetMrelInfo *results, Average *average, SecFilt *secfilt, Measure *measure) {
+
+  off_t k;
+
+  float Mcal= 0, Mmos = 0, Mgrid = 0, Finst = 0;
 
   // set the primary projection cell and skycell for this coordinate
@@ -434,4 +468,8 @@
   get_tess_ids(&tessID, &projectID, &skycellID, average[0].R, average[0].D);
 
+  average[0].tessID       = tessID;
+  average[0].projectionID = projectID;
+  average[0].skycellID    = skycellID;
+
   int NstackGood = 0;
   int NstackSuspect = 0;
@@ -448,18 +486,20 @@
     int haveStack = FALSE;
 
-    // need to find the measurement closest to the center of its skycell, as well as the
-    // closest for the subset of primary projection cells
-
-    float stackCenterOffsetMin = 1e9;
-    off_t stackCenterMeasureMin = -1;
-
-    float stackPrimaryOffsetMin = 1e9;
-    off_t stackPrimaryMeasureMin = -1;
+    float psfQFbest = 0.0;
+
+    off_t stackBestMeasure = -1;
+    off_t stackPrimaryMeasure = -1;
 
     int isBad = FALSE;
     int isSuspect = FALSE;
 
+    int Nstack = 0; // number for this photcode
+    int NstackDet = 0; // number for this photcode
+
     off_t meas = measureOffset;
     for (k = 0; k < average[0].Nmeasure; k++, meas++) {
+
+      // only examine gpc1 stack data
+      if (!isGPC1stack(measure[k].photcode)) continue;
 
       // skip measurements that do not match the current photcode
@@ -468,18 +508,35 @@
       if (code->equiv != thisCode) { continue; }
 
+      Nstack ++;
+      if ((measure[k].photFlags2 & 0x00000004) == 0) NstackDet ++;
+
       // clear this bit for all measurements
       measure[k].dbFlags &= ~ID_MEAS_STACK_PRIMARY;
-
-      // only examine gpc1 stack data
-      // XXX this is absurdly hardwired (along with several photcode tests)
-      if (measure[k].photcode < 11000) continue;
-      if (measure[k].photcode > 11400) continue;
+      measure[k].dbFlags &= ~ID_MEAS_STACK_PHOT_SRC;
 
       haveStack = TRUE;
       haveStackObject = TRUE;
       
+      // match measurement to its image (this is just a check, right?)
+      if (getImageEntry (meas, cat) < 0) {
+	fprintf (stderr, "*** warning : this should be impossible\n");
+	abort();
+	continue;
+      }
+
+      // find the PRIMARY measurement
+
+      // if we request the primary (USE_TREE_FOR_PRIMARY), this is true if the measurement is from the 
+      // primary skycell for this position
+      if (MatchImageSkycellID (meas, cat, tessID, projectID, skycellID)) {
+	stackPrimaryMeasure = k;
+	measure[k].dbFlags |= ID_MEAS_STACK_PRIMARY;
+	secfilt[Nsec].stackPrmryOff = meas;
+      }
+
+      // now choose the BEST measurements (may also be PRIMARY)
+
       if (measure[k].dbFlags & MEAS_BAD) SKIP_THIS_MEAS_STACK(Nbad); 
 
-      if (getImageEntry (meas, cat) < 0) continue;
       // measurements without an image are either external reference photometry or
       // data for which the associated image has not been loaded (probably because of
@@ -493,26 +550,11 @@
       if (isnan(Mgrid)) SKIP_THIS_MEAS_STACK(Ngrid);
 
-      Msys = PhotSys (&measure[k], &average[0], &secfilt[0]);
-      if (isnan(Msys)) SKIP_THIS_MEAS_STACK(Nsys);
-
-      unsigned int stackImageID;
-
-      // which stack image should we use for the mean value?
-      // if we request the primary (USE_TREE_FOR_PRIMARY), then find the min distances for data from the primary cell
-      if (MatchImageSkycellID (meas, cat, tessID, projectID, skycellID)) {
-	float stackPrimaryOffset = getCenterOffset (meas, cat, &measure[k], &stackImageID);
-	if (stackPrimaryOffset < stackPrimaryOffsetMin) {
-	  stackPrimaryOffsetMin = stackPrimaryOffset;
-	  // stackPrimaryIDmin = stackImageID;
-	  stackPrimaryMeasureMin = k;
-	}
-      }
-
-      // get the center distance for the generic case:
-      float stackCenterOffset = getCenterOffset (meas, cat, &measure[k], &stackImageID);
-      if (stackCenterOffset < stackCenterOffsetMin) {
-	stackCenterOffsetMin = stackCenterOffset;
-	// stackCenterIDmin = stackImageID;
-	stackCenterMeasureMin = k;
+      // NOTE: negative and insignificant vlues values are allowed, but not NAN flux values
+      Finst = PhotFluxInst (&measure[k], MAG_CLASS_PSF);
+      if (isnan(Finst)) SKIP_THIS_MEAS_STACK(Ninst);
+
+      if (measure[k].psfQFperf > psfQFbest) {
+	psfQFbest = measure[k].psfQFperf;
+	stackBestMeasure = k;
       }
 
@@ -537,11 +579,10 @@
 
     // measurements which are bad will not have a valid stack entry and are skipped
-    k = (stackPrimaryMeasureMin >= 0) ? stackPrimaryMeasureMin : stackCenterMeasureMin;
+    k = (stackBestMeasure >= 0) ? stackBestMeasure : stackPrimaryMeasure;
     if (k < 0) continue;
-
 
     // we are now populating stackDetectID not stack Image ID in secfilt
     // ID = (stackPrimaryMeasureMin >= 0) ? stackPrimaryIDmin      : stackCenterIDmin;
-    ID = measure[k].extID; // for the stack, this is the stackDetectID
+    // ID = measure[k].extID; // for the stack, this is the stackDetectID
 
     // get the zero point for the selected image
@@ -581,14 +622,24 @@
 
     // need to put in AB mag factor to get to Janskies (or uJy?)
-    secfilt[Nsec].FluxPSF   = zpFactor * measure[k].FluxPSF;  
-    secfilt[Nsec].dFluxPSF  = zpFactor * measure[k].dFluxPSF; 
-    secfilt[Nsec].FluxKron  = zpFactor * measure[k].FluxKron; 
-    secfilt[Nsec].dFluxKron = zpFactor * measure[k].dFluxKron;
-
-    secfilt[Nsec].stackDetectID = ID;
-
+    secfilt[Nsec].FpsfStk   = zpFactor * measure[k].FluxPSF;  
+    secfilt[Nsec].dFpsfStk  = zpFactor * measure[k].dFluxPSF; 
+    secfilt[Nsec].FkronStk  = zpFactor * measure[k].FluxKron; 
+    secfilt[Nsec].dFkronStk = zpFactor * measure[k].dFluxKron;
+    secfilt[Nsec].FapStk    = zpFactor * measure[k].FluxAp;
+    secfilt[Nsec].dFapStk   = zpFactor * measure[k].dFluxAp;
+
+    // Jy to AB mags
+    secfilt[Nsec].MpsfStk   = (measure[k].FluxPSF  > 0.0) ? 8.9 - 2.5*log10(secfilt[Nsec].FpsfStk) : NAN;
+    secfilt[Nsec].MkronStk  = (measure[k].FluxKron > 0.0) ? 8.9 - 2.5*log10(secfilt[Nsec].FkronStk) : NAN;
+    secfilt[Nsec].MapStk    = (measure[k].FluxAp   > 0.0) ? 8.9 - 2.5*log10(secfilt[Nsec].FapStk) : NAN;
+
+    secfilt[Nsec].stackBestOff = k + measureOffset;
+
+    secfilt[Nsec].Nstack    = Nstack;
+    secfilt[Nsec].NstackDet = NstackDet;
+
+    // this is the measurement used by secfilt[]
     measure[k].dbFlags |= ID_MEAS_STACK_PHOT_SRC;
-    if (stackPrimaryMeasureMin >= 0) {
-      measure[k].dbFlags |= ID_MEAS_STACK_PRIMARY;
+    if (k == stackPrimaryMeasure) {
       secfilt[Nsec].flags |= ID_SECF_STACK_PRIMARY;
     }
@@ -607,4 +658,182 @@
 }
 
+# undef SKIP_THIS_MEAS
+# define SKIP_THIS_MEAS(REASON) {				\
+    measure[k].dbFlags |= ID_MEAS_SKIP_PHOTOM;	\
+    results->REASON ++;						\
+    continue; }
+
+// set mean of forced-warp measurements (selected by photcode range for now):
+// somewhat simplified relative to chip-photometry:
+// * no grid, no mosaic, no 2MASS, no SYNTH, no Ubercal, no flatcorr
+int setMrelAverageForcedWarp (off_t measureOffset, int cat, int pass, SetMrelInfo *results, Average *average, SecFilt *secfilt, Measure *measure, off_t *found) {
+
+  off_t k;
+  float Mcal= 0;
+
+  // we are measuring means for 3 types of FLUXes: psf, ap, kron.  I am using the psf mag
+  // error for the ap mags, but krons have their own errors.  it is an open question if I
+  // should be doing weighted or unweighted fits (this is a user option)
+  double *Fpsflist  = results->Mpsflist;
+  double *dpsflist  = results->dpsflist;
+  double *wpsflist  = results->wpsflist;
+
+  double *Faplist   = results->Maplist;
+  double *daplist   = results->daplist;
+  double *waplist   = results->waplist;
+
+  double *Fkronlist = results->Mkronlist;
+  double *dkronlist = results->dkronlist;
+  double *wkronlist = results->wkronlist;
+
+  StatType *psfstats  = &results->psfstats;
+  StatType *apstats   = &results->apstats;
+  StatType *kronstats = &results->kronstats;
+
+  // option for a test print
+  if ((average[0].objID == 0xd6e) && (average[0].catID == 0x4984)) {
+    fprintf (stderr, "test obj\n");
+    print_measure_set_alt (average, secfilt, measure);
+  }
+
+  int Ns;
+  for (Ns = 0; Ns < Nphotcodes; Ns++) {
+
+    int thisCode = photcodes[Ns][0].code;
+    int Nsec = GetPhotcodeNsec(thisCode);
+
+    /* calculate the average mag in this SEC photcode for a single star */
+
+    /* star/photcodes already calibrated */
+    if (found[Nsec]) continue;  
+      
+    // I need to restrict the measurements coming only from the same skycell as the secfilt values
+    // if we cannot make that association, skip this set of warps
+    int stkTessID, stkProjID, stkSkycellID;
+    if (!FindImageSkycellID (secfilt[Nsec].stackBestOff, cat, &stkTessID, &stkProjID, &stkSkycellID)) continue;
+
+    off_t meas = measureOffset;
+
+    int Nap = 0;
+    int Npsf = 0;
+    int Nkron = 0;
+
+    int Nwarp = 0;
+    int NwarpGood = 0;
+    for (k = 0; k < average[0].Nmeasure; k++, meas++) {
+
+      // only examine gpc1 forced-warp data
+      if (!isGPC1warp(measure[k].photcode)) continue;
+
+      // skip measurements that do not match the current photcode
+      PhotCode *code = GetPhotcodebyCode (measure[k].photcode);
+      if (!code) continue;
+      if (code->equiv != thisCode) { continue; }
+
+      Nwarp ++;
+      if (measure[k].psfQFperf > 0.85) NwarpGood ++;
+
+      measure[k].dbFlags &= ~ID_MEAS_WARP_USED;
+
+      if (!MatchImageSkycellID (meas, cat, stkTessID, stkProjID, stkSkycellID)) continue;
+
+      if (measure[k].dbFlags & MEAS_BAD) SKIP_THIS_MEAS(Nbad); 
+
+      if (getImageEntry (meas, cat) < 0) {
+	// measurements without an image are either external reference photometry or
+	// data for which the associated image has not been loaded (probably because of
+	// overlaps).  Msys + measure.Mcal is our best guess of the true magnitude
+	Mcal = measure[k].Mcal; // check that this is zero for loaded REF value
+      } else {
+	// use getMcal not getMcal_alt?
+	Mcal  = getMcal_alt (meas, cat, NULL, measure[k].Xccd, measure[k].Yccd);
+	// Mcal  = getMcal (meas, cat);
+	if (isnan(Mcal))  SKIP_THIS_MEAS(Ncal);
+      }
+      float Fcal = MagToFlux(-Mcal);
+
+      // in the calculations below, 
+      // ...list gives the error per measurement, wlist gives the weight
+      // we can modify the error and weight in a few ways:
+      // 1) MIN_ERROR guarantees a floor
+      // 2) photomErrSys is added in quadrature as a sytematic error, set per photcode
+
+      // skip some absurd values NAN
+      // NOTE : I am using PhotCat not PhotSys for now since GPC1 chip-to-chip color terms
+      // are small (and not measured)
+      float Fpsf = PhotFluxCat (&measure[k], MAG_CLASS_PSF);
+      if (isnan(Fpsf)) SKIP_THIS_MEAS(Nsys);
+      // if (Msys <  0.0) SKIP_THIS_MEAS(Nsys);
+      // if (Msys > 30.0) SKIP_THIS_MEAS(Nsys);
+
+      float dFpsf = PhotFluxCatErr (&measure[k], MAG_CLASS_PSF);
+      if (isnan(dFpsf)) SKIP_THIS_MEAS (Nsys);
+
+      int isBad = (measure[k].psfQF < 0.85);
+      isBad |= isnan(measure[k].psfQF);
+      if (isBad) SKIP_THIS_MEAS (Nsys);
+
+      int isPoor = (measure[k].psfQFperf < 0.85);
+      if ((pass == 0) && isPoor) SKIP_THIS_MEAS (Nsys);
+
+      dFpsf = MAX (dFpsf, MIN_ERROR*Fpsf); // MIN_ERROR is a fractional error
+      Fpsflist[Npsf] = Fpsf * Fcal;
+      dpsflist[Npsf] = dFpsf * Fcal;
+      wpsflist[Npsf] = 1.0;
+      Npsf ++;
+
+      measure[k].dbFlags |= ID_MEAS_WARP_USED;
+
+      float Fap = PhotFluxCat (&measure[k], MAG_CLASS_APER);
+      float dFap = PhotFluxCatErr (&measure[k], MAG_CLASS_APER);
+      if (!isnan(Fap)) {
+	Faplist[Nap] = Fap * Fcal;
+	daplist[Nap] = dFap * Fcal;
+	waplist[Nap] = 1.0; // drop weight lists?
+	Nap ++;
+      }
+
+      float Fkron = PhotFluxCat (&measure[k], MAG_CLASS_KRON);
+      float dFkron = PhotFluxCatErr (&measure[k], MAG_CLASS_KRON);
+      if (!isnan(Fkron)) {
+	Fkronlist[Nkron] = Fkron * Fcal;
+	dkronlist[Nkron] = dFkron * Fcal;
+	wkronlist[Nkron] = 1.0;
+	Nkron ++;
+      }
+    }
+    if (Npsf < 1) continue;
+
+    found[Nsec] = TRUE;
+
+    liststats (Fpsflist, dpsflist, wpsflist, Npsf, psfstats);
+
+    secfilt[Nsec].FpsfWrp  = psfstats->mean;
+    secfilt[Nsec].dFpsfWrp = psfstats->error;
+    secfilt[Nsec].sFpsfWrp = psfstats->sigma; // Mstdev is in millimags (not enough space for more precision)
+    secfilt[Nsec].NusedWrp = psfstats->Nmeas;
+    secfilt[Nsec].MpsfWrp  = isnan(secfilt[Nsec].FpsfWrp) ? NAN : 8.9 - 2.5*log10(secfilt[Nsec].FpsfWrp); // 8.9 since flux is in Jy
+
+    // NOTE : use the modified weight for apmags as well as psf mags
+    liststats (Faplist, daplist, waplist, Nap, apstats);
+    secfilt[Nsec].FapWrp     = Nap > 0 ? apstats->mean : NAN; 
+    secfilt[Nsec].dFapWrp    = Nap > 0 ? apstats->error : NAN; 
+    secfilt[Nsec].sFapWrp    = Nap > 0 ? apstats->sigma : NAN; 
+    secfilt[Nsec].NusedApWrp = Nap;
+    secfilt[Nsec].MapWrp  = isnan(secfilt[Nsec].FapWrp) ? NAN : 8.9 - 2.5*log10(secfilt[Nsec].FapWrp); // 8.9 since flux is in Jy
+
+    liststats (Fkronlist, dkronlist, wkronlist, Nkron, kronstats);
+    secfilt[Nsec].FkronWrp     = Nkron > 0 ? kronstats->mean  : NAN; 
+    secfilt[Nsec].dFkronWrp    = Nkron > 0 ? kronstats->error : NAN; 
+    secfilt[Nsec].sFkronWrp    = Nkron > 0 ? kronstats->sigma : NAN; 
+    secfilt[Nsec].NusedKronWrp = Nkron;
+    secfilt[Nsec].MkronWrp  = isnan(secfilt[Nsec].FkronWrp) ? NAN : 8.9 - 2.5*log10(secfilt[Nsec].FkronWrp); // 8.9 since flux is in Jy
+
+    secfilt[Nsec].Nwarp     = Nwarp;
+    secfilt[Nsec].NwarpGood = NwarpGood;
+  }
+  return (TRUE);
+}
+
 int setGlobalObjStats (Average *average, Measure *measure) {
 
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/setMrelFinal.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/setMrelFinal.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/setMrelFinal.c	(revision 37403)
@@ -85,7 +85,9 @@
 
   /* set catalog[0].found[i] = FALSE */
-  ALLOCATE (catalog[0].found, off_t, MAX (1, Nsecfilt*catalog[0].Naverage));
+  ALLOCATE (catalog[0].found_t, off_t, MAX (1, Nsecfilt*catalog[0].Naverage));
+  ALLOCATE (catalog[0].foundWarp_t, off_t, MAX (1, Nsecfilt*catalog[0].Naverage));
   for (i = 0; i < Nsecfilt*catalog[0].Naverage; i++) {
-    catalog[0].found[i] = FALSE;
+    catalog[0].found_t[i] = FALSE;
+    catalog[0].foundWarp_t[i] = FALSE;
   }
 
@@ -194,5 +196,5 @@
       
       /* star/photcodes already calibrated */
-      if (catalog[0].found[Nsecfilt*i+Nsec]) continue;  
+      if (catalog[0].found_t[Nsecfilt*i+Nsec]) continue;  
 
       m = catalog[0].average[i].measureOffset;
@@ -229,5 +231,5 @@
 	if ((pass < 4) && ImagSelect) {
 	  if (Nim > -1) {
-	    mag = PhotInst (&catalog[0].measure[m]);
+	    mag = PhotInst (&catalog[0].measure[m], MAG_CLASS_PSF);
 	    if (mag < ImagMin) goto skip;
 	    if (mag > ImagMax) goto skip;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/share_mean_mags.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/share_mean_mags.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/share_mean_mags.c	(revision 37403)
@@ -123,5 +123,5 @@
   meanmags->M  = secfilt->M;
   meanmags->dM = secfilt->dM;
-  meanmags->Xm = secfilt->Xm;
+  meanmags->Mchisq = secfilt->Mchisq;
   meanmags->Nsec = Nsec; // key to secfilt entry
 
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/syncfile.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/syncfile.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/relphot/src/syncfile.c	(revision 37403)
@@ -50,5 +50,5 @@
 int clear_sync_file (char *filename) {
   // delete file contents
-  truncate (filename, 0);
+  if (truncate (filename, 0)) fprintf (stderr, "trouble clearing file %s\n", filename);
 
   return TRUE;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/tools/Makefile
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/tools/Makefile	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/tools/Makefile	(revision 37403)
@@ -17,5 +17,5 @@
 PROGRAMS = gconfig fhead ftable fields list_astro glockfile \
 radec mktemp precess csystem fits_insert \
-medianfilter mefhead ckfits roc
+medianfilter mefhead ckfits roc random
 
 all tools: $(PROGRAMS)
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/tools/src/ftable.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/tools/src/ftable.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/tools/src/ftable.c	(revision 37403)
@@ -460,4 +460,12 @@
       } else {
 	for (j = 0; j < Nv; j++) {
+	  if (!strcmp (type, "byte")) {
+	    memcpy (line, &data[i*Nv*Nb + Nb*j], Nb);
+	    fprintf (stdout, "%d ", *(char *)line);
+	  }
+	  if (!strcmp (type, "short")) {
+	    memcpy (line, &data[i*Nv*Nb + Nb*j], Nb);
+	    fprintf (stdout, "%d ", *(short *)line);
+	  }
 	  if (!strcmp (type, "int")) {
 	    memcpy (line, &data[i*Nv*Nb + Nb*j], Nb);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/tools/src/random.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/tools/src/random.c	(revision 37403)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/tools/src/random.c	(revision 37403)
@@ -0,0 +1,63 @@
+# include <ohana.h>
+# define NBUFFER 8000000
+
+int main (int argc, char **argv) {
+
+  char c;
+  int i, j, N;
+
+  int FAST = FALSE;
+  if ((N = get_argument (argc, argv, "-fast"))) {
+    remove_argument (N, &argc, argv);
+    FAST = TRUE;
+  }
+
+  if (argc != 2) {
+    fprintf (stderr, "USAGE: random (Nbytes) [-fast]\n");
+    fprintf (stderr, "  generates Nbytes of random characters, to stdout\n");
+    fprintf (stderr, "  [-fast generates non random bytes, but ~2x faster]\n");
+    exit (1);
+  }
+
+  long A = time(NULL);
+  srand48(A);
+
+  int Nbytes = atoi (argv[1]);
+  char buffer[NBUFFER];
+
+  int Nblock = Nbytes / NBUFFER;
+  int Nextra = Nbytes - (Nblock * NBUFFER);
+
+  for (j = 0; j < Nblock; j++) {
+    for (i = 0; i < NBUFFER; i++) {
+      if (i % 80 == 0) {
+	buffer[i] = '\n';
+	continue;
+      }
+      if (FAST) {
+	c = (i % 90) + 33;
+      } else {
+	c = (char) 90*drand48() + 33;
+      }
+      buffer[i] = c;
+    }
+    fwrite (buffer, 1, NBUFFER, stdout);
+  }
+  for (i = 0; i < Nextra - 1; i++) {
+    if (i % 80 == 0) {
+      buffer[i] = '\n';
+      continue;
+    }
+    if (FAST) {
+      c = (i % 90) + 33;
+    } else {
+      c = (char) 90*drand48() + 33;
+    }
+    buffer[i] = c;
+  }
+  buffer[i] = '\n';
+  fwrite (buffer, 1, Nextra, stdout);
+  exit (0);
+}
+
+
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/uniphot/src/ImageSubset.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/uniphot/src/ImageSubset.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/uniphot/src/ImageSubset.c	(revision 37403)
@@ -99,11 +99,9 @@
   gfits_create_table_header (&theader, "BINTABLE", "IMAGE_SUBSET");
 
-  gfits_define_bintable_column (&theader, "E", "MCAL", "zero point offset", "magnitudes", 1.0, 0.0);
-  gfits_define_bintable_column (&theader, "E", "MCAL_ERR", "zero point error", "magnitudes", 1.0, 0.0);
-
-  // an unsigned int needs to have bzero of 0x8000
-  gfits_define_bintable_column (&theader, "J", "IMAGE_ID", "image ID", NULL, 1.0, 1.0*0x8000);
-  gfits_define_bintable_column (&theader, "J", "PHOTOM_MAP", "map", NULL, 1.0, 1.0*0x8000);
-  gfits_define_bintable_column (&theader, "J", "FLAGS", "flags", NULL, 1.0, 1.0*0x8000);
+  gfits_define_bintable_column (&theader, "E", "MCAL",       "zero point offset", "magnitudes", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E", "MCAL_ERR",   "zero point error",  "magnitudes", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "J", "IMAGE_ID",   "image ID", 	  NULL, 	1.0, FT_BZERO_INT32);
+  gfits_define_bintable_column (&theader, "J", "PHOTOM_MAP", "map",      	  NULL, 	1.0, FT_BZERO_INT32);
+  gfits_define_bintable_column (&theader, "J", "FLAGS",      "flags",    	  NULL, 	1.0, FT_BZERO_INT32);
 
   // generate the output array that carries the data
@@ -114,6 +112,6 @@
 
   // create intermediate storage arrays
-  ALLOCATE (Mcal,  float, Nimage);
-  ALLOCATE (dMcal, float, Nimage);
+  ALLOCATE (Mcal,    float, 	   Nimage);
+  ALLOCATE (dMcal,   float, 	   Nimage);
   ALLOCATE (imageID, unsigned int, Nimage);
   ALLOCATE (map,     unsigned int, Nimage);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/uniphot/src/ImageSubsetFixImageIDs.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/uniphot/src/ImageSubsetFixImageIDs.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/uniphot/src/ImageSubsetFixImageIDs.c	(revision 37403)
@@ -1,5 +1,3 @@
 # include "fiximids.h"
-# define FT_BZERO_INT16 1.0*0x8000	  
-# define FT_BZERO_INT32 1.0*0x80000000
 
 # define GET_COLUMN(OUT,NAME,TYPE) \
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/uniphot/src/ImageSubsetFixStackIDs.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/uniphot/src/ImageSubsetFixStackIDs.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/uniphot/src/ImageSubsetFixStackIDs.c	(revision 37403)
@@ -1,5 +1,3 @@
 # include "fixstkids.h"
-# define FT_BZERO_INT16 1.0*0x8000	  
-# define FT_BZERO_INT32 1.0*0x80000000
 
 # define GET_COLUMN(OUT,NAME,TYPE) \
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/uniphot/src/ImageSubsetSetPosangle.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/uniphot/src/ImageSubsetSetPosangle.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/uniphot/src/ImageSubsetSetPosangle.c	(revision 37403)
@@ -149,6 +149,5 @@
   gfits_create_table_header (&theader, "BINTABLE", "IMAGE_SUBSET");
 
-  // an unsigned int needs to have bzero of 0x8000
-  gfits_define_bintable_column (&theader, "J",   "IMAGE_ID",   "image ID", NULL, 1.0, 1.0*0x8000);
+  gfits_define_bintable_column (&theader, "J",   "IMAGE_ID",   "image ID", NULL, 1.0, FT_BZERO_INT32);
   gfits_define_bintable_column (&theader, "E",   "TZERO",      "tmp", 	   "mp", 1.0, 0.0);
   gfits_define_bintable_column (&theader, "E",   "TRATE",      "tmp", 	   "mp", 1.0, 0.0);
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/uniphot/src/load_images_fiximids.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/uniphot/src/load_images_fiximids.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/uniphot/src/load_images_fiximids.c	(revision 37403)
@@ -1,4 +1,3 @@
 # include "fiximids.h"
-# define FT_BZERO_INT32 1.0*0x80000000
 
 off_t   Nimage = 0;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/uniphot/src/load_images_fixstkids.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/uniphot/src/load_images_fixstkids.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/uniphot/src/load_images_fixstkids.c	(revision 37403)
@@ -1,4 +1,3 @@
 # include "fixstkids.h"
-# define FT_BZERO_INT32 1.0*0x80000000
 
 off_t Nimage = 0;
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/uniphot/src/update_catalog_fiximids.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/uniphot/src/update_catalog_fiximids.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/uniphot/src/update_catalog_fiximids.c	(revision 37403)
@@ -1,3 +1,8 @@
 # include "fiximids.h"
+
+// test image: 2013/06/15,13:25:51, GPC1.r.XY50
+static int CHECK_TEST_IMAGE = FALSE;
+static unsigned int Tref = 1378812312; 
+static short Cref = 10001;
 
 void update_catalog_fiximids (Catalog *catalog) {
@@ -18,4 +23,8 @@
     short photcode = catalog[0].measure[i].photcode;
     e_time time = catalog[0].measure[i].t;
+
+    if (CHECK_TEST_IMAGE && (abs(time - Tref) < 10) && (photcode == Cref)) {
+      fprintf (stderr, ".");
+    }
 
     // skip detections with no valid imageID (eg, ref photcode)
Index: branches/eam_branches/ps2-tc3-20130727/Ohana/src/uniphot/src/update_catalog_setastrom.c
===================================================================
--- branches/eam_branches/ps2-tc3-20130727/Ohana/src/uniphot/src/update_catalog_setastrom.c	(revision 37401)
+++ branches/eam_branches/ps2-tc3-20130727/Ohana/src/uniphot/src/update_catalog_setastrom.c	(revision 37403)
@@ -76,5 +76,5 @@
     // correction may be Minst or Minst + 5.0*log(fwhm
     float fwhm_maj = FromShortPixels(measure[0].FWx);
-    float Minst = PhotInst (measure);
+    float Minst = PhotInst (measure, MAG_CLASS_PSF);
     float MinstSB = Minst + 5.0*log10(fwhm_maj);
 
