Index: /branches/cnb_branch_20090215/Branches.txt
===================================================================
--- /branches/cnb_branch_20090215/Branches.txt	(revision 21535)
+++ /branches/cnb_branch_20090215/Branches.txt	(revision 21536)
@@ -1,2 +1,6 @@
+
+eam_branch_20090208
+* Ohana : mucking around with measure.d, average.d, etc to define the
+  initial PS1 survey DVO output formats.
 
 eam_branch_20090203
Index: /branches/cnb_branch_20090215/Ohana/configure.tcsh
===================================================================
--- /branches/cnb_branch_20090215/Ohana/configure.tcsh	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/configure.tcsh	(revision 21536)
@@ -12,4 +12,5 @@
 set memcheck = 0
 set use_tcmalloc = 0
+set use_gnu99 = 0
 
 set prefix  = ""
@@ -70,4 +71,7 @@
    set use_tcmalloc = 1
    breaksw;
+  case --use-gnu99
+   set use_gnu99 = 1
+   breaksw;
   case --pedantic
    set pedantic = 1
@@ -167,4 +171,5 @@
   set CFLAGS = "-g -O0"
 endif  
+
 # optimize overrides user-supplied CFLAGS
 if ($optimize) set CFLAGS = "-O2"
@@ -172,4 +177,7 @@
 # profiler code
 if ($profile) set CFLAGS = "$CFLAGS -pg"
+
+# use_gnu99
+if ($use_gnu99) set CFLAGS = "$CFLAGS -std=gnu99"
 
 if (! $?CPPFLAGS) then
Index: /branches/cnb_branch_20090215/Ohana/src/addstar/Makefile
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/Makefile	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/Makefile	(revision 21536)
@@ -27,5 +27,9 @@
 mkcmf       : $(BIN)/mkcmf.$(ARCH)
 
-all: addstar addstarc addstard addstart sedstar load2mass skycells
+all: addstar sedstar load2mass skycells
+
+# I need to fix the client/server version of addstar now that I have dropped Stars
+# as an autocode type and have converted to carrying average and measure
+# all: addstar addstarc addstard addstart sedstar load2mass skycells
 
 ADDSTAR = \
@@ -48,9 +52,4 @@
 $(SRC)/find_matches_refstars.$(ARCH).o \
 $(SRC)/find_subset.$(ARCH).o \
-$(SRC)/get2mass.$(ARCH).o \
-$(SRC)/get2mass_as.$(ARCH).o \
-$(SRC)/get2mass_as_raw.$(ARCH).o \
-$(SRC)/get2mass_dr2.$(ARCH).o \
-$(SRC)/get2mass_ops.$(ARCH).o \
 $(SRC)/getgsc.$(ARCH).o \
 $(SRC)/gettycho.$(ARCH).o \
@@ -71,4 +70,5 @@
 $(SRC)/replace_match.$(ARCH).o \
 $(SRC)/resort_catalog.$(ARCH).o \
+$(SRC)/StarOps.$(ARCH).o \
 $(SRC)/ReadStarsFITS.$(ARCH).o \
 $(SRC)/ReadStarsTEXT.$(ARCH).o \
@@ -106,9 +106,4 @@
 $(SRC)/find_matches_refstars.$(ARCH).o \
 $(SRC)/find_subset.$(ARCH).o \
-$(SRC)/get2mass.$(ARCH).o \
-$(SRC)/get2mass_as.$(ARCH).o \
-$(SRC)/get2mass_as_raw.$(ARCH).o \
-$(SRC)/get2mass_dr2.$(ARCH).o \
-$(SRC)/get2mass_ops.$(ARCH).o \
 $(SRC)/getgsc.$(ARCH).o \
 $(SRC)/gettycho.$(ARCH).o \
@@ -141,9 +136,4 @@
 $(SRC)/find_matches_refstars.$(ARCH).o \
 $(SRC)/find_subset.$(ARCH).o \
-$(SRC)/get2mass.$(ARCH).o \
-$(SRC)/get2mass_as.$(ARCH).o \
-$(SRC)/get2mass_as_raw.$(ARCH).o \
-$(SRC)/get2mass_dr2.$(ARCH).o \
-$(SRC)/get2mass_ops.$(ARCH).o \
 $(SRC)/getgsc.$(ARCH).o \
 $(SRC)/getusno.$(ARCH).o \
@@ -209,4 +199,5 @@
 $(SRC)/replace_match.$(ARCH).o \
 $(SRC)/update_coords.$(ARCH).o \
+$(SRC)/StarOps.$(ARCH).o \
 $(SRC)/ConfigInit.$(ARCH).o \
 $(SRC)/Shutdown.$(ARCH).o \
@@ -252,5 +243,10 @@
 $(BIN)/mkcmf.$(ARCH)       : $(MKCMF)
 
-INSTALL = addstar addstarc addstard addstart sedstar load2mass skycells mkcmf
+INSTALL = addstar sedstar load2mass skycells mkcmf
+
+# I need to fix the client/server version of addstar now that I have dropped Stars
+# as an autocode type and have converted to carrying average and measure
+# all: addstar addstarc addstard addstart sedstar load2mass skycells
+# INSTALL = addstar addstarc addstard addstart sedstar load2mass skycells mkcmf
 
 # dependancy rules for binary code #########################
Index: /branches/cnb_branch_20090215/Ohana/src/addstar/doc/notes.txt
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/doc/notes.txt	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/doc/notes.txt	(revision 21536)
@@ -1,2 +1,28 @@
+
+2009.02.11
+
+  updating DVO tables with more fields: cleaning up the conversions
+  from external formats to the DVO internal formats:  I am changing
+  the APIs to convert directly to the Measure structure, including
+  conversion functions for the compressed fields (ie, pixels carried
+  as short).
+
+  A few remaining issues:
+
+  * t_msec : I've added a field to carry the fractional seconds, but
+    nothing is yet setting this value, and the query functions do not
+    use this value.
+
+  * various fields are reported in either arcseconds or pixels (eg,
+    FWHMx, moments, error in centroid).  These are currently not very
+    consistent, and should be tightened up...
+
+    ** if we store these values in pixels, then cameras with a wide
+       range of plate scales (GPC1 << SkyProbe << AllSky) will all fit
+       in field with a small dynamic range; since we also provide the
+       plate scale (as a float), conversions are easy:
+       GPC1     : 0.26 arcsec / pixel
+       SkyProbe : 4.5 arcsec / pixel
+       AllSky   : 3600.0 arcsec / pixel 
 
 2008.10.11
Index: /branches/cnb_branch_20090215/Ohana/src/addstar/include/addstar.h
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/include/addstar.h	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/include/addstar.h	(revision 21536)
@@ -28,4 +28,18 @@
     fprintf (stderr, "ERROR:  photcode %s not found in photcode table\n", NAME); \
     exit (0); }
+
+typedef struct {
+  char *exthead;
+  char *extdata;
+  char *exttype;
+  int extnum_head;
+  int extnum_data;
+} HeaderSet;
+
+typedef struct {
+  Average average;
+  Measure measure;
+  int found;
+} Stars;
 
 typedef struct {
@@ -39,12 +53,4 @@
   char *refcat;
 } DVO_DATA;
-
-typedef struct {
-  char *exthead;
-  char *extdata;
-  char *exttype;
-  int extnum_head;
-  int extnum_data;
-} HeaderSet;
 
 typedef struct sockaddr_in SockAddress;
@@ -92,4 +98,5 @@
 /* these globals modify the behavior of gstars (KEEP) */
 double 	SNLIMIT;
+int     PHOTFLAG_EXCLUDE;
 int    	ACCEPT_ASTROM;  // accept even bad astrometry solutions (NASTRO == 0)
 int    	ACCEPT_MOTION;  // accept reference proper motion measurements
@@ -137,6 +144,8 @@
 /*** addstar prototypes ***/
 
+AddstarClientOptions ConfigInit   PROTO((int *argc, char **argv));
+AddstarClientOptions args         PROTO((int argc, char **argv, AddstarClientOptions options));
+
 void       AddToCalibration       PROTO((Average *average, SecFilt *secfilt, Measure *measure, Measure *new, int *next, int Nstar));
-AddstarClientOptions ConfigInit   PROTO((int *argc, char **argv));
 void       FindCalibration        PROTO((Image *image));
 FILE      *GetDB                  PROTO((int *state));
@@ -145,27 +154,31 @@
 void       SetProtect             PROTO((int mode));
 int        SetSignals             PROTO((void));
-int        Shutdown               PROTO((char *message, ...); ) 
+int        Shutdown               PROTO((char *message, ...));
 void       TrapSignal             PROTO((int sig));
 float      airmass                PROTO((float secz_image, double ra, double dec, double st, double latitude));
+float      azimuth                PROTO((double ha, double dec, double latitude));
 void       SetAirmassQuality      PROTO((int quality));
 SkyTable  *SkyTableFromTychoIndex PROTO((char *filename, int VERBOSE));
-AddstarClientOptions args         PROTO((int argc, char **argv, AddstarClientOptions options));
 void       check_permissions      PROTO((char *basefile));
 int        dump_rawstars          PROTO((Stars *stars, int Nstars));
 int        edge_check             PROTO((double *x1, double *y1, double *x2, double *y2));
 Image     *fakeimage              PROTO((char *rootname, int *Nimage, int photcode));
+
 int        find_matches           PROTO((SkyRegion *region, Stars *stars, int Nstars, Catalog *catalog, AddstarClientOptions options));
 int        find_matches_closest   PROTO((SkyRegion *region, Stars *stars, int Nstars, Catalog *catalog, AddstarClientOptions options));
 int        find_matches_refstars  PROTO((SkyRegion *region, Stars **stars, int Nstars, Catalog *catalog, AddstarClientOptions options));
+
 Stars    **find_subset            PROTO((SkyRegion *region, Stars *stars, int Nstars, int *NSTARS));
 int        gcatalog               PROTO((Catalog *catalog));
 Stars     *get2mass               PROTO((SkyRegion *patch, int photcode, int mode, int *NSTARS));
 double     get_subpix             PROTO((double x, double y));
+
+Stars     *greference             PROTO((char *Refcat, SkyRegion *catstats, int photcode, int *nstars));
 Stars     *getgsc                 PROTO((SkyRegion *patch, int *NSTARS));
 Stars     *gettycho               PROTO((SkyRegion *catstats, int photcode, int *Nstars));
 Stars     *getusno                PROTO((SkyRegion *catstats, int photcode, int *Nstars));
 Stars     *getusnob               PROTO((SkyRegion *catstats, int photcode, int *Nstars));
-Image     *gimages                PROTO((FITS_DB *db, Image *image, Coords *mosaic, int *Npimage));
-Stars     *grefcat                PROTO((char *Refcat, SkyRegion *catstats, int photcode, int *nstars));
+
+// load text-based stars (REF only in the sense of REF photcodes)
 Stars     *grefstars              PROTO((char *file, int photcode, int *Nstars));
 
@@ -249,4 +262,9 @@
 Stars     *Convert_PS1_DEV_0	  PROTO((FTable *table, int *nstars));
 Stars     *Convert_PS1_DEV_1	  PROTO((FTable *table, int *nstars));
+Stars     *Convert_PS1_V1	  PROTO((FTable *table, int *nstars));
+
+int        InitStar               PROTO((Stars *star));
+short      ShortPixels            PROTO((float pixels));
+short      ShortDegree            PROTO((float degrees));
 
 int args_skycells (int argc, char **argv);
Index: /branches/cnb_branch_20090215/Ohana/src/addstar/include/skycells.h
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/include/skycells.h	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/include/skycells.h	(revision 21536)
@@ -30,5 +30,5 @@
   int NX;
   int NY;
-  int code;
+  int photcode;
   char name[64];
 } SkyRectangle;
Index: /branches/cnb_branch_20090215/Ohana/src/addstar/src/ConfigInit.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/src/ConfigInit.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/src/ConfigInit.c	(revision 21536)
@@ -39,4 +39,8 @@
   ScanConfig (config, "MIN_SN_FSTAT",           "%lf", 0, &SNLIMIT);
   ScanConfig (config, "ADDSTAR_SNLIMIT",        "%lf", 0, &SNLIMIT);
+
+  /* exclude stars with bits that match the given photFlags bits */
+  PHOTFLAG_EXCLUDE = 0;
+  ScanConfig (config, "ADDSTAR_PHOTFLAG_EXCLUDE", "%d", 0, &PHOTFLAG_EXCLUDE);
 
   MAX_CERROR = 0.5; // arcseconds
Index: /branches/cnb_branch_20090215/Ohana/src/addstar/src/FilterStars.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/src/FilterStars.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/src/FilterStars.c	(revision 21536)
@@ -1,4 +1,13 @@
 # include "addstar.h"
+# define EXTERNAL_ID FALSE
 
+/* exclude some detections based on various filter options:
+ * *** S/N limit
+ * *** Acceptable window on detector
+ * *** bad photFlags
+ */
+
+// the imageID supplied here is the sequence **within this set**
+// this value is updated based on the image table later
 Stars *FilterStars (Stars *instars, Image *image, unsigned int imageID) {
 
@@ -19,33 +28,39 @@
   ALLOCATE (stars, Stars, image[0].nstar);
   for (N = j = 0; j < image[0].nstar; j++) {
+
     /* allow for some dynamic filtering of star list */
-    if (SNLIMIT && instars[j].dM > SNLIMIT) continue;
-    if (XMAX && (instars[j].X > XMAX)) continue;
-    if (XMIN && (instars[j].X < XMIN)) continue;
-    if (YMAX && (instars[j].Y > YMAX)) continue;
-    if (YMIN && (instars[j].Y < YMIN)) continue;
+    if (SNLIMIT && instars[j].measure.dM > SNLIMIT) continue;
+    if (XMAX && (instars[j].measure.Xccd > XMAX)) continue;
+    if (XMIN && (instars[j].measure.Xccd < XMIN)) continue;
+    if (YMAX && (instars[j].measure.Yccd > YMAX)) continue;
+    if (YMIN && (instars[j].measure.Yccd < YMIN)) continue;
+    if (PHOTFLAG_EXCLUDE && (instars[j].measure.photFlags & PHOTFLAG_EXCLUDE)) continue;
+
     stars[N] = instars[j];
 
-    XY_to_RD (&stars[N].R, &stars[N].D, stars[N].X, stars[N].Y, &image[0].coords);
-    stars[N].R = ohana_normalize_angle (stars[N].R);
-    stars[N].found = -1;
-    stars[N].code = image[0].photcode;
+    XY_to_RD (&stars[N].average.R, &stars[N].average.D, stars[N].measure.Xccd, stars[N].measure.Yccd, &image[0].coords);
+    stars[N].average.R = ohana_normalize_angle (stars[N].average.R);
 
-    RMIN = MIN (RMIN, stars[N].R);
-    RMAX = MAX (RMAX, stars[N].R);
-    DMIN = MIN (DMIN, stars[N].D);
-    DMAX = MAX (DMAX, stars[N].D);
+    stars[N].measure.photcode = image[0].photcode;
+
+    // determine the full coverage of this set of measurements
+    RMIN = MIN (RMIN, stars[N].average.R);
+    RMAX = MAX (RMAX, stars[N].average.R);
+    DMIN = MIN (DMIN, stars[N].average.D);
+    DMAX = MAX (DMAX, stars[N].average.D);
+
     /** additional quantities to supply to Stars based on the image data **/
 
-    /* calculate accurate per-star airmass */
-    stars[N].airmass = airmass (image[0].secz, stars[N].R, stars[N].D, image[0].sidtime, image[0].latitude);
-    stars[N].Mcal    = image[0].Mcal;
-    stars[N].t       = image[0].tzero + 1e-4*stars[N].Y*image[0].trate;  /* trate is in 0.1 msec / row */
-    stars[N].dt      = MTIME;
+    /* calculate accurate per-star airmass and azimuth */
+    stars[N].measure.airmass = airmass (image[0].secz, stars[N].average.R, stars[N].average.D, image[0].sidtime, image[0].latitude);
+    stars[N].measure.az      = azimuth (image[0].sidtime - stars[N].average.R, stars[N].average.D, image[0].latitude);
+    stars[N].measure.Mcal    = image[0].Mcal;
+    stars[N].measure.t       = image[0].tzero + 1e-4*stars[N].measure.Yccd*image[0].trate;  /* trate is in 0.1 msec / row */
+    stars[N].measure.dt      = MTIME;
 
-    if ((stars[N].M > 25.0) && (stars[N].M < 32.0)) {
+    // watch out for any strange values:
+    if ((stars[N].measure.M > 25.0) && (stars[N].measure.M < 32.0)) {
       fprintf (stderr, "*");
     }
-
     // stars->M is either NAN or a valid inst magnitude
     // stars->dM is either NAN or a valid error
@@ -54,22 +69,33 @@
     dMx = 0.0;
     if (SUBPIX) {
-      dMs = get_subpix (stars[N].X, stars[N].Y);
-      dMx = scat_subpix (stars[N].X, stars[N].Y);
-      if (!isnan(stars[N].dM)) {
-	stars[N].dM = hypot (stars[N].dM, dMx);
+      dMs =  get_subpix (stars[N].measure.Xccd, stars[N].measure.Yccd);
+      dMx = scat_subpix (stars[N].measure.Xccd, stars[N].measure.Yccd);
+      if (!isnan(stars[N].measure.dM)) {
+	stars[N].measure.dM = hypot (stars[N].measure.dM, dMx);
       }
     }
 
-    if (!isnan(stars[N].M)) {
-      stars[N].M += MTIME - dMs;
+    if (!isnan(stars[N].measure.M)) {
+      stars[N].measure.M   += MTIME - dMs;
     }
-    if (!isnan(stars[N].Map)) {
-      stars[N].Map += MTIME - dMs;
+    if (!isnan(stars[N].measure.Map)) {
+      stars[N].measure.Map += MTIME - dMs;
     }
     
-    // XXX currently, this ID is internal only; 
-    // should we use the psphot / other external ID, if available?
-    stars[N].detID = N; // sequence number within image
-    stars[N].imageID = imageID; // does this need to be updated?
+    // the external ID is supplied, but do we trust it?
+    if (!EXTERNAL_ID) {
+      stars[N].measure.detID = N; // sequence number within image
+    }
+
+# if (0) 
+    if (PSPS_ID) {
+      double mjd;
+      mjd = ohana_sec_to_mjd (image[0].tzero);
+      // XXX this is clearly wrong : what does PSPS want?
+      stars[N].measure.extID = PSPS_create_detectid (mjd, imageID);
+    }
+# endif
+
+    stars[N].measure.imageID = imageID; // this value is update in UpdateImageIDs
 
     N ++;
Index: /branches/cnb_branch_20090215/Ohana/src/addstar/src/GetFileMode.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/src/GetFileMode.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/src/GetFileMode.c	(revision 21536)
@@ -7,4 +7,5 @@
   int Naxis;
   int simple, extend, haveNaxis, haveCTYPE;
+  int tmp, havePHOT_VER, haveTARG_VER;
 
   gfits_scan (header, "SIMPLE", "%t", 1, &simple);
@@ -14,13 +15,9 @@
   gfits_scan (header, "EXTEND", "%t", 1, &extend);
     
-{
-    int tmp, havePHOT_VER, haveTARG_VER;
-
-    // SDSS tsObj files have a version number for the PHOTO and 
-    // TS (target selection) pipelines present as header keywords
-    havePHOT_VER = gfits_scan (header, "PHOT_VER", "%s", 1, &tmp);
-    haveTARG_VER = gfits_scan (header, "TARG_VER", "%s", 1, &tmp);
-    if (havePHOT_VER && haveTARG_VER) return SDSS_OBJ;
-}
+  // SDSS tsObj files have a version number for the PHOTO and 
+  // TS (target selection) pipelines present as header keywords
+  havePHOT_VER = gfits_scan (header, "PHOT_VER", "%s", 1, &tmp);
+  haveTARG_VER = gfits_scan (header, "TARG_VER", "%s", 1, &tmp);
+  if (havePHOT_VER && haveTARG_VER) return SDSS_OBJ;
 
   if ((Naxis == 2) || TEXTMODE || !simple) {
Index: /branches/cnb_branch_20090215/Ohana/src/addstar/src/LoadData.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/src/LoadData.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/src/LoadData.c	(revision 21536)
@@ -41,4 +41,5 @@
     // I need to detect them here and load them with ReadStarsTEXT instead of calling the code
     // below.
+    // inStars = ReadStarsFITS (f, headers[Nhead], headers[Ndata], &images[0][Nvalid].nstar);
 
     // XXX use something to set the chip name? EXTNAME?
Index: /branches/cnb_branch_20090215/Ohana/src/addstar/src/LoadDataPMM.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/src/LoadDataPMM.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/src/LoadDataPMM.c	(revision 21536)
@@ -82,11 +82,9 @@
 
     for (i = 0; i < Nline; i++) {
-      // fscanf (f, "%lf %lf %lf", &ra, &dec, &mag) != EOF) {
-
       dparse (&ra,  1, &buffer[i*NBYTE_ASC_TABLE]);
       dparse (&dec, 2, &buffer[i*NBYTE_ASC_TABLE]);
       dparse (&mag, 3, &buffer[i*NBYTE_ASC_TABLE]);
 
-      memset (&inStars[Ninstars], 0, sizeof(Stars));
+      InitStar (&inStars[Ninstars]);
 
       if (ra > 180) {
@@ -100,13 +98,14 @@
       maxD = MAX(maxD, dec);
 
-      inStars[Ninstars].M       = mag - ZeroPoint + ZeroPt;
-      inStars[Ninstars].R       = ra;
-      inStars[Ninstars].D       = dec;
-      inStars[Ninstars].t       = images[0][0].tzero;
-      inStars[Ninstars].dt      = images[0][0].exptime;
-      inStars[Ninstars].code    = code;
-      inStars[Ninstars].airmass = airmass;
-      inStars[Ninstars].az      = az;
-      inStars[Ninstars].found   = -1; // found starts at -1 == not yet found
+      inStars[Ninstars].average.R        = ra;
+      inStars[Ninstars].average.D        = dec;
+
+      inStars[Ninstars].measure.M        = mag - ZeroPoint + ZeroPt;
+      inStars[Ninstars].measure.t        = images[0][0].tzero;
+      inStars[Ninstars].measure.dt       = images[0][0].exptime;
+      inStars[Ninstars].measure.photcode = code;
+      inStars[Ninstars].measure.airmass  = airmass;
+      inStars[Ninstars].measure.az       = az;
+
       Ninstars++;
       CHECK_REALLOCATE (inStars, Stars, NINSTARS, Ninstars, 10000);
@@ -238,5 +237,5 @@
     image[0].Mcal = 0.0;
     image[0].Xm   = NAN_S_SHORT;
-    image[0].code = 0;
+    image[0].flags = 0;
 
     image[0].nstar = 0;
Index: /branches/cnb_branch_20090215/Ohana/src/addstar/src/LoadStars.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/src/LoadStars.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/src/LoadStars.c	(revision 21536)
@@ -63,4 +63,5 @@
     }
 
+    // load PMM data if specified (these are not stored as FITS-tables)
     if (PMM_CCD_TABLE != NULL) {
       LoadDataPMM (f, file[i], images, Nimages, &stars, Nstars);
@@ -68,4 +69,5 @@
     }
 
+    // otherwise, we have FITS-table files: parse their headers to determine the contents
     headers = LoadHeaders (f, &mode, &Nheaders);
     headerSets = MatchHeaders (&extsize, &NheaderSets, mode, headers, Nheaders);
@@ -86,4 +88,5 @@
     }
 
+    // if these are SDSS data, load with SDSS-specific wrapper
     if (headerSets[0].exttype && !strcmp (headerSets[0].exttype, "SDSS_OBJ")) {
       LoadDataSDSS (f, file[i], images, Nimages, &stars, Nstars, headers, extsize, headerSets, NheaderSets);
Index: /branches/cnb_branch_20090215/Ohana/src/addstar/src/MatchHeaders.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/src/MatchHeaders.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/src/MatchHeaders.c	(revision 21536)
@@ -51,4 +51,5 @@
     if (!strcmp (exttype, "PS1_DEV_0")) goto keep;
     if (!strcmp (exttype, "PS1_DEV_1")) goto keep;
+    if (!strcmp (exttype, "PS1_V1")) goto keep;
     continue;
 
Index: /branches/cnb_branch_20090215/Ohana/src/addstar/src/PSPS_IDs.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/src/PSPS_IDs.c	(revision 21536)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/src/PSPS_IDs.c	(revision 21536)
@@ -0,0 +1,71 @@
+# include "addstar.h"
+
+uint64_7 PSPS_create_detectID (double MJDobs, int imageID) {
+
+  // MJD has a PS lifetime range of : 3288 (2009/01/01) to 9132 (2025/01/01) (< 2^14)
+
+  static double t0 = 51544.5; // MJD @ 2000/01/01,12:00:00
+
+  uint64_t iTime;
+  uint64_t detectID;
+
+  iTime = floor(tobs - t0);
+
+  // iTime takes the upper 16 bits, imageID can take up to lower 48 bits
+  detectID = (iTime << 48) | imageID;
+
+  return detectID;
+}
+
+uint64_t PSPS_create_objID (double ra, double dec) {
+
+  static double zh = 0.0083333; // zone height = 30 arcsec
+
+  uint64_t objID;
+  uint64_t part1, part2, part3;
+
+  double zid, zresid;
+  int izone;
+
+  zid = (dec + 90.0) / zh; // 0 - 180*60*2 = 21600 (< 15 bits)
+  izone = (int) floor(zid);
+  zresid = zid -  ((float) izone); // 0 - 1.0 
+  part1 = (uint64_t)( izone  * 10000000000000) ;
+  part2 = ((uint64_t)(ra * 1 000 000.)) * 10000 ; // 0 - 360.0*1e6 = 3.6e8 (< 29 bits)
+  part3 = (int) (zresid * 10000.0) ; // 0 - 10000 (1 bit == 30/10000 arcsec = 0.003 arcsec) (< 14 bits)
+
+  objID = part1 + part2 + part3;
+
+  return objID;
+}
+
+uint64_t PSPS_create_objID_eam (double ra, double dec) {
+
+  static double zh = 0.0083333; // zone height = 30 arcsec
+
+  uint64_t objID;
+  uint64_t part1, part2, part3;
+
+  double zid, zresid;
+  int izone, ira;
+
+  zid = (dec + 90.0) / zh; // 0 - 180*60*2 = 21600 (< 15 bits)
+  izone = (int) floor(zid);
+  zresid = zid -  ((float) izone); // 0 - 1.0 
+
+  ira = ra * 1 000 000; // 0 - 360.0*1e6 = 3.6e8 (< 29 bits) 
+
+  part1 = (izone << 48);
+  part2 = (ira << 16);
+  part3 = (int) (zresid * 10000.0) ; // 0 - 10000 (1 bit == 30/10000 arcsec = 0.003 arcsec) (< 14 bits)
+
+  objID = part1 | part2 | part3;
+
+  return objID;
+}
+
+// part1 : 15 bits
+// part2 : 29 bits
+// part3 : 14 bits
+// 15 + 14 + 29 bits = 58 bits...
+
Index: /branches/cnb_branch_20090215/Ohana/src/addstar/src/ReadImageHeader.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/src/ReadImageHeader.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/src/ReadImageHeader.c	(revision 21536)
@@ -200,5 +200,5 @@
   image[0].Mcal = 0.0;
   image[0].Xm   = NAN_S_SHORT;
-  image[0].code = 0;
+  image[0].flags = 0;
 
   /* find expected number of stars */
Index: /branches/cnb_branch_20090215/Ohana/src/addstar/src/ReadStarsFITS.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/src/ReadStarsFITS.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/src/ReadStarsFITS.c	(revision 21536)
@@ -40,4 +40,7 @@
     stars = Convert_PS1_DEV_1 (&table, &Nstars);
   }
+  if (!strcmp (type, "PS1_V1")) {
+    stars = Convert_PS1_V1 (&table, &Nstars);
+  }
   if (stars == NULL) {
     fprintf (stderr, "ERROR: invalid table type %s\n", type);
@@ -62,26 +65,27 @@
   ZeroPt = GetZeroPoint();
 
-  /* XXX we need to check at least the size of the loaded table */
-  // XXX use memset to zero-out the elements before setting
-
-  ALLOCATE (stars, Stars, Nstars);
-  for (i = 0; i < Nstars; i++) {
-    stars[i].X      = smpdata[i].X;
-    stars[i].Y      = smpdata[i].Y;
+  ALLOCATE (stars, Stars, Nstars);
+  for (i = 0; i < Nstars; i++) {
+    InitStar (&stars[i]);
+
+    stars[i].measure.Xccd      = smpdata[i].X;
+    stars[i].measure.Yccd      = smpdata[i].Y;
 
     if ((smpdata[i].M >= ZeroPt) || isnan(smpdata[i].M)) {
-      stars[i].M    = NAN;
-      stars[i].Map  = NAN;
-    } else {
-      stars[i].M    = smpdata[i].M;
-      stars[i].Map  = smpdata[i].M;
-    }
-
-    stars[i].dM     = smpdata[i].dM*0.001;
-    stars[i].dophot = smpdata[i].dophot;
-
-    stars[i].fx     = smpdata[i].fx;
-    stars[i].fy     = smpdata[i].fy;
-    stars[i].df     = smpdata[i].df;
+      stars[i].measure.M       = NAN;
+      stars[i].measure.Map     = NAN;
+    } else {
+      stars[i].measure.M       = smpdata[i].M;
+      stars[i].measure.Map     = smpdata[i].M;
+    }
+
+    stars[i].measure.dM        = smpdata[i].dM*0.001;
+
+    // the dophot type information gets pushed into the upper 2 bytes of photFlags
+    stars[i].measure.photFlags = (smpdata[i].dophot << 16);
+
+    stars[i].measure.FWx       = ShortPixels (smpdata[i].fx);
+    stars[i].measure.FWy       = ShortPixels (smpdata[i].fy);
+    stars[i].measure.theta     = ShortDegree (smpdata[i].df);
   }    
   *nstars = Nstars;
@@ -101,52 +105,29 @@
   ALLOCATE (stars, Stars, Nstars);
   for (i = 0; i < Nstars; i++) {
-    stars[i].X       = ps1data[i].X;
-    stars[i].Y       = ps1data[i].Y;
-    stars[i].dX      = ps1data[i].dX;
-    stars[i].dY      = ps1data[i].dY;
+    InitStar (&stars[i]);
+    stars[i].measure.Xccd     = ps1data[i].X;
+    stars[i].measure.Yccd     = ps1data[i].Y;
+
+    stars[i].measure.dXccd    = ShortPixels(ps1data[i].dX);
+    stars[i].measure.dYccd    = ShortPixels(ps1data[i].dY);
+   
     if ((ps1data[i].M >= 0.0) || isnan(ps1data[i].M)) {
-      stars[i].M     = NAN;
-    } else {
-      stars[i].M     = ps1data[i].M + ZeroPt;
-    }
-    stars[i].dM      = ps1data[i].dM;
-    stars[i].Mpeak   = ps1data[i].Mpeak;
-
-    stars[i].sky     = ps1data[i].sky;
-    stars[i].dsky    = ps1data[i].dSky;
-
-    stars[i].fx      = ps1data[i].fx;
-    stars[i].fy      = ps1data[i].fy;
-    stars[i].df      = ps1data[i].df;
-
-    stars[i].psfChisq = ps1data[i].psfChisq;
-    stars[i].psfQual  = ps1data[i].psfQual;
-
-    stars[i].detID   = ps1data[i].detID;
-
-    /* these are set elsewhere */
-    stars[i].R       = 0.0;
-    stars[i].D       = 0.0;
-    stars[i].dR      = 0.0;
-    stars[i].dD      = 0.0;
-
-    stars[i].uR      = 0.0;
-    stars[i].uD      = 0.0;
-    stars[i].duR     = 0.0;
-    stars[i].duD     = 0.0;
-
-    stars[i].P       = 0.0;
-    stars[i].dP      = 0.0;
-
-    stars[i].Mcal    = 0;
-    stars[i].t       = 0;
-    stars[i].dt      = 0;
-    stars[i].airmass = 0;
-    stars[i].code    = 0;
-    stars[i].found   = 0;
-
-    /* these are not used */
-    stars[i].Map     = NAN;
-    stars[i].dophot  = 0;
+      stars[i].measure.M      = NAN;
+    } else {
+      stars[i].measure.M      = ps1data[i].M + ZeroPt;
+    }
+    stars[i].measure.Map      = NAN;
+    stars[i].measure.dM       = ps1data[i].dM;
+    stars[i].measure.Sky      = ps1data[i].sky;
+    stars[i].measure.dSky     = ps1data[i].dSky;
+
+    stars[i].measure.FWx      = ShortPixels(ps1data[i].fx);
+    stars[i].measure.FWy      = ShortPixels(ps1data[i].fy);
+    stars[i].measure.theta    = ShortDegree(ps1data[i].df);
+
+    stars[i].measure.psfChisq = ps1data[i].psfChisq;
+    stars[i].measure.psfQual  = ps1data[i].psfQual;
+
+    stars[i].measure.detID    = ps1data[i].detID;
   }    
   *nstars = Nstars;
@@ -168,61 +149,97 @@
   ALLOCATE (stars, Stars, Nstars);
   for (i = 0; i < Nstars; i++) {
-    stars[i].X       = ps1data[i].X;
-    stars[i].Y       = ps1data[i].Y;
-    stars[i].dX      = ps1data[i].dX;
-    stars[i].dY      = ps1data[i].dY;
+    InitStar (&stars[i]);
+    stars[i].measure.Xccd       = ps1data[i].X;
+    stars[i].measure.Yccd       = ps1data[i].Y;
+
+    stars[i].measure.dXccd      = ShortPixels(ps1data[i].dX);
+    stars[i].measure.dYccd      = ShortPixels(ps1data[i].dY);
+
     if ((ps1data[i].M >= 0.0) || isnan(ps1data[i].M)) {
-	stars[i].M   = NAN;
-    } else {
-	stars[i].M   = ps1data[i].M + ZeroPt;
-    }
-    stars[i].dM      = ps1data[i].dM;
-    stars[i].Mpeak   = ps1data[i].Mpeak;
-
-    stars[i].sky     = ps1data[i].sky;
-    stars[i].dsky    = ps1data[i].dSky;
-
-    stars[i].fx      = ps1data[i].fx;
-    stars[i].fy      = ps1data[i].fy;
-    stars[i].df      = ps1data[i].df;
-
-    stars[i].psfChisq  = ps1data[i].psfChisq;
-    stars[i].psfQual   = ps1data[i].psfQual;
-    stars[i].crNsigma  = ps1data[i].crNsigma;
-    stars[i].extNsigma = ps1data[i].extNsigma;
-
-    stars[i].detID     = ps1data[i].detID;
-    stars[i].flags     = ps1data[i].flags;
-
-    // XXX not defined anyway
-    // stars[i].stargal   = ps1data[i].stargal;
-
-    /* these are set elsewhere */
-    stars[i].R       = 0.0;
-    stars[i].D       = 0.0;
-    stars[i].dR      = 0.0;
-    stars[i].dD      = 0.0;
-
-    stars[i].uR      = 0.0;
-    stars[i].uD      = 0.0;
-    stars[i].duR     = 0.0;
-    stars[i].duD     = 0.0;
-
-    stars[i].P       = 0.0;
-    stars[i].dP      = 0.0;
-
-    stars[i].Mcal    = 0;
-    stars[i].t       = 0;
-    stars[i].dt      = 0;
-    stars[i].airmass = 0;
-    stars[i].az      = 0;
-    stars[i].code    = 0;
-    stars[i].found   = 0;
-
-    /* these are not used */
-    stars[i].Map     = NAN;
-    stars[i].dophot  = 0;
-  }    
-  *nstars = Nstars;
-  return (stars);
-}
+	stars[i].measure.M      = NAN;
+    } else {
+	stars[i].measure.M      = ps1data[i].M + ZeroPt;
+    }
+    stars[i].measure.Map        = NAN;
+    stars[i].measure.dM         = ps1data[i].dM;
+    stars[i].measure.Sky        = ps1data[i].sky;
+    stars[i].measure.dSky       = ps1data[i].dSky;
+
+    stars[i].measure.FWx        = ShortPixels(ps1data[i].fx);
+    stars[i].measure.FWy        = ShortPixels(ps1data[i].fy);
+    stars[i].measure.theta      = ShortDegree(ps1data[i].df);
+
+    stars[i].measure.psfChisq  	= ps1data[i].psfChisq;
+    stars[i].measure.psfQual   	= ps1data[i].psfQual;
+    stars[i].measure.crNsigma  	= ps1data[i].crNsigma;
+    stars[i].measure.extNsigma 	= ps1data[i].extNsigma;
+
+    stars[i].measure.detID     	= ps1data[i].detID;
+    stars[i].measure.photFlags  = ps1data[i].flags;
+  }    
+  *nstars = Nstars;
+  return (stars);
+}
+
+Stars *Convert_PS1_V1 (FTable *table, int *nstars) {
+
+  int i, Nstars;
+  double ZeroPt;
+  Stars *stars;
+  CMF_PS1_V1 *ps1data;
+
+  ps1data = gfits_table_get_CMF_PS1_V1 (table, &Nstars, 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      = ShortPixels(ps1data[i].dX);
+    stars[i].measure.dYccd      = ShortPixels(ps1data[i].dY);
+
+    stars[i].measure.posangle   = ShortDegree(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.Sky        = ps1data[i].sky;
+    stars[i].measure.dSky       = ps1data[i].dSky;
+		        
+    stars[i].measure.psfChisq   = ps1data[i].psfChisq;
+    stars[i].measure.psfQual    = ps1data[i].psfQual;
+    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;
+
+    stars[i].measure.FWx        = ShortPixels(ps1data[i].fx);
+    stars[i].measure.FWy        = ShortPixels(ps1data[i].fy);
+    stars[i].measure.theta      = ShortDegree(ps1data[i].df);
+
+    stars[i].measure.Mxx        = ShortPixels(ps1data[i].Mxx);
+    stars[i].measure.Mxy        = ShortPixels(ps1data[i].Mxy);
+    stars[i].measure.Myy        = ShortPixels(ps1data[i].Myy);
+		        
+    stars[i].measure.photFlags  = ps1data[i].flags;
+
+    // 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/cnb_branch_20090215/Ohana/src/addstar/src/ReadStarsSDSS.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/src/ReadStarsSDSS.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/src/ReadStarsSDSS.c	(revision 21536)
@@ -140,35 +140,27 @@
     for (j = 0; j < NFILTER; j++) {
       N = NFILTER*i + j;
-      stars[N].X         = colc[N];
-      stars[N].Y         = rowc[N];
-      stars[N].dX        = colcErr[N];
-      stars[N].dY        = rowcErr[N];
-      stars[N].M         = psfCounts[N] + ZeroPt - zeropt[j];
-      stars[N].dM        = psfCountsErr[N];
-      stars[N].Map       = fiberCounts[N] + ZeroPt - zeropt[j];
-      stars[N].Mpeak     = NAN;
-      stars[N].sky       = sky[N]; // adjust this to counts?
-      stars[N].dsky      = skyErr[N];
-      stars[N].fx        = seeing[j]; // reported in arcsec?
-      stars[N].fy        = seeing[j];
-      stars[N].df        = 0.0;
-      stars[N].psfChisq  = prob_psf[N]; // XXX not really the correct value...
-      stars[N].psfQual   = 0.0;
-      stars[N].crNsigma  = 0.0;
-      stars[N].extNsigma = 0.0;
-      stars[N].detID     = N;
-      stars[N].R         = ra[i] + dCOS(dec[i]) * offsetRa[N] / 3600.0;
-      stars[N].D         = dec[i] + offsetDec[N] / 3600.0;
-      stars[N].dR        = NAN;
-      stars[N].dD        = NAN;
-      stars[N].uR        = 0.0; // I don't trust the SDSS proper motions
-      stars[N].uD        = 0.0; // I don't trust the SDSS proper motions
-      stars[N].duR       = 0.0;
-      stars[N].duD       = 0.0;
-      stars[N].P         = 0.0;
-      stars[N].dP        = 0.0;
-      stars[N].Mcal      = 0.0;
-      stars[N].t         = tzero[j] + clockRate*rowc[N]; // time since row 0
-      stars[N].dt        = 53.907456; // is this 2048*clockRate ?
+      InitStar (&stars[N]);
+      
+      // any values not explicitly set are left at 0.0
+      stars[N].average.R         = ra[i] + dCOS(dec[i]) * offsetRa[N] / 3600.0;
+      stars[N].average.D         = dec[i] + offsetDec[N] / 3600.0;
+      stars[N].average.dR        = NAN;
+      stars[N].average.dD        = NAN;
+
+      stars[N].measure.Xccd      = colc[N];
+      stars[N].measure.Yccd      = rowc[N];
+      stars[N].measure.dXccd     = ShortPixels(colcErr[N]);
+      stars[N].measure.dYccd     = ShortPixels(rowcErr[N]);
+      stars[N].measure.M         = psfCounts[N] + ZeroPt - zeropt[j];
+      stars[N].measure.dM        = psfCountsErr[N];
+      stars[N].measure.Map       = fiberCounts[N] + ZeroPt - zeropt[j];
+      stars[N].measure.Sky       = sky[N]; // adjust this to counts?
+      stars[N].measure.dSky      = skyErr[N];
+      stars[N].measure.FWx       = ShortPixels(seeing[j]); // reported in arcsec?
+      stars[N].measure.FWy       = ShortPixels(seeing[j]);
+      stars[N].measure.psfChisq  = prob_psf[N]; // XXX not really the correct value...
+      stars[N].measure.detID     = N;
+      stars[N].measure.t         = tzero[j] + clockRate*rowc[N]; // time since row 0
+      stars[N].measure.dt        = 53.907456; // is this 2048*clockRate ?
 
       SetSDSSFlags (&stars[N], flags[N], flags2[N]);
@@ -182,14 +174,11 @@
       double Latitude = 32.7803611755; // degrees
 
-      jd = ohana_sec_to_jd (stars[N].t);
+      jd = ohana_sec_to_jd (stars[N].measure.t);
       sidtime  = 15.0*ohana_lst (jd, Longitude); // sidtime in degrees
-      altaz (&alt, &az, sidtime - stars[N].R, stars[N].D, Latitude);
-
-      stars[N].airmass   = 1.0 / dCOS(90.0 - alt);
-      stars[N].az        = az;
-
-      stars[N].code      = photcode[j];
-      stars[N].found     = -1;
-      stars[N].dophot    = 0;
+      altaz (&alt, &az, sidtime - stars[N].average.R, stars[N].average.D, Latitude);
+
+      stars[N].measure.airmass   = 1.0 / dCOS(90.0 - alt);
+      stars[N].measure.az        = az;
+      stars[N].measure.photcode  = photcode[j];
     }
   }    
@@ -202,9 +191,9 @@
     strcpy (images[N].coords.ctype, "RA---TAN");
     
-    images[N].coords.crval1 = stars[0].R;
-    images[N].coords.crval2 = stars[0].D;
+    images[N].coords.crval1 = stars[0].average.R;
+    images[N].coords.crval2 = stars[0].average.D;
     
-    images[N].coords.crpix1 = stars[0].X;
-    images[N].coords.crpix2 = stars[0].Y;
+    images[N].coords.crpix1 = stars[0].measure.Xccd;
+    images[N].coords.crpix2 = stars[0].measure.Yccd;
     images[N].coords.cdelt1 = images[N].coords.cdelt2 = 0.4 / 3600.0;
 
@@ -251,5 +240,5 @@
 
     images[N].trate = clockRate * 1e-4;
-    images[N].secz = stars[0].airmass;
+    images[N].secz = stars[0].measure.airmass;
     images[N].ccdnum = camcol;
 
@@ -257,5 +246,5 @@
     images[N].Mcal = 0.0;
     images[N].Xm   = NAN_S_SHORT;
-    images[N].code = 0;
+    images[N].flags = 0;
 
     images[N].nstar = Nstars;
@@ -297,19 +286,19 @@
 
   // XXX this is wrong, need to roll left to set the correct bit 
-  if (flags1 & 0x00000002) star[0].flags |= 0x0001; // BRIGHT            - 1  1
-  if (flags1 & 0x00000004) star[0].flags |= 0x0002; // EDGE              - 1  2
-  if (flags1 & 0x00000008) star[0].flags |= 0x0004; // BLENDED           - 1  3
-  if (flags1 & 0x00000010) star[0].flags |= 0x0008; // CHILD             - 1  4
-  if (flags1 & 0x00000020) star[0].flags |= 0x0010; // PEAKCENTER        - 1  5
-  if (flags1 & 0x00000040) star[0].flags |= 0x0020; // NODEBLEND         - 1  6
-  if (flags1 & 0x00040000) star[0].flags |= 0x0040; // SATUR             - 1 18
-  if (flags1 & 0x00080000) star[0].flags |= 0x0080; // NOTCHECKED        - 1 19
-  if (flags1 & 0x10000000) star[0].flags |= 0x0100; // BINNED1           - 1 28
-  if (flags1 & 0x20000000) star[0].flags |= 0x0200; // BINNED2           - 1 29
-  if (flags1 & 0x40000000) star[0].flags |= 0x0400; // BINNED4           - 1 30
-  if (flags2 & 0x00000040) star[0].flags |= 0x0800; // LOCAL_EDGE        - 2  7
-  if (flags2 & 0x00000800) star[0].flags |= 0x1000; // INTERP_CENTER     - 2 12
-  if (flags2 & 0x00002000) star[0].flags |= 0x2000; // DEBLEND_NOPEAK    - 2 14
-  if (flags2 & 0x02000000) star[0].flags |= 0x4000; // NOTCHECKED_CENTER - 2 26
+  if (flags1 & 0x00000002) star[0].measure.photFlags |= 0x0001; // BRIGHT            - 1  1
+  if (flags1 & 0x00000004) star[0].measure.photFlags |= 0x0002; // EDGE              - 1  2
+  if (flags1 & 0x00000008) star[0].measure.photFlags |= 0x0004; // BLENDED           - 1  3
+  if (flags1 & 0x00000010) star[0].measure.photFlags |= 0x0008; // CHILD             - 1  4
+  if (flags1 & 0x00000020) star[0].measure.photFlags |= 0x0010; // PEAKCENTER        - 1  5
+  if (flags1 & 0x00000040) star[0].measure.photFlags |= 0x0020; // NODEBLEND         - 1  6
+  if (flags1 & 0x00040000) star[0].measure.photFlags |= 0x0040; // SATUR             - 1 18
+  if (flags1 & 0x00080000) star[0].measure.photFlags |= 0x0080; // NOTCHECKED        - 1 19
+  if (flags1 & 0x10000000) star[0].measure.photFlags |= 0x0100; // BINNED1           - 1 28
+  if (flags1 & 0x20000000) star[0].measure.photFlags |= 0x0200; // BINNED2           - 1 29
+  if (flags1 & 0x40000000) star[0].measure.photFlags |= 0x0400; // BINNED4           - 1 30
+  if (flags2 & 0x00000040) star[0].measure.photFlags |= 0x0800; // LOCAL_EDGE        - 2  7
+  if (flags2 & 0x00000800) star[0].measure.photFlags |= 0x1000; // INTERP_CENTER     - 2 12
+  if (flags2 & 0x00002000) star[0].measure.photFlags |= 0x2000; // DEBLEND_NOPEAK    - 2 14
+  if (flags2 & 0x02000000) star[0].measure.photFlags |= 0x4000; // NOTCHECKED_CENTER - 2 26
   return (TRUE);
 
Index: /branches/cnb_branch_20090215/Ohana/src/addstar/src/ReadStarsTEXT.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/src/ReadStarsTEXT.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/src/ReadStarsTEXT.c	(revision 21536)
@@ -7,7 +7,7 @@
 
   int j, N, Nextra, Ninstar, Nskip, Nbytes, nbytes;
-  int done;
+  int done, itmp;
   char *buffer, *c, *c2;
-  double tmp;
+  double tmp, fx, fy, df;
   double ZeroPt;
   Stars *stars;
@@ -66,17 +66,20 @@
     Nextra = nbytes % BYTES_STAR;
     for (j = 0; (j < Ninstar) && (N < *nstars); j++, N++) {
-      dparse (&stars[N].X,  1, &buffer[j*BYTES_STAR]);
-      dparse (&stars[N].Y,  2, &buffer[j*BYTES_STAR]);
-      dparse (&stars[N].M,  3, &buffer[j*BYTES_STAR]);
-      if ((stars[N].M > ZeroPt) || isnan(stars[N].M)) {
-	stars[N].M = NAN;
+      InitStar (&stars[N]);
+      fparse (&stars[N].measure.Xccd,  1, &buffer[j*BYTES_STAR]);
+      fparse (&stars[N].measure.Yccd,  2, &buffer[j*BYTES_STAR]);
+      fparse (&stars[N].measure.M,  3, &buffer[j*BYTES_STAR]);
+      if ((stars[N].measure.M > ZeroPt) || isnan(stars[N].measure.M)) {
+	stars[N].measure.M = NAN;
       }
 
       /* cmp files carry dM in millimags */
       dparse (&tmp, 4, &buffer[j*BYTES_STAR]);
-      stars[N].dM = 0.001*tmp;
+      stars[N].measure.dM = 0.001*tmp;
 
+      // the dophot type information get pushed into the upper 2 bytes of photFlags
       dparse (&tmp,         5, &buffer[j*BYTES_STAR]);
-      stars[N].dophot = tmp;
+      itmp = tmp;
+      stars[N].measure.photFlags = (itmp << 16);
 
       // XXX I've removed the Mgal field from the measure.d table, and am using Map
@@ -87,8 +90,12 @@
 
       // dparse (&stars[N].Mgal, 7, &buffer[j*BYTES_STAR]);
-      dparse (&stars[N].Map,  8, &buffer[j*BYTES_STAR]);
-      dparse (&stars[N].fx,   9, &buffer[j*BYTES_STAR]);
-      dparse (&stars[N].fy,  10, &buffer[j*BYTES_STAR]);
-      dparse (&stars[N].df,  11, &buffer[j*BYTES_STAR]);
+      fparse (&stars[N].measure.Map,  8, &buffer[j*BYTES_STAR]);
+      dparse (&fx,   9, &buffer[j*BYTES_STAR]);
+      dparse (&fy,  10, &buffer[j*BYTES_STAR]);
+      dparse (&df,  11, &buffer[j*BYTES_STAR]);
+
+      stars[N].measure.FWx   = ShortPixels (fx);
+      stars[N].measure.FWy   = ShortPixels (fy);
+      stars[N].measure.theta = ShortDegree (df);
     }
   }
Index: /branches/cnb_branch_20090215/Ohana/src/addstar/src/SEDfit.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/src/SEDfit.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/src/SEDfit.c	(revision 21536)
@@ -164,5 +164,5 @@
     outcat[0].average[Nave].measureOffset = Nmeas;
     outcat[0].average[Nave].missingOffset = -1;
-    outcat[0].average[Nave].code          = 0;
+    outcat[0].average[Nave].flags         = 0;
 
     for (j = 0; j < Nsec; j++) {
@@ -181,20 +181,20 @@
     for (j = 0; valid && (j < Nmodel); j++) {
       n = modelRow[j];
-      outcat[0].measure[Nmeas].dR       = 0.0;
-      outcat[0].measure[Nmeas].dD       = 0.0;
-      outcat[0].measure[Nmeas].M        = table[0].row[minFit.row][0].mags[n] + minFit.Md;
-      outcat[0].measure[Nmeas].dM       = 0.0;
-      outcat[0].measure[Nmeas].Mcal     = 0;
-      outcat[0].measure[Nmeas].t        = TIMEREF;
-      outcat[0].measure[Nmeas].averef   = Nave;
-      outcat[0].measure[Nmeas].photcode = table[0].code[n];
-      outcat[0].measure[Nmeas].dophot   = 0;
-      outcat[0].measure[Nmeas].dbFlags  = 0;
-      outcat[0].measure[Nmeas].dt       = 0xffff;
-
-      outcat[0].measure[Nmeas].airmass  = 0;
-      outcat[0].measure[Nmeas].FWx      = NAN_S_SHORT;
-      outcat[0].measure[Nmeas].FWy      = NAN_S_SHORT;
-      outcat[0].measure[Nmeas].theta    = NAN_S_SHORT;
+      outcat[0].measure[Nmeas].dR        = 0.0;
+      outcat[0].measure[Nmeas].dD        = 0.0;
+      outcat[0].measure[Nmeas].M         = table[0].row[minFit.row][0].mags[n] + minFit.Md;
+      outcat[0].measure[Nmeas].dM        = 0.0;
+      outcat[0].measure[Nmeas].Mcal      = 0;
+      outcat[0].measure[Nmeas].t         = TIMEREF;
+      outcat[0].measure[Nmeas].averef    = Nave;
+      outcat[0].measure[Nmeas].photcode  = table[0].code[n];
+      outcat[0].measure[Nmeas].photFlags = 0;
+      outcat[0].measure[Nmeas].dbFlags   = 0;
+      outcat[0].measure[Nmeas].dt        = 0xffff;
+					 
+      outcat[0].measure[Nmeas].airmass   = 0;
+      outcat[0].measure[Nmeas].FWx       = NAN_S_SHORT;
+      outcat[0].measure[Nmeas].FWy       = NAN_S_SHORT;
+      outcat[0].measure[Nmeas].theta     = NAN_S_SHORT;
 
       outcat[0].average[Nave].Nmeasure++;
Index: /branches/cnb_branch_20090215/Ohana/src/addstar/src/SkyListForStars.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/src/SkyListForStars.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/src/SkyListForStars.c	(revision 21536)
@@ -1,3 +1,15 @@
 # include "addstar.h"
+
+void sort_stars_ra (Stars *stars, int N) {
+
+# define SWAPFUNC(A,B){ Stars tmp; tmp = stars[A]; stars[A] = stars[B]; stars[B] = tmp; }
+# define COMPARE(A,B)(stars[A].average.R < stars[B].average.R)
+
+  OHANA_SORT (N, COMPARE, SWAPFUNC);
+
+# undef SWAPFUNC
+# undef COMPARE
+
+}
 
 SkyList *SkyListForStars (SkyTable *table, int depth, Stars *stars, int Nstars) {
@@ -17,14 +29,14 @@
   sort_stars_ra (stars, Nstars); /* sort by RA */
   for (i = 0; i < Nstars; i++) {
-    if (stars[i].found) continue;
-    here = SkyRegionByPoint (table, depth, stars[i].R, stars[i].D);
-    stars[i].found = TRUE;
+    if (stars[i].found == -2) continue;
+    here = SkyRegionByPoint (table, depth, stars[i].average.R, stars[i].average.D);
+    stars[i].found = -2;
     /* search forward for all contained stars */
     for (j = i; j < Nstars; j++) {
-      if (stars[j].R >= here[0].regions[0][0].Rmax) break;
-      if (stars[j].R <  here[0].regions[0][0].Rmin) break;
-      if (stars[j].D <  here[0].regions[0][0].Dmin) continue;
-      if (stars[j].D >= here[0].regions[0][0].Dmax) continue;
-      stars[j].found = TRUE;
+      if (stars[j].average.R >= here[0].regions[0][0].Rmax) break;
+      if (stars[j].average.R <  here[0].regions[0][0].Rmin) break;
+      if (stars[j].average.D <  here[0].regions[0][0].Dmin) continue;
+      if (stars[j].average.D >= here[0].regions[0][0].Dmax) continue;
+      stars[j].found = -2;
     }
     list[0].regions[Nr] = here[0].regions[0];
Index: /branches/cnb_branch_20090215/Ohana/src/addstar/src/StarOps.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/src/StarOps.c	(revision 21536)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/src/StarOps.c	(revision 21536)
@@ -0,0 +1,28 @@
+# include "addstar.h"
+
+int InitStar (Stars *star) {
+
+    memset (&star[0].average, 0, sizeof(Average));
+    memset (&star[0].measure, 0, sizeof(Measure));
+    star[0].found = -1; // found == -1 -> not yet found (use enums?)
+
+    return TRUE;
+}
+
+short ShortPixels (float pixels) {
+
+    short value;
+
+    value = 100*pixels;
+
+    return value;
+}
+
+short ShortDegree (float degrees) {
+
+    short value;
+
+    value = (0xffff/360.0)*degrees;
+
+    return value;
+}
Index: /branches/cnb_branch_20090215/Ohana/src/addstar/src/UpdateImageIDs.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/src/UpdateImageIDs.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/src/UpdateImageIDs.c	(revision 21536)
@@ -43,10 +43,9 @@
 
   for (i = 0; i < Nstars; i++) {
-    stars[i].imageID += imageID;
+    stars[i].measure.imageID += imageID;
   }
 
   imageID += Nimages;
   status = gfits_modify (&db.header, "IMAGEID", "%u", 1, imageID);
- 
 
   if (isEmpty) {
Index: /branches/cnb_branch_20090215/Ohana/src/addstar/src/addstar.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/src/addstar.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/src/addstar.c	(revision 21536)
@@ -135,5 +135,5 @@
 	break;
       case M_REFCAT:
-	stars = grefcat (argv[1], skylist[0].regions[i], options.photcode, &Nstars);
+	stars = greference (argv[1], skylist[0].regions[i], options.photcode, &Nstars);
       case M_REFLIST:
 	subset = find_subset (skylist[0].regions[i], stars, Nstars, &Nsubset);
Index: /branches/cnb_branch_20090215/Ohana/src/addstar/src/airmass.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/src/airmass.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/src/airmass.c	(revision 21536)
@@ -1,5 +1,5 @@
 # include "addstar.h"
 
-static int AirmassQuality = FALSE;
+static int AirmassQuality = TRUE;
 
 void SetAirmassQuality (int quality) {
@@ -25,2 +25,21 @@
   return (secz);
 }
+
+// ha/dec -> az
+float azimuth (double ha, double dec, double latitude) {
+
+  double rdec, rlat, rha;
+  double sinh, cosh;
+  float az;
+
+  rdec = RAD_DEG*dec;
+  rha = RAD_DEG*ha;
+  rlat = RAD_DEG*latitude;
+
+  sinh = - cos (rdec) * sin (rha);
+  cosh =   sin (rdec) * cos (rlat) - cos (rdec) * cos (rha) * sin (rlat);
+
+  az = DEG_RAD * atan2 (sinh, cosh);
+
+  return az;
+}
Index: /branches/cnb_branch_20090215/Ohana/src/addstar/src/args.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/src/args.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/src/args.c	(revision 21536)
@@ -28,4 +28,8 @@
     remove_argument (N, &argc, argv);
   }
+  if ((N = get_argument (argc, argv, "-resort"))) {
+    options.mode = M_RESORT;
+    remove_argument (N, &argc, argv);
+  }
   if ((N = get_argument (argc, argv, "-fakeimage"))) {
     options.mode = M_FAKEIMAGE;
@@ -36,8 +40,4 @@
     remove_argument (N, &argc, argv);
     FAKE_THETA = atof (argv[N]);
-    remove_argument (N, &argc, argv);
-  }
-  if ((N = get_argument (argc, argv, "-resort"))) {
-    options.mode = M_RESORT;
     remove_argument (N, &argc, argv);
   }
@@ -221,8 +221,12 @@
   /*** optional situations ***/
   /* choose high quality airmass vs low quality airmass (per-star vs per-image) */
-  QUALITY_AIRMASS = FALSE;
+  QUALITY_AIRMASS = TRUE;
   if ((N = get_argument (argc, argv, "-quality-airmass"))) {
     remove_argument (N, &argc, argv);
     QUALITY_AIRMASS = TRUE;
+  }
+  if ((N = get_argument (argc, argv, "-quick-airmass"))) {
+    remove_argument (N, &argc, argv);
+    QUALITY_AIRMASS = FALSE;
   }
   /* choose high quality airmass vs low quality airmass (per-star vs per-image) */
@@ -310,8 +314,10 @@
 
   fprintf (stderr, "USAGE: addstar (filename)\n");
+  fprintf (stderr, "USAGE: addstar -list (filename)\n");
   fprintf (stderr, "USAGE: addstar -cat (catalog)\n");
   fprintf (stderr, "USAGE: addstar -ref (filename)\n");
   fprintf (stderr, "USAGE: addstar -fakeimage (ra) (dec) (theta) (name)\n");
   fprintf (stderr, "USAGE: addstar -resort (SkyRegion)\n");
+  fprintf (stderr, "USAGE: addstar -ppm (filename)\n");
   exit (2);
 }
@@ -322,4 +328,6 @@
   fprintf (stderr, "  addstar (filename)\n");
   fprintf (stderr, "     add specified image (cmp format) to database\n\n");
+  fprintf (stderr, "  addstar -list (filename)\n");
+  fprintf (stderr, "     add list of images (cmp format) to database\n\n");
   fprintf (stderr, "  addstar -ref (filename)");
   fprintf (stderr, "     add ASCII data (ra dec mag dmag) to database\n\n");
@@ -328,4 +336,8 @@
   fprintf (stderr, "  addstar -resort (SkyRegion)");
   fprintf (stderr, "     perform measure sorting for the specified catalog\n\n");
+  fprintf (stderr, "  addstar -fakeimage (ra) (dec) (theta) (name)");
+  fprintf (stderr, "     insert a fake image in the db\n\n");
+  fprintf (stderr, "  addstar -pmm (filename)");
+  fprintf (stderr, "     insert pmm table into database\n\n");
 
   fprintf (stderr, "  optional flags:\n");
@@ -340,14 +352,25 @@
   fprintf (stderr, "  -missed               	  : skipped 'missed' entries\n");
   fprintf (stderr, "  -replace              	  : replace time/photcode measurements (no duplication)\n");
-  fprintf (stderr, "  -closest             	  : use closest-star algorith\n");
+  fprintf (stderr, "  -closest             	  : use closest-star algorith (default)\n");
+  fprintf (stderr, "  -all-matches             	  : use all-matches algorith\n");
   fprintf (stderr, "  -nosort             	  : don't re-sort the measure entries (improves speed)\n");
   fprintf (stderr, "  -update             	  : only update the new rows (forces -nosort)\n");
+  fprintf (stderr, "  -force-sort             	  : \n");
   fprintf (stderr, "  -image                	  : only insert image data\n");
   fprintf (stderr, "  -cal                  	  : perform zero-point calibration\n");
+  fprintf (stderr, "  -excal                  	  : apply supplied zero-point calibration\n");
+  fprintf (stderr, "  -incal                  	  : perform zero-point calibration\n");
+  fprintf (stderr, "  -quality-airmass            : use per-star airmass values (default)\n");
+  fprintf (stderr, "  -quick-airmass              : use per-image airmass values\n");
+  fprintf (stderr, "  -subpix             	  : apply subpixel corrections\n");
   fprintf (stderr, "  -skyprobe             	  : specify skyprobe mode\n");
+  fprintf (stderr, "  -2massquality            	  : define 2MASS quality flags to keep\n");
   fprintf (stderr, "  -accept               	  : accept bad astrometry from header\n");
   fprintf (stderr, "  -accept-astrom          	  : accept bad astrometry from header\n");
   fprintf (stderr, "  -accept-motion           	  : accept proper-motion data from reference\n");
+  fprintf (stderr, "  -accept-time           	  : use TZERO supplied in header\n");
+  fprintf (stderr, "  -no-stars                	  : skip the stars\n");
   fprintf (stderr, "  -force                	  : force read of database with inconsistent info\n");
+  fprintf (stderr, "  -textmode                	  : force textmode for file (ignore header clues)\n");
   fprintf (stderr, "  -v                    	  : verbose mode\n");
   fprintf (stderr, "  -dump (mode)          	  : output test data. Currently supported values for mode are: 'rawdata', 'cal'.\n");
Index: /branches/cnb_branch_20090215/Ohana/src/addstar/src/dump.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/src/dump.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/src/dump.c	(revision 21536)
@@ -11,7 +11,7 @@
     fprintf (f, "%4d  %10.6f %10.6f  %8.2f %8.2f  %7.2f %7.2f\n", 
 	     i, 
-	     stars[i].R, stars[i].D,
-	     stars[i].X, stars[i].Y,
-	     stars[i].M, stars[i].dM);
+	     stars[i].average.R, stars[i].average.D,
+	     stars[i].measure.Xccd, stars[i].measure.Yccd,
+	     stars[i].measure.M, stars[i].measure.dM);
   }
 
Index: /branches/cnb_branch_20090215/Ohana/src/addstar/src/fakeimage.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/src/fakeimage.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/src/fakeimage.c	(revision 21536)
@@ -129,7 +129,7 @@
     image[i+1].ccdnum = 0xff;
 
-    image[i+1].Mcal = 0.0;
-    image[i+1].Xm   = NAN_S_SHORT;
-    image[i+1].code = 0;
+    image[i+1].Mcal  = 0.0;
+    image[i+1].Xm    = NAN_S_SHORT;
+    image[i+1].flags = 0;
 
     image[i+1].nstar = 0;
@@ -189,5 +189,5 @@
   image[0].Mcal = 0.0;
   image[0].Xm   = NAN_S_SHORT;
-  image[0].code = 0;
+  image[0].flags = 0;
   image[0].nstar = 0;
   image[0].Myyyy = 0;
Index: /branches/cnb_branch_20090215/Ohana/src/addstar/src/find_matches.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/src/find_matches.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/src/find_matches.c	(revision 21536)
@@ -62,8 +62,8 @@
   strcpy (tcoords.ctype, "RA---ARC");
 
-  /* build spatial index (RA sort) */
+  /* build spatial index (RA sort) referencing input array sequence */
   Nstars = 0;
   for (i = 0; i < NstarsIn; i++) {
-    status = RD_to_XY (&X1[Nstars], &Y1[Nstars], stars[i].R, stars[i].D, &tcoords);
+    status = RD_to_XY (&X1[Nstars], &Y1[Nstars], stars[i].average.R, stars[i].average.D, &tcoords);
     if (!status) continue;
     N1[Nstars] = i;
@@ -104,5 +104,5 @@
   /** find matched stars **/
   for (i = j = 0; (i < Nstars) && (j < Nave); ) {
-        if (!finite(X1[i]) || !finite(Y1[i])) { 
+    if (!finite(X1[i]) || !finite(Y1[i])) { 
       i++; 
       continue;
@@ -147,60 +147,35 @@
 
       /** add measurements for this star **/
-      /** dR,dD now represent arcsec **/
-      catalog[0].measure[Nmeas].dR       = 3600.0*(catalog[0].average[n].R - stars[N].R);
+
+      // set the new measurements
+      catalog[0].measure[Nmeas]          = stars[N].measure;
+
+      // 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].dbFlags  = 0;
+      catalog[0].measure[Nmeas].averef   = n; // this must be an absolute sequence number, if partial average is loaded 
+      catalog[0].measure[Nmeas].objID    = catalog[0].average[n].objID;
+      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].R += 360.0;
-	  catalog[0].measure[Nmeas].dR = 3600.0*(catalog[0].average[n].R - stars[N].R);
+	  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].R -= 360.0;
-	  catalog[0].measure[Nmeas].dR = 3600.0*(catalog[0].average[n].R - stars[N].R);
+	  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].R, stars[N].D,
+		   stars[N].average.R, stars[N].average.D,
 		   X1[i], X2[J], 
 		   Y1[i], Y2[J]);
       }
-      catalog[0].measure[Nmeas].dD       = 3600.0*(catalog[0].average[n].D - stars[N].D);
-
-      catalog[0].measure[Nmeas].Xccd     = stars[N].X;
-      catalog[0].measure[Nmeas].Yccd     = stars[N].Y;
-
-      catalog[0].measure[Nmeas].M        = stars[N].M;
-      catalog[0].measure[Nmeas].dM       = stars[N].dM;  /* error in input files stored in thousandths of mag */
-      catalog[0].measure[Nmeas].Mcal     = stars[N].Mcal;
-      catalog[0].measure[Nmeas].t        = stars[N].t;
-      catalog[0].measure[Nmeas].averef   = n;              /* this must be an absolute sequence number, if partial average is loaded */
-      catalog[0].measure[Nmeas].photcode = stars[N].code;  /* photcode */
-      catalog[0].measure[Nmeas].dophot   = stars[N].dophot;  
-      catalog[0].measure[Nmeas].dbFlags  = 0;
-      catalog[0].measure[Nmeas].dt       = stars[N].dt;
-      catalog[0].measure[Nmeas].airmass  = stars[N].airmass;
-
-      catalog[0].measure[Nmeas].photFlags = stars[N].flags;
-      catalog[0].measure[Nmeas].qPSF      = stars[N].psfQual;
-      catalog[0].measure[Nmeas].psfChisq  = stars[N].psfChisq;
-      catalog[0].measure[Nmeas].crNsigma  = stars[N].crNsigma;
-      catalog[0].measure[Nmeas].extNsigma = stars[N].extNsigma;
-      catalog[0].measure[Nmeas].Sky       = stars[N].sky;
-      catalog[0].measure[Nmeas].dSky      = stars[N].dsky;
-
-      catalog[0].measure[Nmeas].stargal   = 0; // XXX not yet set
-
-      catalog[0].measure[Nmeas].detID     = stars[N].detID;
-      catalog[0].measure[Nmeas].imageID   = stars[N].imageID;
-
-      catalog[0].measure[Nmeas].dXccd     = stars[N].dX;
-      catalog[0].measure[Nmeas].dYccd     = stars[N].dY;
-
-      catalog[0].measure[Nmeas].Map      = stars[N].Map;
-      catalog[0].measure[Nmeas].FWx      = 100*stars[N].fx;
-      catalog[0].measure[Nmeas].FWy      = 100*stars[N].fy;
-      catalog[0].measure[Nmeas].theta    = (0xffff/360.0)*stars[N].df;
-	
+
       /* adds the measurement to the calibration if appropriate color terms are found */
       /* we call this before (optionally) setting the average magnitude to avoid auto-correlations */
@@ -266,71 +241,56 @@
     N = N1[i];
     if (stars[N].found >= 0) continue;
-    if (!IN_REGION (stars[N].R, stars[N].D)) continue;
-
-    catalog[0].average[Nave].R         	   = stars[N].R;
-    catalog[0].average[Nave].D         	   = stars[N].D;
-    catalog[0].average[Nave].Xp        	   = 0;
+    if (!IN_REGION (stars[N].average.R, stars[N].average.D)) continue;
+
+    catalog[0].average[Nave].R         	   = stars[N].average.R;
+    catalog[0].average[Nave].D         	   = stars[N].average.D;
+    catalog[0].average[Nave].dR        	   = 0;
+    catalog[0].average[Nave].dD        	   = 0;
+
     catalog[0].average[Nave].Nmeasure      = 1;
     catalog[0].average[Nave].Nmissing      = 0;
+    catalog[0].average[Nave].Nextend       = 0;
+
     catalog[0].average[Nave].measureOffset = Nmeas;
     catalog[0].average[Nave].missingOffset = -1;
-    catalog[0].average[Nave].code          = 0;
-
-    catalog[0].average[Nave].dR        = 0;
-    catalog[0].average[Nave].dD        = 0;
-    catalog[0].average[Nave].uR        = 0;
-    catalog[0].average[Nave].uD        = 0;
-    catalog[0].average[Nave].duR       = 0;
-    catalog[0].average[Nave].duD       = 0;
-    catalog[0].average[Nave].P         = 0;
-    catalog[0].average[Nave].dP        = 0;
-
-    catalog[0].average[Nave].objID     = objID;
-    catalog[0].average[Nave].catID     = catID;
+    catalog[0].average[Nave].extendOffset  = -1;
+
+    catalog[0].average[Nave].uR        	   = 0;
+    catalog[0].average[Nave].uD        	   = 0;
+    catalog[0].average[Nave].duR       	   = 0;
+    catalog[0].average[Nave].duD       	   = 0;
+    catalog[0].average[Nave].P         	   = 0;
+    catalog[0].average[Nave].dP        	   = 0;
+
+    catalog[0].average[Nave].Xp        	   = 0;
+    catalog[0].average[Nave].ChiSq    	   = 0.0;
+    catalog[0].average[Nave].Npos    	   = 0;
+
+    catalog[0].average[Nave].objID     	   = objID;
+    catalog[0].average[Nave].catID     	   = catID;
+    catalog[0].average[Nave].flags         = 0;
+
     objID ++;
 
     for (j = 0; j < Nsecfilt; j++) {
-      catalog[0].secfilt[Nave*Nsecfilt+j].M  = NAN;
-      catalog[0].secfilt[Nave*Nsecfilt+j].dM = NAN;
-      catalog[0].secfilt[Nave*Nsecfilt+j].Xm = NAN_S_SHORT;
-    }
-
-    catalog[0].measure[Nmeas].Xccd     = stars[N].X;
-    catalog[0].measure[Nmeas].Yccd     = stars[N].Y;
-
+      catalog[0].secfilt[Nave*Nsecfilt+j].M    	= NAN;
+      catalog[0].secfilt[Nave*Nsecfilt+j].dM   	= NAN;
+      catalog[0].secfilt[Nave*Nsecfilt+j].Xm   	= NAN_S_SHORT;
+      catalog[0].secfilt[Nave*Nsecfilt+j].M_20 	= NAN_S_SHORT;
+      catalog[0].secfilt[Nave*Nsecfilt+j].M_80 	= NAN_S_SHORT;
+      catalog[0].secfilt[Nave*Nsecfilt+j].Ncode = 0;
+      catalog[0].secfilt[Nave*Nsecfilt+j].Nused = 0;
+    }
+
+    // supply the measurments from this detection
+    catalog[0].measure[Nmeas]           = stars[N].measure;
+
+    // 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].M        	= stars[N].M;
-    catalog[0].measure[Nmeas].dM       	= stars[N].dM;
-    catalog[0].measure[Nmeas].Mcal  	= stars[N].Mcal;
-    catalog[0].measure[Nmeas].t        	= stars[N].t;
-    catalog[0].measure[Nmeas].averef   	= Nave;           /* XXX EAM : must be absolute Nave if partial read */
-    catalog[0].measure[Nmeas].photcode  = stars[N].code;  /* photcode */
-    catalog[0].measure[Nmeas].dophot   	= stars[N].dophot;  
     catalog[0].measure[Nmeas].dbFlags 	= 0;
-    catalog[0].measure[Nmeas].dt    	= stars[N].dt;
-    catalog[0].measure[Nmeas].airmass   = stars[N].airmass;
-
-    catalog[0].measure[Nmeas].photFlags = stars[N].flags;
-    catalog[0].measure[Nmeas].qPSF      = stars[N].psfQual;
-    catalog[0].measure[Nmeas].psfChisq  = stars[N].psfChisq;
-    catalog[0].measure[Nmeas].crNsigma  = stars[N].crNsigma;
-    catalog[0].measure[Nmeas].extNsigma = stars[N].extNsigma;
-    catalog[0].measure[Nmeas].Sky       = stars[N].sky;
-    catalog[0].measure[Nmeas].dSky      = stars[N].dsky;
-
-    catalog[0].measure[Nmeas].stargal   = 0; // XXX not yet set
-
-    catalog[0].measure[Nmeas].detID     = stars[N].detID;
-    catalog[0].measure[Nmeas].imageID   = stars[N].imageID;
-
-    catalog[0].measure[Nmeas].dXccd     = stars[N].dX;
-    catalog[0].measure[Nmeas].dYccd     = stars[N].dY;
-
-    catalog[0].measure[Nmeas].Map  	= stars[N].Map;
-    catalog[0].measure[Nmeas].FWx      	= 100*stars[N].fx;
-    catalog[0].measure[Nmeas].FWy      	= 100*stars[N].fy;
-    catalog[0].measure[Nmeas].theta    	= (0xffff/360.0)*stars[N].df;
-    /* XXX replace df here with theta, right? */
+    catalog[0].measure[Nmeas].averef   	= Nave; // XXX EAM : must be absolute Nave if partial read
+    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 */
Index: /branches/cnb_branch_20090215/Ohana/src/addstar/src/find_matches_closest.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/src/find_matches_closest.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/src/find_matches_closest.c	(revision 21536)
@@ -7,6 +7,6 @@
   double *X1, *Y1, *X2, *Y2;
   double dX, dY, dR;
-  int *N1, *N2,  *next_meas, *next_miss;
-  int Nave, NAVE, Nmeas, NMEAS, Nmiss, NMISS, Nmatch;
+  int *N1, *N2,  *next_meas;
+  int Nave, NAVE, Nmeas, NMEAS, Nmatch;
   int Nsecfilt, Nsec;
   unsigned int objID, catID;
@@ -37,5 +37,4 @@
   Nmatch = 0;
   NMEAS = Nmeas = catalog[0].Nmeasure;
-  NMISS = Nmiss = catalog[0].Nmissing;
 
   // current max obj ID for this catalog
@@ -66,5 +65,5 @@
   Nstars = 0;
   for (i = 0; i < NstarsIn; i++) {
-    status = RD_to_XY (&X1[Nstars], &Y1[Nstars], stars[i].R, stars[i].D, &tcoords);
+    status = RD_to_XY (&X1[Nstars], &Y1[Nstars], stars[i].average.R, stars[i].average.D, &tcoords);
     if (!status) continue;
     N1[Nstars] = i;
@@ -92,5 +91,5 @@
   if (Nave > 1) sort_coords_index (X2, Y2, N2, Nave);
 
-  /* set up pointers for linked list of measure, missing */
+  /* set up pointers for linked list of measure */
   if (catalog[0].sorted && (catalog[0].Nmeasure == catalog[0].Nmeas_disk)) {
     // this version is only valid if we have done a full catalog load, and if the catalog
@@ -100,6 +99,4 @@
     next_meas = build_measure_links (catalog[0].average, Nave, catalog[0].measure, Nmeas);
   }    
-  next_miss = init_missing_links (catalog[0].average, Nave, catalog[0].missing, Nmiss);
-  /* missing MUST be written 'sorted', or not at all */
 
   /* choose a radius for matches */
@@ -167,65 +164,42 @@
 	
     /** add measurements for this star **/
+
+    // set the new measurements
+    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].R);
+    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].dbFlags  = 0;
+    catalog[0].measure[Nmeas].averef   = n;
+    catalog[0].measure[Nmeas].objID    = catalog[0].average[n].objID;
+    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].R += 360.0;
-      catalog[0].measure[Nmeas].dR = 3600.0*(catalog[0].average[n].R - stars[N].R);
+      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].R -= 360.0;
-      catalog[0].measure[Nmeas].dR = 3600.0*(catalog[0].average[n].R - stars[N].R);
+      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].R, stars[N].D,
+	       stars[N].average.R, stars[N].average.D,
 	       X1[i], X2[Jmin], 
 	       Y1[i], Y2[Jmin]);
     }
-    catalog[0].measure[Nmeas].dD       = 3600.0*(catalog[0].average[n].D - stars[N].D);
-
-    /* XXX need to add dX, dY : need to load into stars[N].dX,dY */
-    /* XXX need to add stargal, Sky, dSky, qPSF, detID, imageID */
-    catalog[0].measure[Nmeas].Xccd     = stars[N].X;
-    catalog[0].measure[Nmeas].Yccd     = stars[N].Y;
-
-    catalog[0].measure[Nmeas].M        = stars[N].M;
-    catalog[0].measure[Nmeas].dM       = stars[N].dM;  /* error in input files stored in thousandths of mag */
-    catalog[0].measure[Nmeas].Mcal     = stars[N].Mcal;
-    catalog[0].measure[Nmeas].t        = stars[N].t;
-    catalog[0].measure[Nmeas].averef   = n;
-    catalog[0].measure[Nmeas].photcode = stars[N].code;  /* photcode */
-    catalog[0].measure[Nmeas].dophot   = stars[N].dophot;  
-    catalog[0].measure[Nmeas].dbFlags  = 0;
-    catalog[0].measure[Nmeas].dt       = stars[N].dt;
-    catalog[0].measure[Nmeas].airmass  = stars[N].airmass;
-
-    catalog[0].measure[Nmeas].photFlags = stars[N].flags;
-    catalog[0].measure[Nmeas].qPSF      = stars[N].psfQual;
-    catalog[0].measure[Nmeas].psfChisq  = stars[N].psfChisq;
-    catalog[0].measure[Nmeas].crNsigma  = stars[N].crNsigma;
-    catalog[0].measure[Nmeas].extNsigma = stars[N].extNsigma;
-    catalog[0].measure[Nmeas].Sky       = stars[N].sky;
-    catalog[0].measure[Nmeas].dSky      = stars[N].dsky;
-
-    catalog[0].measure[Nmeas].stargal   = 0;
-
-    catalog[0].measure[Nmeas].detID     = stars[N].detID;
-    catalog[0].measure[Nmeas].imageID   = stars[N].imageID;
-
-    catalog[0].measure[Nmeas].dXccd     = stars[N].dX;
-    catalog[0].measure[Nmeas].dYccd     = stars[N].dY;
-
-    catalog[0].measure[Nmeas].Map       = stars[N].Map;
-
-    // XXX saturate range for FWx, FWy, theta
-    // XXX convert to unsigned int for these...
-    catalog[0].measure[Nmeas].FWx      = 100*stars[N].fx;
-    catalog[0].measure[Nmeas].FWy      = 100*stars[N].fy;
-    catalog[0].measure[Nmeas].theta    = (0xffff/360.0)*stars[N].df;
-	
+
+
+    /* adds the measurement to the calibration if appropriate color terms are found */
+    /* we call this before (optionally) setting the average magnitude to avoid auto-correlations */
+    if (options.calibrate) {
+      AddToCalibration (&catalog[0].average[n], &catalog[0].secfilt[n*Nsecfilt], catalog[0].measure, &catalog[0].measure[Nmeas], next_meas, N);
+    }
+
     /* 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 */
@@ -234,9 +208,4 @@
 	catalog[0].secfilt[n*Nsecfilt+Nsec].M = PhotCat (&catalog[0].measure[Nmeas]);
       }
-    }
-
-    /* adds the measurement to the calibration if appropriate color terms are found */
-    if (options.calibrate) {
-      AddToCalibration (&catalog[0].average[n], &catalog[0].secfilt[n*Nsecfilt], catalog[0].measure, &catalog[0].measure[Nmeas], next_meas, N);
     }
 
@@ -270,26 +239,34 @@
     N = N1[i];
     if (stars[N].found >= 0) continue;
-    if (!IN_REGION (stars[N].R, stars[N].D)) continue;
-
-    catalog[0].average[Nave].R         	   = stars[N].R;
-    catalog[0].average[Nave].D         	   = stars[N].D;
-    catalog[0].average[Nave].Xp        	   = 0;
+    if (!IN_REGION (stars[N].average.R, stars[N].average.D)) continue;
+
+    catalog[0].average[Nave].R         	   = stars[N].average.R;
+    catalog[0].average[Nave].D         	   = stars[N].average.D;
+    catalog[0].average[Nave].dR        	   = 0;
+    catalog[0].average[Nave].dD        	   = 0;
+
     catalog[0].average[Nave].Nmeasure  	   = 1;
     catalog[0].average[Nave].Nmissing  	   = 0;
+    catalog[0].average[Nave].Nextend       = 0;
+
     catalog[0].average[Nave].measureOffset = Nmeas;
     catalog[0].average[Nave].missingOffset = -1;
-    catalog[0].average[Nave].code          = 0;
-
-    catalog[0].average[Nave].dR        = 0;
-    catalog[0].average[Nave].dD        = 0;
-    catalog[0].average[Nave].uR        = 0;
-    catalog[0].average[Nave].uD        = 0;
-    catalog[0].average[Nave].duR       = 0;
-    catalog[0].average[Nave].duD       = 0;
-    catalog[0].average[Nave].P         = 0;
-    catalog[0].average[Nave].dP        = 0;
-
-    catalog[0].average[Nave].objID     = objID;
-    catalog[0].average[Nave].catID     = catID;
+    catalog[0].average[Nave].extendOffset  = -1;
+
+    catalog[0].average[Nave].uR        	   = 0;
+    catalog[0].average[Nave].uD        	   = 0;
+    catalog[0].average[Nave].duR       	   = 0;
+    catalog[0].average[Nave].duD       	   = 0;
+    catalog[0].average[Nave].P         	   = 0;
+    catalog[0].average[Nave].dP        	   = 0;
+
+    catalog[0].average[Nave].Xp        	   = 0;
+    catalog[0].average[Nave].ChiSq    	   = 0.0;
+    catalog[0].average[Nave].Npos    	   = 0;
+
+    catalog[0].average[Nave].objID     	   = objID;
+    catalog[0].average[Nave].catID     	   = catID;
+    catalog[0].average[Nave].flags         = 0;
+
     objID ++;
 
@@ -298,42 +275,20 @@
       catalog[0].secfilt[Nave*Nsecfilt+j].dM = NAN;
       catalog[0].secfilt[Nave*Nsecfilt+j].Xm = NAN_S_SHORT;
-    }
-
-    catalog[0].measure[Nmeas].Xccd     = stars[N].X;
-    catalog[0].measure[Nmeas].Yccd     = stars[N].Y;
-
+      catalog[0].secfilt[Nave*Nsecfilt+j].M_20 	= NAN_S_SHORT;
+      catalog[0].secfilt[Nave*Nsecfilt+j].M_80 	= NAN_S_SHORT;
+      catalog[0].secfilt[Nave*Nsecfilt+j].Ncode = 0;
+      catalog[0].secfilt[Nave*Nsecfilt+j].Nused = 0;
+    }
+
+    // supply the measurments from this detection
+    catalog[0].measure[Nmeas]           = stars[N].measure;
+
+    // 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].M        = stars[N].M;
-    catalog[0].measure[Nmeas].dM       = stars[N].dM;
-    catalog[0].measure[Nmeas].Mcal     = stars[N].Mcal;
-    catalog[0].measure[Nmeas].t        = stars[N].t;
+    catalog[0].measure[Nmeas].dbFlags  = 0;
     catalog[0].measure[Nmeas].averef   = Nave;
-    catalog[0].measure[Nmeas].photcode = stars[N].code;  /* photcode */
-    catalog[0].measure[Nmeas].dophot   = stars[N].dophot;  
-    catalog[0].measure[Nmeas].dbFlags  = 0;
-    catalog[0].measure[Nmeas].dt       = stars[N].dt;
-    catalog[0].measure[Nmeas].airmass  = stars[N].airmass;
-
-    catalog[0].measure[Nmeas].photFlags = stars[N].flags;
-    catalog[0].measure[Nmeas].qPSF      = stars[N].psfQual;
-    catalog[0].measure[Nmeas].psfChisq  = stars[N].psfChisq;
-    catalog[0].measure[Nmeas].crNsigma  = stars[N].crNsigma;
-    catalog[0].measure[Nmeas].extNsigma = stars[N].extNsigma;
-    catalog[0].measure[Nmeas].Sky       = stars[N].sky;
-    catalog[0].measure[Nmeas].dSky      = stars[N].dsky;
-
-    catalog[0].measure[Nmeas].stargal   = 0;
-
-    catalog[0].measure[Nmeas].detID     = stars[N].detID;
-    catalog[0].measure[Nmeas].imageID   = stars[N].imageID;
-
-    catalog[0].measure[Nmeas].dXccd     = stars[N].dX;
-    catalog[0].measure[Nmeas].dYccd     = stars[N].dY;
-
-    catalog[0].measure[Nmeas].Map      = stars[N].Map;
-    catalog[0].measure[Nmeas].FWx      = 100*stars[N].fx;
-    catalog[0].measure[Nmeas].FWy      = 100*stars[N].fy;
-    catalog[0].measure[Nmeas].theta    = (0xffff/360.0)*stars[N].df;
+    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 */
Index: /branches/cnb_branch_20090215/Ohana/src/addstar/src/find_matches_refstars.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/src/find_matches_refstars.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/src/find_matches_refstars.c	(revision 21536)
@@ -69,5 +69,5 @@
   
   for (i = 0; i < Nstars; i++) {
-    RD_to_XY (&X1[i], &Y1[i], stars[i][0].R, stars[i][0].D, &tcoords);
+    RD_to_XY (&X1[i], &Y1[i], stars[i][0].average.R, stars[i][0].average.D, &tcoords);
     N1[i] = i;
   }
@@ -134,56 +134,48 @@
       /* find last measurement of this star */
       for (k = 0; k < catalog[0].average[n].Nmeasure - 1; k++) m = next[m];
+
       /* set up references */
       next[Nmeas] = next[m];
       next[m] = Nmeas;
+
       /* last just was moved */
       if (next[Nmeas] == -1) last = Nmeas;
 	
       /** add measurements for this star **/
+
+      // set the new measurements
+      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].R);
-      catalog[0].measure[Nmeas].dD       = 3600.0*(catalog[0].average[n].D - stars[N][0].D);
-      catalog[0].measure[Nmeas].M        = stars[N][0].M;
-      catalog[0].measure[Nmeas].dM       = stars[N][0].dM;
-      catalog[0].measure[Nmeas].Mcal     = 0;
-      catalog[0].measure[Nmeas].t        = (TIMEREF == 0) ? stars[N][0].t : TIMEREF; /** careful : time_t vs e_time **/
+      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);
+
+      // rationalize dR:
+      if (catalog[0].measure[Nmeas].dR > +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) {
+	  // 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].averef   = n;
-      catalog[0].measure[Nmeas].photcode = stars[N][0].code;
-      catalog[0].measure[Nmeas].dophot   = 0;
       catalog[0].measure[Nmeas].dbFlags  = 0;
-      catalog[0].measure[Nmeas].dt       = 0xffff;
-
-      catalog[0].measure[Nmeas].Map      = NAN;
-      catalog[0].measure[Nmeas].airmass  = 0;
-      catalog[0].measure[Nmeas].FWx      = stars[N][0].fx; // XXX make sure these are zero'ed as needed
-      catalog[0].measure[Nmeas].FWy      = stars[N][0].fy; // XXX make sure these are zero'ed as needed
-      catalog[0].measure[Nmeas].theta    = stars[N][0].df; // XXX make sure these are zero'ed as needed
-	
-      catalog[0].measure[Nmeas].photFlags = stars[N][0].flags; // XXX make sure these are zero'ed as needed
-      catalog[0].measure[Nmeas].qPSF      = 0;
-      catalog[0].measure[Nmeas].psfChisq  = 0;
-      catalog[0].measure[Nmeas].crNsigma  = 0;
-      catalog[0].measure[Nmeas].extNsigma = 0;
-      catalog[0].measure[Nmeas].Sky       = 0;
-      catalog[0].measure[Nmeas].dSky      = 0;
-
-      catalog[0].measure[Nmeas].stargal   = 0; // XXX not yet set
-
-      catalog[0].measure[Nmeas].detID     = 0;
-      catalog[0].measure[Nmeas].imageID   = 0;
-
-      catalog[0].measure[Nmeas].dXccd     = 0;
-      catalog[0].measure[Nmeas].dYccd     = 0;
-
-      catalog[0].measure[Nmeas].Xccd     = stars[N][0].X; // XXX make sure these are zero'ed as needed
-      catalog[0].measure[Nmeas].Yccd     = stars[N][0].Y; // XXX make sure these are zero'ed as needed
+      catalog[0].measure[Nmeas].objID    = catalog[0].average[n].objID;
+      catalog[0].measure[Nmeas].catID    = catalog[0].catID;
+
+      catalog[0].measure[Nmeas].t        = (TIMEREF == 0) ? stars[N][0].measure.t      : TIMEREF; /** careful : time_t vs e_time **/
+      catalog[0].measure[Nmeas].t_msec   = (TIMEREF == 0) ? stars[N][0].measure.t_msec : TIMEREF; /** careful : time_t vs e_time **/
 
       if (ACCEPT_MOTION) {
-	catalog[0].average[n].uR         = stars[N][0].uR;
-	catalog[0].average[n].uD         = stars[N][0].uD;
-	catalog[0].average[n].duR        = stars[N][0].duR;
-	catalog[0].average[n].duD        = stars[N][0].duD;
-	catalog[0].average[n].P          = stars[N][0].P;
-	catalog[0].average[n].dP         = stars[N][0].dP;
+	catalog[0].average[n].uR         = stars[N][0].average.uR;
+	catalog[0].average[n].uD         = stars[N][0].average.uD;
+	catalog[0].average[n].duR        = stars[N][0].average.duR;
+	catalog[0].average[n].duD        = stars[N][0].average.duD;
+	catalog[0].average[n].P          = stars[N][0].average.P;
+	catalog[0].average[n].dP         = stars[N][0].average.dP;
       }
 
@@ -233,86 +225,72 @@
   for (i = 0; (i < Nstars) && !options.only_match; i+=NREFSTAR_GROUP) {
     N = N1[i];
-    if (stars[N][0].found >= 0) continue;
-
-    catalog[0].average[Nave].R         	   = stars[N][0].R;
-    catalog[0].average[Nave].D         	   = stars[N][0].D;
-    catalog[0].average[Nave].Xp        	   = 0;
+    if (stars[N][0].found > -1) continue;
+
+    catalog[0].average[Nave].R         	   = stars[N][0].average.R;
+    catalog[0].average[Nave].D         	   = stars[N][0].average.D;
+
     catalog[0].average[Nave].Nmeasure      = NREFSTAR_GROUP;
     catalog[0].average[Nave].Nmissing      = 0;
+    catalog[0].average[Nave].Nextend       = 0;
+
     catalog[0].average[Nave].measureOffset = Nmeas;
     catalog[0].average[Nave].missingOffset = -1;
-    catalog[0].average[Nave].code          = 0;
+    catalog[0].average[Nave].extendOffset  = -1;
 
     if (ACCEPT_MOTION) {
-      catalog[0].average[Nave].dR    = stars[N][0].dR;
-      catalog[0].average[Nave].dD    = stars[N][0].dD;
-      catalog[0].average[Nave].uR    = stars[N][0].uR;
-      catalog[0].average[Nave].uD    = stars[N][0].uD;
-      catalog[0].average[Nave].duR   = stars[N][0].duR;
-      catalog[0].average[Nave].duD   = stars[N][0].duD;
-      catalog[0].average[Nave].P     = stars[N][0].P;
-      catalog[0].average[Nave].dP    = stars[N][0].dP;
+      catalog[0].average[Nave].dR    	   = stars[N][0].average.dR;
+      catalog[0].average[Nave].dD    	   = stars[N][0].average.dD;
+      catalog[0].average[Nave].uR    	   = stars[N][0].average.uR;
+      catalog[0].average[Nave].uD    	   = stars[N][0].average.uD;
+      catalog[0].average[Nave].duR   	   = stars[N][0].average.duR;
+      catalog[0].average[Nave].duD   	   = stars[N][0].average.duD;
+      catalog[0].average[Nave].P     	   = stars[N][0].average.P;
+      catalog[0].average[Nave].dP    	   = stars[N][0].average.dP;
     } else {
-      catalog[0].average[Nave].dR    = 0;
-      catalog[0].average[Nave].dD    = 0;
-      catalog[0].average[Nave].uR    = 0;
-      catalog[0].average[Nave].uD    = 0;
-      catalog[0].average[Nave].duR   = 0;
-      catalog[0].average[Nave].duD   = 0;
-      catalog[0].average[Nave].P     = 0;
-      catalog[0].average[Nave].dP    = 0;
-    }
-
-    catalog[0].average[Nave].objID     = objID;
-    catalog[0].average[Nave].catID     = catID;
+      catalog[0].average[Nave].dR    	   = 0;
+      catalog[0].average[Nave].dD    	   = 0;
+      catalog[0].average[Nave].uR    	   = 0;
+      catalog[0].average[Nave].uD    	   = 0;
+      catalog[0].average[Nave].duR   	   = 0;
+      catalog[0].average[Nave].duD   	   = 0;
+      catalog[0].average[Nave].P     	   = 0;
+      catalog[0].average[Nave].dP    	   = 0;
+      catalog[0].average[Nave].Xp    	   = 0;
+    }
+
+    catalog[0].average[Nave].Xp            = 0;
+    catalog[0].average[Nave].ChiSq    	   = 0.0;
+    catalog[0].average[Nave].Npos    	   = 0;
+
+    catalog[0].average[Nave].objID     	   = objID;
+    catalog[0].average[Nave].catID     	   = catID;
+    catalog[0].average[Nave].flags     	   = 0;
+
     objID ++;
 
     for (j = 0; j < Nsecfilt; j++) {
-      catalog[0].secfilt[Nave*Nsecfilt+j].M  = NAN;
-      catalog[0].secfilt[Nave*Nsecfilt+j].dM = NAN;
-      catalog[0].secfilt[Nave*Nsecfilt+j].Xm = NAN_S_SHORT;
+      catalog[0].secfilt[Nave*Nsecfilt+j].M  	= NAN;
+      catalog[0].secfilt[Nave*Nsecfilt+j].dM 	= NAN;
+      catalog[0].secfilt[Nave*Nsecfilt+j].Xm 	= NAN_S_SHORT;
+      catalog[0].secfilt[Nave*Nsecfilt+j].M_20 	= NAN_S_SHORT;
+      catalog[0].secfilt[Nave*Nsecfilt+j].M_80 	= NAN_S_SHORT;
+      catalog[0].secfilt[Nave*Nsecfilt+j].Ncode = 0;
+      catalog[0].secfilt[Nave*Nsecfilt+j].Nused = 0;
     }
 
     for (j = 0; j < NREFSTAR_GROUP; j++) {
       N = N1[i + j];
+
+      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].M        = stars[N][0].M;
-      catalog[0].measure[Nmeas].dM       = stars[N][0].dM;
-      catalog[0].measure[Nmeas].Mcal     = 0;
-      catalog[0].measure[Nmeas].t        = (stars[N][0].t == 0) ? TIMEREF : stars[N][0].t; /** careful : time_t vs e_time **/
+
+      catalog[0].measure[Nmeas].t        = (stars[N][0].measure.t == 0) ? TIMEREF : stars[N][0].measure.t;      /** careful : time_t vs e_time **/
+      catalog[0].measure[Nmeas].t_msec   = (stars[N][0].measure.t == 0) ?       0 : stars[N][0].measure.t_msec; /** careful : time_t vs e_time **/
+      catalog[0].measure[Nmeas].dbFlags  = 0;
       catalog[0].measure[Nmeas].averef   = Nave;
-      catalog[0].measure[Nmeas].photcode = stars[N][0].code;
-      catalog[0].measure[Nmeas].dophot   = 0;
-      catalog[0].measure[Nmeas].dbFlags  = 0;
-      catalog[0].measure[Nmeas].dt       = 0xffff;
-
-      catalog[0].measure[Nmeas].photFlags = stars[N][0].flags; // XXX make sure these are zero'ed as needed
-      catalog[0].measure[Nmeas].qPSF      = 0;
-      catalog[0].measure[Nmeas].psfChisq  = 0;
-      catalog[0].measure[Nmeas].crNsigma  = 0;
-      catalog[0].measure[Nmeas].extNsigma = 0;
-      catalog[0].measure[Nmeas].Sky       = 0;
-      catalog[0].measure[Nmeas].dSky      = 0;
-
-      catalog[0].measure[Nmeas].stargal   = 0; // XXX not yet set
-
-      catalog[0].measure[Nmeas].detID     = 0;
-      catalog[0].measure[Nmeas].imageID   = 0;
-
-      catalog[0].measure[Nmeas].dXccd     = 0;
-      catalog[0].measure[Nmeas].dYccd     = 0;
-
-      catalog[0].measure[Nmeas].Xccd     = stars[N][0].X; // XXX make sure these are zero'ed as needed
-      catalog[0].measure[Nmeas].Yccd     = stars[N][0].Y; // XXX make sure these are zero'ed as needed
-
-      catalog[0].measure[Nmeas].airmass  = 0;
-      catalog[0].measure[Nmeas].Map      = NAN;
-      catalog[0].measure[Nmeas].FWx      = stars[N][0].fx; // XXX make sure these are zero'ed as needed
-      catalog[0].measure[Nmeas].FWy      = stars[N][0].fy; // XXX make sure these are zero'ed as needed
-      catalog[0].measure[Nmeas].theta    = stars[N][0].df; // XXX make sure these are zero'ed as needed
-
-      catalog[0].measure[Nmeas].Xccd     = 0.0;
-      catalog[0].measure[Nmeas].Yccd     = 0.0;
+      catalog[0].measure[Nmeas].objID    = catalog[0].average[Nave].objID;
+      catalog[0].measure[Nmeas].catID    = catalog[0].catID;
 
       stars[N][0].found = Nmeas;
Index: /branches/cnb_branch_20090215/Ohana/src/addstar/src/find_subset.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/src/find_subset.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/src/find_subset.c	(revision 21536)
@@ -20,8 +20,8 @@
   /* find stars within ra,dec region */
   for (i = N = 0; i < Nstars; i++) {
-    if (stars[i].R <  RA0)  continue;
-    if (stars[i].R >= RA1)  continue;
-    if (stars[i].D <  DEC0) continue;
-    if (stars[i].D >= DEC1) continue;
+    if (stars[i].average.R <  RA0)  continue;
+    if (stars[i].average.R >= RA1)  continue;
+    if (stars[i].average.D <  DEC0) continue;
+    if (stars[i].average.D >= DEC1) continue;
 
     subset[N] = &stars[i];
Index: /branches/cnb_branch_20090215/Ohana/src/addstar/src/get2mass_dr2.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/src/get2mass_dr2.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/src/get2mass_dr2.c	(revision 21536)
@@ -68,21 +68,21 @@
 	dparse (&J,  1, &buffer[NBYTE*i + 53]);
 	dparse (&dJ, 2, &buffer[NBYTE*i + 53]);
-	stars[Nstars].M    = J;
-	stars[Nstars].dM   = dJ;
-	stars[Nstars].code = TM_J;
+	stars[Nstars].M        = J;
+	stars[Nstars].dM       = dJ;
+	stars[Nstars].photcode = TM_J;
       }
       if (photcode == TM_H) {
 	dparse (&H,  1, &buffer[NBYTE*i + 72]);
 	dparse (&dH, 2, &buffer[NBYTE*i + 72]);
-	stars[Nstars].M    = H;
-	stars[Nstars].dM   = dH;
-	stars[Nstars].code = TM_H;
+	stars[Nstars].M        = H;
+	stars[Nstars].dM       = dH;
+	stars[Nstars].photcode = TM_H;
       }
       if (photcode == TM_K) {
 	dparse (&K,  1, &buffer[NBYTE*i + 91]);
 	dparse (&dK, 2, &buffer[NBYTE*i + 91]);
-	stars[Nstars].M    = K;
-	stars[Nstars].dM   = dK;
-	stars[Nstars].code = TM_K;
+	stars[Nstars].M        = K;
+	stars[Nstars].dM       = dK;
+	stars[Nstars].photcode = TM_K;
       }
       Nstars ++;
Index: /branches/cnb_branch_20090215/Ohana/src/addstar/src/get2mass_full.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/src/get2mass_full.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/src/get2mass_full.c	(revision 21536)
@@ -15,44 +15,44 @@
   ptr = next2MASSfield (ptr); // dec (assumed to be already set)
   ptr = next2MASSfield (ptr); // err_maj
-  star[0][0].fx = strtod (ptr, NULL);
+  star[0][0].measure.FWx = ShortPixels(strtod (ptr, NULL));
   ptr = next2MASSfield (ptr); // err_min
-  star[0][0].fy = strtod (ptr, NULL);
+  star[0][0].measure.FWy = ShortPixels(strtod (ptr, NULL));
   ptr = next2MASSfield (ptr); // err_ang
-  star[0][0].df = strtod (ptr, NULL);
-
-  star[2][0].fx = star[2][0].fx = star[0][0].fx;
-  star[2][0].fy = star[2][0].fy = star[0][0].fy;
-  star[2][0].df = star[2][0].df = star[0][0].df;
+  star[0][0].measure.theta = ShortPixels(strtod (ptr, NULL));
+
+  star[2][0].measure.FWx   = star[2][0].measure.FWx   = star[0][0].measure.FWx;
+  star[2][0].measure.FWy   = star[2][0].measure.FWy   = star[0][0].measure.FWy;
+  star[2][0].measure.theta = star[2][0].measure.theta = star[0][0].measure.theta;
 
   ptr = next2MASSfield (ptr); // designation (skip)
 
   ptr = next2MASSfield (ptr); // j_m
-  star[0][0].M  = strtod (ptr, NULL);
+  star[0][0].measure.M  = strtod (ptr, NULL);
   ptr = next2MASSfield (ptr); // j_cmsig
-  star[0][0].dM = strtod (ptr, NULL);
+  star[0][0].measure.dM = strtod (ptr, NULL);
   ptr = next2MASSfield (ptr); // j_msigcom
   dMfull = strtod (ptr, NULL);
-  star[0][0].dMcal = sqrt (SQ(dMfull) - SQ(star[0][0].dM));
+  star[0][0].measure.dMcal = sqrt (SQ(dMfull) - SQ(star[0][0].measure.dM));
   ptr = next2MASSfield (ptr); // j_snr (skip)
 
   ptr = next2MASSfield (ptr); // h_m
-  star[1][0].M  = strtod (ptr, NULL);
+  star[1][0].measure.M  = strtod (ptr, NULL);
   ptr = next2MASSfield (ptr); // h_cmsig
-  star[1][0].dM = strtod (ptr, NULL);
+  star[1][0].measure.dM = strtod (ptr, NULL);
   ptr = next2MASSfield (ptr); // h_msigcom
   dMfull = strtod (ptr, NULL);
-  star[1][0].dMcal = sqrt (SQ(dMfull) - SQ(star[1][0].dM));
+  star[1][0].measure.dMcal = sqrt (SQ(dMfull) - SQ(star[1][0].measure.dM));
   ptr = next2MASSfield (ptr); // h_snr (skip)
 
   ptr = next2MASSfield (ptr); // k_m
-  star[2][0].M  = strtod (ptr, NULL);
+  star[2][0].measure.M  = strtod (ptr, NULL);
   ptr = next2MASSfield (ptr); // k_cmsig
-  star[2][0].dM = strtod (ptr, NULL);
+  star[2][0].measure.dM = strtod (ptr, NULL);
   ptr = next2MASSfield (ptr); // k_msigcom
   dMfull = strtod (ptr, NULL);
-  star[2][0].dMcal = sqrt (SQ(dMfull) - SQ(star[2][0].dM));
+  star[2][0].measure.dMcal = sqrt (SQ(dMfull) - SQ(star[2][0].measure.dM));
   ptr = next2MASSfield (ptr); // k_snr (skip)
 
-  star[2][0].flags = star[1][0].flags = star[0][0].flags = 0;
+  star[2][0].measure.photFlags = star[1][0].measure.photFlags = star[0][0].measure.photFlags = 0;
 
   ptr = next2MASSfield (ptr); // ph_qual
@@ -99,29 +99,29 @@
 
   ptr = next2MASSfield (ptr); // x_scan
-  star[0][0].X = strtod (ptr, NULL);
-  star[2][0].X = star[1][0].X = star[0][0].X;
+  star[0][0].measure.Xccd = strtod (ptr, NULL);
+  star[2][0].measure.Xccd = star[1][0].measure.Xccd = star[0][0].measure.Xccd;
 
   ptr = next2MASSfield (ptr); // jdate (julian date)
   jd = strtod (ptr, NULL);
-  star[0][0].t = ohana_jd_to_sec (jd);
-  star[2][0].t = star[1][0].t = star[0][0].t;
+  star[0][0].measure.t = ohana_jd_to_sec (jd);
+  star[2][0].measure.t = star[1][0].measure.t = star[0][0].measure.t;
 
   ptr = next2MASSfield (ptr); // j_psfchi
-  star[0][0].psfChisq = strtod (ptr, NULL);
+  star[0][0].measure.psfChisq = strtod (ptr, NULL);
   ptr = next2MASSfield (ptr); // h_psfchi
-  star[1][0].psfChisq = strtod (ptr, NULL);
+  star[1][0].measure.psfChisq = strtod (ptr, NULL);
   ptr = next2MASSfield (ptr); // k_psfchi
-  star[2][0].psfChisq = strtod (ptr, NULL);
+  star[2][0].measure.psfChisq = strtod (ptr, NULL);
 
   ptr = next2MASSfield (ptr); // j_m_stdap
-  star[0][0].Map = strtod (ptr, NULL);
+  star[0][0].measure.Map = strtod (ptr, NULL);
   ptr = next2MASSfield (ptr); // j_msig_stdap (skip?)
 
   ptr = next2MASSfield (ptr); // h_m_stdap
-  star[1][0].Map = strtod (ptr, NULL);
+  star[1][0].measure.Map = strtod (ptr, NULL);
   ptr = next2MASSfield (ptr); // h_msig_stdap (skip?)
 
   ptr = next2MASSfield (ptr); // k_m_stdap
-  star[2][0].Map = strtod (ptr, NULL);
+  star[2][0].measure.Map = strtod (ptr, NULL);
   ptr = next2MASSfield (ptr); // k_msig_stdap (skip?)
 
@@ -140,18 +140,15 @@
   set2MASS_use_flag (star[2], ptr[0]);
 
-  star[0][0].code  = TM_J;
-  star[0][0].found = -1;
-  star[0][0].detID   = 0;
-  star[0][0].imageID = 0;
-
-  star[1][0].code  = TM_H;
-  star[1][0].found = -1;
-  star[1][0].detID   = 0;
-  star[1][0].imageID = 0;
-
-  star[2][0].code  = TM_K;
-  star[2][0].found = -1;
-  star[2][0].detID   = 0;
-  star[2][0].imageID = 0;
+  star[0][0].measure.photcode  = TM_J;
+  star[0][0].measure.detID   = 0;
+  star[0][0].measure.imageID = 0;
+
+  star[1][0].measure.photcode  = TM_H;
+  star[1][0].measure.detID   = 0;
+  star[1][0].measure.imageID = 0;
+
+  star[2][0].measure.photcode  = TM_K;
+  star[2][0].measure.detID   = 0;
+  star[2][0].measure.imageID = 0;
 
   return TRUE;
@@ -174,12 +171,12 @@
 
   switch (qual) {
-    case 'X': star[0].flags |= 0x0000; break;
-    case 'U': star[0].flags |= 0x0001; break;
-    case 'F': star[0].flags |= 0x0002; break;
-    case 'E': star[0].flags |= 0x0003; break;
-    case 'A': star[0].flags |= 0x0004; break;
-    case 'B': star[0].flags |= 0x0005; break;
-    case 'C': star[0].flags |= 0x0006; break;
-    case 'D': star[0].flags |= 0x0007; break;
+    case 'X': star[0].measure.photFlags |= 0x0000; break;
+    case 'U': star[0].measure.photFlags |= 0x0001; break;
+    case 'F': star[0].measure.photFlags |= 0x0002; break;
+    case 'E': star[0].measure.photFlags |= 0x0003; break;
+    case 'A': star[0].measure.photFlags |= 0x0004; break;
+    case 'B': star[0].measure.photFlags |= 0x0005; break;
+    case 'C': star[0].measure.photFlags |= 0x0006; break;
+    case 'D': star[0].measure.photFlags |= 0x0007; break;
     default: 
       fprintf (stderr, "error!\n");
@@ -192,11 +189,11 @@
 
   switch (qual) {
-    case '0': star[0].flags |= 0x0000; break;
-    case '1': star[0].flags |= 0x0010; break;
-    case '2': star[0].flags |= 0x0020; break;
-    case '3': star[0].flags |= 0x0030; break;
-    case '4': star[0].flags |= 0x0040; break;
-    case '6': star[0].flags |= 0x0050; break;
-    case '9': star[0].flags |= 0x0060; break;
+    case '0': star[0].measure.photFlags |= 0x0000; break;
+    case '1': star[0].measure.photFlags |= 0x0010; break;
+    case '2': star[0].measure.photFlags |= 0x0020; break;
+    case '3': star[0].measure.photFlags |= 0x0030; break;
+    case '4': star[0].measure.photFlags |= 0x0040; break;
+    case '6': star[0].measure.photFlags |= 0x0050; break;
+    case '9': star[0].measure.photFlags |= 0x0060; break;
     default: 
       fprintf (stderr, "error!\n");
@@ -209,10 +206,10 @@
 
   switch (qual) {
-    case 'p': star[0].flags |= 0x0000; break;
-    case 'c': star[0].flags |= 0x0100; break;
-    case 'd': star[0].flags |= 0x0200; break;
-    case 's': star[0].flags |= 0x0300; break;
-    case 'b': star[0].flags |= 0x0400; break;
-    case '0': star[0].flags |= 0x0500; break;
+    case 'p': star[0].measure.photFlags |= 0x0000; break;
+    case 'c': star[0].measure.photFlags |= 0x0100; break;
+    case 'd': star[0].measure.photFlags |= 0x0200; break;
+    case 's': star[0].measure.photFlags |= 0x0300; break;
+    case 'b': star[0].measure.photFlags |= 0x0400; break;
+    case '0': star[0].measure.photFlags |= 0x0500; break;
     default: 
       fprintf (stderr, "error!\n");
@@ -225,7 +222,7 @@
 
   switch (qual) {
-    case '0': star[0].flags &= ~0x0008; break;
-    case '1': star[0].flags &= ~0x0008; break;
-    default:  star[0].flags |=  0x0008; break;
+    case '0': star[0].measure.photFlags &= ~0x0008; break;
+    case '1': star[0].measure.photFlags &= ~0x0008; break;
+    default:  star[0].measure.photFlags |=  0x0008; break;
   }      
   return (TRUE);
@@ -235,9 +232,9 @@
 
   switch (qual) {
-    case '0': star[0].flags &= ~0x0080; break;
-    case '1': star[0].flags &= ~0x0080; break;
+    case '0': star[0].measure.photFlags &= ~0x0080; break;
+    case '1': star[0].measure.photFlags &= ~0x0080; break;
     default:  
-      star[0].flags |= 0x0080; 
-      star[0].extNsigma = 100.0;
+      star[0].measure.photFlags |= 0x0080; 
+      star[0].measure.extNsigma = 100.0;
       break;
   }      
@@ -248,7 +245,7 @@
 
   switch (qual) {
-    case '0': star[0].flags &= ~0x0800; break;
-    case '1': star[0].flags &= ~0x0800; break;
-    default:  star[0].flags |=  0x0800; break;
+    case '0': star[0].measure.photFlags &= ~0x0800; break;
+    case '1': star[0].measure.photFlags &= ~0x0800; break;
+    default:  star[0].measure.photFlags |=  0x0800; break;
   }      
   return (TRUE);
@@ -258,7 +255,7 @@
 
   switch (qual) {
-    case '0': star[0].flags &= ~0x1000; break;
-    case '1': star[0].flags &= ~0x1000; break;
-    default:  star[0].flags |=  0x1000; break;
+    case '0': star[0].measure.photFlags &= ~0x1000; break;
+    case '1': star[0].measure.photFlags &= ~0x1000; break;
+    default:  star[0].measure.photFlags |=  0x1000; break;
   }      
   return (TRUE);
@@ -268,6 +265,6 @@
 
   switch (qual) {
-    case '0': star[0].flags &= ~0x2000; break;
-    case '1': star[0].flags |=  0x2000; break;
+    case '0': star[0].measure.photFlags &= ~0x2000; break;
+    case '1': star[0].measure.photFlags |=  0x2000; break;
     default:  abort();
   }      
Index: /branches/cnb_branch_20090215/Ohana/src/addstar/src/get2mass_ops.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/src/get2mass_ops.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/src/get2mass_ops.c	(revision 21536)
@@ -42,4 +42,6 @@
   double M, dM;
   e_time time;
+
+  InitStar (star);
 
   ptr = skipNbounds (line, '|', FilterSkip, Nmax);
@@ -57,11 +59,10 @@
   }
 
-  star[0].M       = M;
-  star[0].dM      = dM;
-  star[0].code    = Photcode;
-  star[0].t       = time;
-  star[0].found   = -1;
-  star[0].detID   = 0;
-  star[0].imageID = 0;
+  star[0].measure.M        = M;
+  star[0].measure.dM       = dM;
+  star[0].measure.photcode = Photcode;
+  star[0].measure.t        = time;
+  star[0].measure.detID    = 0;
+  star[0].measure.imageID  = 0;
 
   return TRUE;
@@ -107,27 +108,24 @@
   // how many bits are being used for the 2mass flags; can we just set photFlags based on them?
 
-  star[0].M     = J;
-  star[0].dM    = dJ;
-  star[0].code  = TM_J;
-  star[0].t     = time;
-  star[0].found = -1;
-  star[0].detID   = 0;
-  star[0].imageID = 0;
-
-  star[1].M     = H;
-  star[1].dM    = dH;
-  star[1].code  = TM_H;
-  star[1].t     = time;
-  star[1].found = -1;
-  star[1].detID   = 0;
-  star[1].imageID = 0;
-
-  star[2].M     = K;
-  star[2].dM    = dK;
-  star[2].code  = TM_K;
-  star[2].t     = time;
-  star[2].found = -1;
-  star[2].detID   = 0;
-  star[2].imageID = 0;
+  star[0].measure.M         = J;
+  star[0].measure.dM        = dJ;
+  star[0].measure.photcode  = TM_J;
+  star[0].measure.t         = time;
+  star[0].measure.detID     = 0;
+  star[0].measure.imageID   = 0;
+
+  star[1].measure.M         = H;
+  star[1].measure.dM        = dH;
+  star[1].measure.photcode  = TM_H;
+  star[1].measure.t         = time;
+  star[1].measure.detID     = 0;
+  star[1].measure.imageID   = 0;
+
+  star[2].measure.M         = K;
+  star[2].measure.dM        = dK;
+  star[2].measure.photcode  = TM_K;
+  star[2].measure.t         = time;
+  star[2].measure.detID     = 0;
+  star[2].measure.imageID   = 0;
 
   return TRUE;
Index: /branches/cnb_branch_20090215/Ohana/src/addstar/src/getgsc.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/src/getgsc.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/src/getgsc.c	(revision 21536)
@@ -67,26 +67,20 @@
     Nline = nbytes / BYTES_STAR;
     for (i = 0; i < Nline; i++) {
+
+      InitStar (&stars[Nstars]);
+
       Nbyte = i*BYTES_STAR;
-      dparse (&stars[Nstars].R, 1, &buffer[Nbyte]);
-      dparse (&stars[Nstars].D, 2, &buffer[Nbyte]);
-      if (stars[Nstars].R < UserPatch.Rmin) continue;
-      if (stars[Nstars].R > UserPatch.Rmax) continue;
-      if (stars[Nstars].D < UserPatch.Dmin) continue;
-      if (stars[Nstars].D > UserPatch.Dmax) continue;
+      dparse (&stars[Nstars].average.R, 1, &buffer[Nbyte]);
+      dparse (&stars[Nstars].average.D, 2, &buffer[Nbyte]);
 
-      dparse (&stars[Nstars].M, 3, &buffer[Nbyte]);
-      stars[Nstars].dM 	  = NAN;
-      stars[Nstars].t  	  = 0;
-      stars[Nstars].code  = GSC_M;
-      stars[Nstars].found = -1;
+      if (stars[Nstars].average.R < UserPatch.Rmin) continue;
+      if (stars[Nstars].average.R > UserPatch.Rmax) continue;
+      if (stars[Nstars].average.D < UserPatch.Dmin) continue;
+      if (stars[Nstars].average.D > UserPatch.Dmax) continue;
 
-      stars[Nstars].detID   = 0;
-      stars[Nstars].imageID = 0;
-
-      stars[Nstars].X  = 0;
-      stars[Nstars].Y  = 0;
-      stars[Nstars].fx = 0;
-      stars[Nstars].fy = 0;
-      stars[Nstars].df = 0;
+      fparse (&stars[Nstars].measure.M, 3, &buffer[Nbyte]);
+      stars[Nstars].measure.dM 	      = NAN;
+      stars[Nstars].measure.photcode  = GSC_M;
+      stars[Nstars].measure.t  	      = 0;
 
       Nstars ++;
Index: /branches/cnb_branch_20090215/Ohana/src/addstar/src/gettycho.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/src/gettycho.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/src/gettycho.c	(revision 21536)
@@ -69,54 +69,45 @@
 
       for (j = 0; j < nitems; j++) {
+
 	line = &buffer[j*NBYTE];
-	stars[Ntycho].R = atof (&line[15]);
-	stars[Ntycho].D = atof (&line[28]);
 
-	if (stars[Ntycho].R < region[0].Rmin) goto next_section;
-	if (stars[Ntycho].R > region[0].Rmax) goto next_section;
-	if (stars[Ntycho].D < region[0].Dmin) goto next_section;
-	if (stars[Ntycho].D > region[0].Dmax) goto next_section;
+	InitStar (&stars[Ntycho]);
 
-	if (stars[Ntycho].R < UserPatch.Rmin) continue;
-	if (stars[Ntycho].R > UserPatch.Rmax) continue;
-	if (stars[Ntycho].D < UserPatch.Dmin) continue;
-	if (stars[Ntycho].D > UserPatch.Dmax) continue;
+	stars[Ntycho].average.R = atof (&line[15]);
+	stars[Ntycho].average.D = atof (&line[28]);
 
-	stars[Ntycho].dR  = 1000 * atof (&line[57]);
-	stars[Ntycho].dD  = 1000 * atof (&line[64]);
+	if (stars[Ntycho].average.R < region[0].Rmin) goto next_section;
+	if (stars[Ntycho].average.R > region[0].Rmax) goto next_section;
+	if (stars[Ntycho].average.D < region[0].Dmin) goto next_section;
+	if (stars[Ntycho].average.D > region[0].Dmax) goto next_section;
+
+	if (stars[Ntycho].average.R < UserPatch.Rmin) continue;
+	if (stars[Ntycho].average.R > UserPatch.Rmax) continue;
+	if (stars[Ntycho].average.D < UserPatch.Dmin) continue;
+	if (stars[Ntycho].average.D > UserPatch.Dmax) continue;
+
+	stars[Ntycho].average.dR  = 1000 * atof (&line[57]);
+	stars[Ntycho].average.dD  = 1000 * atof (&line[64]);
 
 	/* XXX : we need to apply uR,uD to R,D to advance to 2000.0 */
-	stars[Ntycho].uR  = atof (&line[41]);
-	stars[Ntycho].uD  = atof (&line[49]);
+	stars[Ntycho].average.uR  = atof (&line[41]);
+	stars[Ntycho].average.uD  = atof (&line[49]);
 
-	stars[Ntycho].duR = atof (&line[69]);
-	stars[Ntycho].duD = atof (&line[75]);
-	
-	stars[Ntycho].P   = 0;
-	stars[Ntycho].dP  = 0;
-
-	stars[Ntycho].detID   = 0;
-	stars[Ntycho].imageID = 0;
+	stars[Ntycho].average.duR = atof (&line[69]);
+	stars[Ntycho].average.duD = atof (&line[75]);
 
 	/* Tycho uses J2000 equinox and 1991.25 epoch for coordinates */
 	/* the magnitudes have no temporal information */ 
-	stars[Ntycho].t   = TychoEpoch;
-	stars[Ntycho].found = -1;
-      
-	stars[Ntycho].X  = 0;
-	stars[Ntycho].Y  = 0;
-	stars[Ntycho].fx = 0;
-	stars[Ntycho].fy = 0;
-	stars[Ntycho].df = 0;
+	stars[Ntycho].measure.t   = TychoEpoch;
 
 	/* one pass of addstar does either r or b */
 	if (photcode == TYCHO_B) {
-	  stars[Ntycho].M     = atof (&line[110]);
-	  stars[Ntycho].dM    = atof (&line[117]);
-	  stars[Ntycho].code  = TYCHO_B;
+	  stars[Ntycho].measure.M     	 = atof (&line[110]);
+	  stars[Ntycho].measure.dM    	 = atof (&line[117]);
+	  stars[Ntycho].measure.photcode = TYCHO_B;
 	} else {
-	  stars[Ntycho].M     = atof (&line[123]);
-	  stars[Ntycho].dM    = atof (&line[130]);
-	  stars[Ntycho].code  = TYCHO_V;
+	  stars[Ntycho].measure.M     	 = atof (&line[123]);
+	  stars[Ntycho].measure.dM    	 = atof (&line[130]);
+	  stars[Ntycho].measure.photcode = TYCHO_V;
 	}	
       
Index: /branches/cnb_branch_20090215/Ohana/src/addstar/src/getusno.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/src/getusno.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/src/getusno.c	(revision 21536)
@@ -110,28 +110,18 @@
       if (buf[1] > iDEC1) continue;
 
-      memset (&stars[Nusno], 0, sizeof(Stars));
-      stars[Nusno].R     = buf[0]/360000.0;
-      stars[Nusno].D     = buf[1]/360000.0 - 90.0;
-      stars[Nusno].dM    = NAN;
-      stars[Nusno].t     = 0;
-      stars[Nusno].found = -1;
+      InitStar (&stars[Nusno]);
 
-      stars[Nusno].detID   = 0;
-      stars[Nusno].imageID = 0;
-
-      stars[Nusno].X  = 0;
-      stars[Nusno].Y  = 0;
-      stars[Nusno].fx = 0;
-      stars[Nusno].fy = 0;
-      stars[Nusno].df = 0;
+      stars[Nusno].average.R     = buf[0]/360000.0;
+      stars[Nusno].average.D     = buf[1]/360000.0 - 90.0;
+      stars[Nusno].measure.dM    = NAN;
 
       /* one pass of addstar does either r or b */
       if (photcode == USNO_RED) {
-	stars[Nusno].code  = USNO_RED;
-	stars[Nusno].M     = fabs (0.1*(buf[2] - 1000*((int)(buf[2]/1000))));
+	stars[Nusno].measure.photcode = USNO_RED;
+	stars[Nusno].measure.M        = fabs (0.1*(buf[2] - 1000*((int)(buf[2]/1000))));
       } 
       if (photcode == USNO_BLUE) {	
-	stars[Nusno].code  = USNO_BLUE;
-	stars[Nusno].M     = fabs (0.1*((int)(buf[2] - 1000000*((int)(buf[2]/1000000))) / 1000));
+	stars[Nusno].measure.photcode = USNO_BLUE;
+	stars[Nusno].measure.M        = fabs (0.1*((int)(buf[2] - 1000000*((int)(buf[2]/1000000))) / 1000));
       }
       Nusno ++;
Index: /branches/cnb_branch_20090215/Ohana/src/addstar/src/getusnob.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/src/getusnob.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/src/getusnob.c	(revision 21536)
@@ -125,37 +125,28 @@
       /* USNO coords are reported for J2000 / epoch 2000.0 */
       /* extract the basic stellar data */
-      memset (&stars[Nusno], 0, sizeof(Stars));
-      stars[Nusno].R   = buf[0]/360000.0;
-      stars[Nusno].D   = buf[1]/360000.0 - 90.0;
+      InitStar (&stars[Nusno]);
+
+      stars[Nusno].average.R   = buf[0]/360000.0;
+      stars[Nusno].average.D   = buf[1]/360000.0 - 90.0;
 
       /* XXX uR cos(D) or just uR ??? */
-      stars[Nusno].uR  = 2.0 * ((buf[2]       % 10000) - 5000);
-      stars[Nusno].uD  = 2.0 * ((buf[2]/10000 % 10000) - 5000);
+      stars[Nusno].average.uR  = 2.0 * ((buf[2]       % 10000) - 5000);
+      stars[Nusno].average.uD  = 2.0 * ((buf[2]/10000 % 10000) - 5000);
 
-      stars[Nusno].duR = (buf[3]      % 1000);
-      stars[Nusno].duD = (buf[3]/1000 % 1000);
+      stars[Nusno].average.duR = (buf[3]      % 1000);
+      stars[Nusno].average.duD = (buf[3]/1000 % 1000);
 
-      stars[Nusno].dR  = 0.001 * (buf[4]      % 1000);
-      stars[Nusno].dD  = 0.001 * (buf[4]/1000 % 1000);
+      stars[Nusno].average.dR  = 0.001 * (buf[4]      % 1000);
+      stars[Nusno].average.dD  = 0.001 * (buf[4]/1000 % 1000);
 
-      stars[Nusno].P   = 0;
-      stars[Nusno].dP  = 0;
+      stars[Nusno].average.P   = 0;
+      stars[Nusno].average.dP  = 0;
 
       /* USNO magnitude errors are reported as a fixed 0.3 mag */
-      stars[Nusno].dM    = 0.3;
-      stars[Nusno].found = -1;
-      
-      stars[Nusno].detID   = 0;
-      stars[Nusno].imageID = 0;
-
-      stars[Nusno].X  = 0;
-      stars[Nusno].Y  = 0;
-      stars[Nusno].fx = 0;
-      stars[Nusno].fy = 0;
-      stars[Nusno].df = 0;
+      stars[Nusno].measure.dM  = 0.3;
 
       /* USNO-B uses J2000 equinox and 2000.0 epoch for coordinates */
       /* the magnitudes have no temporal information */ 
-      stars[Nusno].t     = USNOepoch;
+      stars[Nusno].measure.t   = USNOepoch;
 
       /* one pass of addstar does r, b, or n */
@@ -172,5 +163,5 @@
 	  m2 = 0;
       }
-      stars[Nusno].code = photcode;
+      stars[Nusno].measure.photcode = photcode;
 
       /* if two mags are available, get an average */
@@ -180,5 +171,5 @@
 	mag = (m1) ? m1 : m2;
       }
-      stars[Nusno].M = (mag == 0.0) ? 32.0 : mag;
+      stars[Nusno].measure.M = (mag == 0.0) ? 32.0 : mag;
 
       Nusno ++;
Index: /branches/cnb_branch_20090215/Ohana/src/addstar/src/greference.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/src/greference.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/src/greference.c	(revision 21536)
@@ -3,5 +3,5 @@
 # define LOAD_DR2    1
 
-Stars *grefcat (char *Refcat, SkyRegion *region, int photcode, int *nstars) {
+Stars *greference (char *Refcat, SkyRegion *region, int photcode, int *nstars) {
 
   int Nstars;
@@ -36,15 +36,21 @@
   /* get stars from 2MASS for the given region */
   if (!strcasecmp (Refcat, "2MASS")) {
-    stars = get2mass (region, photcode, LOAD_ALLSKY, &Nstars);
+    // stars = get2mass (region, photcode, LOAD_ALLSKY, &Nstars);
+    fprintf (stderr, "2MASS load via addstar is deprecated: use load2mass\n");
+    exit (2);
   }
   
   /* get stars from 2MASS for the given region */
   if (!strcasecmp (Refcat, "2MASS-ALLSKY")) {
-    stars = get2mass (region, photcode, LOAD_ALLSKY, &Nstars);
+    // stars = get2mass (region, photcode, LOAD_ALLSKY, &Nstars);
+    fprintf (stderr, "2MASS load via addstar is deprecated: use load2mass\n");
+    exit (2);
   }
   
   /* get stars from 2MASS for the given region */
   if (!strcasecmp (Refcat, "2MASS-DR2")) {
-    stars = get2mass (region, photcode, LOAD_DR2, &Nstars);
+    // stars = get2mass (region, photcode, LOAD_DR2, &Nstars);
+    fprintf (stderr, "2MASS load via addstar is deprecated: use load2mass\n");
+    exit (2);
   }
   
Index: /branches/cnb_branch_20090215/Ohana/src/addstar/src/grefstars.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/src/grefstars.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/src/grefstars.c	(revision 21536)
@@ -21,20 +21,15 @@
     if (line[0] == 0) continue;
     if (line[0] == '#') continue;
-    dparse (&stars[N].R,  1, line);
-    dparse (&stars[N].D,  2, line);
-    dparse (&stars[N].M,  3, line);
-    dparse (&stars[N].dM, 4, line);
-    stars[N].R = ohana_normalize_angle (stars[N].R);
-    stars[N].t = 0;
-    stars[N].code = photcode;
-    stars[N].found = FALSE;
-    stars[N].detID   = 0;
-    stars[N].imageID = 0;
 
-    stars[N].X  = 0;
-    stars[N].Y  = 0;
-    stars[N].fx = 0;
-    stars[N].fy = 0;
-    stars[N].df = 0;
+    InitStar (&stars[N]);
+
+    dparse (&stars[N].average.R,  1, line);
+    dparse (&stars[N].average.D,  2, line);
+    stars[N].average.R = ohana_normalize_angle (stars[N].average.R);
+
+    fparse (&stars[N].measure.M,  3, line);
+    fparse (&stars[N].measure.dM, 4, line);
+
+    stars[N].measure.photcode = photcode;
 
     CHECK_REALLOCATE (stars, Stars, NSTARS, N+1, 100);
@@ -43,7 +38,2 @@
   return (stars);
 }
-
-/* stars.found is set here to FALSE.
-   find_match_refstars uses stars.found to identify the seq number of the
-   star which is found.  it requires an initial value of -1 XXX
-*/
Index: /branches/cnb_branch_20090215/Ohana/src/addstar/src/load2mass_as_rawdata.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/src/load2mass_as_rawdata.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/src/load2mass_as_rawdata.c	(revision 21536)
@@ -140,12 +140,15 @@
 	ALLOCATE (stars[Nstars+2], Stars, 1);
 
-	stars[Nstars+0][0].R = tstars[j].R;
-	stars[Nstars+0][0].D = tstars[j].D;
-	stars[Nstars+1][0].R = tstars[j].R;
-	stars[Nstars+1][0].D = tstars[j].D;
-	stars[Nstars+2][0].R = tstars[j].R;
-	stars[Nstars+2][0].D = tstars[j].D;
+	InitStar (stars[Nstars+0]);
+	InitStar (stars[Nstars+1]);
+	InitStar (stars[Nstars+2]);
+
+	stars[Nstars+0][0].average.R = tstars[j].R;
+	stars[Nstars+0][0].average.D = tstars[j].D;
+	stars[Nstars+1][0].average.R = tstars[j].R;
+	stars[Nstars+1][0].average.D = tstars[j].D;
+	stars[Nstars+2][0].average.R = tstars[j].R;
+	stars[Nstars+2][0].average.D = tstars[j].D;
 	get2mass_3star_full (&stars[Nstars], &buffer[offset], Nbyte - offset);
-	// get2mass_star (&stars[Nstars], &buffer[offset], Nbyte - offset);
 
 	tstars[j].flag = TRUE;
Index: /branches/cnb_branch_20090215/Ohana/src/addstar/src/load2mass_catalog.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/src/load2mass_catalog.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/src/load2mass_catalog.c	(revision 21536)
@@ -20,6 +20,6 @@
     // XXX for now, the output objects will have limited astrometric interpretation...
     // XXX every 3 stars represents 3 measurements and 1 average
-    catalog[0].average[Nave].R     = stars[i].R;
-    catalog[0].average[Nave].D     = stars[i].D;
+    catalog[0].average[Nave].R     = stars[i].average.R;
+    catalog[0].average[Nave].D     = stars[i].average.D;
     catalog[0].average[Nave].dR    = 0;
     catalog[0].average[Nave].dD    = 0;
@@ -37,36 +37,25 @@
     catalog[0].average[Nave].measureOffset = Nmeas;
     catalog[0].average[Nave].missingOffset = -1;
-    catalog[0].average[Nave].code          = 0;
+    catalog[0].average[Nave].flags         = 0;
 
     for (j = 0; j < Nsec; j++) {
-      catalog[0].secfilt[Nave*Nsec+j].M  = NAN;
-      catalog[0].secfilt[Nave*Nsec+j].dM = NAN;
-      catalog[0].secfilt[Nave*Nsec+j].Xm = NAN_S_SHORT;
+      catalog[0].secfilt[Nave*Nsec+j].M     = NAN;
+      catalog[0].secfilt[Nave*Nsec+j].dM    = NAN;
+      catalog[0].secfilt[Nave*Nsec+j].Xm    = NAN_S_SHORT;
+      catalog[0].secfilt[Nave*Nsec+j].M_20  = NAN_S_SHORT;
+      catalog[0].secfilt[Nave*Nsec+j].M_80  = NAN_S_SHORT;
+      catalog[0].secfilt[Nave*Nsec+j].Ncode = 0;
+      catalog[0].secfilt[Nave*Nsec+j].Nused = 0;
     }
 
     // we now have the min chisq row. use this to supply the other filter values....
     for (j = 0; j < 3; j++) {
+      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].Xccd      = stars[i+j].X;
-      catalog[0].measure[Nmeas].Yccd      = stars[i+j].Y;
-      catalog[0].measure[Nmeas].dXccd     = 0.0;
-      catalog[0].measure[Nmeas].dYccd     = 0.0;
-      catalog[0].measure[Nmeas].M         = stars[i+j].M;
-      catalog[0].measure[Nmeas].dM        = stars[i+j].dM;
-      catalog[0].measure[Nmeas].Mcal      = 0;
-      catalog[0].measure[Nmeas].dMcal     = stars[i+j].dMcal;
-      catalog[0].measure[Nmeas].t         = stars[i+j].t;
-      catalog[0].measure[Nmeas].averef    = Nave;
-      catalog[0].measure[Nmeas].photcode  = stars[i+j].code;
-      catalog[0].measure[Nmeas].dophot    = 0;
-      catalog[0].measure[Nmeas].photFlags = stars[i+j].flags;
-      catalog[0].measure[Nmeas].dbFlags   = 0;
-      catalog[0].measure[Nmeas].dt        = 0xffff;
-					  
-      catalog[0].measure[Nmeas].airmass   = 0;
-      catalog[0].measure[Nmeas].FWx       = stars[i+j].fx;
-      catalog[0].measure[Nmeas].FWy       = stars[i+j].fy;
-      catalog[0].measure[Nmeas].theta     = stars[i+j].df;
+      catalog[0].measure[Nmeas].dt        = NAN_S_SHORT;
+
+      // XXX what about averef?
 
       catalog[0].average[Nave].Nmeasure++;
Index: /branches/cnb_branch_20090215/Ohana/src/addstar/src/replace_match.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/src/replace_match.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/src/replace_match.c	(revision 21536)
@@ -7,9 +7,9 @@
   /* search for entry and replace values M, dM, R, D */
   for (i = 0; i < average[0].Nmeasure; i++) {
-    if (measure[i].photcode != star[0].code) continue;
-    measure[i].dR = 3600.0*(average[0].R - star[0].R);
-    measure[i].dD = 3600.0*(average[0].D - star[0].D);
-    measure[i].M  = star[0].M;
-    measure[i].dM = star[0].dM;
+    if (measure[i].photcode != star[0].measure.photcode) continue;
+    measure[i].dR = 3600.0*(average[0].R - star[0].average.R);
+    measure[i].dD = 3600.0*(average[0].D - star[0].average.D);
+    measure[i].M  = star[0].measure.M;
+    measure[i].dM = star[0].measure.dM;
     star[0].found = average[0].measureOffset + i;
     return (TRUE);
Index: /branches/cnb_branch_20090215/Ohana/src/addstar/src/sky_tessalation.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/addstar/src/sky_tessalation.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/addstar/src/sky_tessalation.c	(revision 21536)
@@ -281,5 +281,5 @@
   image[0].NY = NY;
 
-  image[0].code = 1; // this needs to be set more sensibly
+  image[0].photcode = 1; // this needs to be set more sensibly
 
   image[0].Mx   = xv[0];  image[0].My   = yv[0];
@@ -433,5 +433,5 @@
   rectangle[0].NX = NX;
   rectangle[0].NY = NY;
-  rectangle[0].code = 1; // this needs to be set more sensibly
+  rectangle[0].photcode = 1; // this needs to be set more sensibly
 
   return (TRUE);
@@ -477,5 +477,5 @@
   rectangle[0].NX = NX;
   rectangle[0].NY = NY;
-  rectangle[0].code = 1; // this needs to be set more sensibly
+  rectangle[0].photcode = 1; // this needs to be set more sensibly
 
   return (TRUE);
@@ -511,5 +511,5 @@
       output[N].NX = NX;
       output[N].NY = NY;
-      output[N].code = input[0].code;
+      output[N].photcode = input[0].photcode;
 
       output[N].coords.crpix1 = input[0].coords.crpix1 - i*NX;
Index: /branches/cnb_branch_20090215/Ohana/src/getstar/src/ReadImageFiles.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/getstar/src/ReadImageFiles.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/getstar/src/ReadImageFiles.c	(revision 21536)
@@ -64,5 +64,5 @@
       /* find image rootname */
       name = filebasename (file[i]);
-      snprintf (image[N].name, DVO_IMAGE_NAME_LEN, name);
+      snprintf (image[N].name, DVO_IMAGE_NAME_LEN, "%s", name);
       free (name);
 
Index: /branches/cnb_branch_20090215/Ohana/src/getstar/src/ReadImageHeader.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/getstar/src/ReadImageHeader.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/getstar/src/ReadImageHeader.c	(revision 21536)
@@ -112,5 +112,5 @@
   image[0].Mcal = 0.0;
   image[0].Xm   = NAN_S_SHORT;
-  image[0].code = 0;
+  image[0].flags = 0;
 
   return (TRUE);
Index: /branches/cnb_branch_20090215/Ohana/src/getstar/src/write_getstar_ps1_dev_0.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/getstar/src/write_getstar_ps1_dev_0.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/getstar/src/write_getstar_ps1_dev_0.c	(revision 21536)
@@ -46,5 +46,5 @@
     output[i].D        = average[i].D;
 
-    output[i].code     = average[i].code;
+    output[i].code     = average[i].flags;
     output[i].photcode = code_c0;
 
Index: /branches/cnb_branch_20090215/Ohana/src/getstar/src/write_getstar_ps1_dev_1.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/getstar/src/write_getstar_ps1_dev_1.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/getstar/src/write_getstar_ps1_dev_1.c	(revision 21536)
@@ -49,5 +49,5 @@
     output[i].P        = average[i].P;
 
-    output[i].code     = average[i].code;
+    output[i].code     = average[i].flags;
     output[i].photcode = code_c0;
 
Index: /branches/cnb_branch_20090215/Ohana/src/getstar/src/write_getstar_ps1_dev_2.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/getstar/src/write_getstar_ps1_dev_2.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/getstar/src/write_getstar_ps1_dev_2.c	(revision 21536)
@@ -55,5 +55,5 @@
     output[i].dP       = average[i].dP;
 
-    output[i].code     = average[i].code;
+    output[i].code     = average[i].flags;
     output[i].photcode = code_c0;
 
Index: /branches/cnb_branch_20090215/Ohana/src/imregister/imphot/modify.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/imregister/imphot/modify.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/imregister/imphot/modify.c	(revision 21536)
@@ -13,14 +13,14 @@
     if (options.modify) {
       if (!strcasecmp (options.ModifyEntry, "and")) {
-	image[i].code &= atoi (options.ModifyValue);
+	image[i].flags &= atoi (options.ModifyValue);
       }
       if (!strcasecmp (options.ModifyEntry, "or")) {
-	image[i].code |= atoi (options.ModifyValue);
+	image[i].flags |= atoi (options.ModifyValue);
       }
       if (!strcasecmp (options.ModifyEntry, "xor")) {
-	image[i].code ^= atoi (options.ModifyValue);
+	image[i].flags ^= atoi (options.ModifyValue);
       }
       if (!strcasecmp (options.ModifyEntry, "=")) {
-	image[i].code = atoi (options.ModifyValue);
+	image[i].flags = atoi (options.ModifyValue);
       }
     }
Index: /branches/cnb_branch_20090215/Ohana/src/imregister/imphot/output.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/imregister/imphot/output.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/imregister/imphot/output.c	(revision 21536)
@@ -39,5 +39,5 @@
       
     fprintf (stdout, "%s %s %s  %7.4f %7.4f  %7.4f %5d %02x\n", image[i].name, photstr, timestr, 
-	     image[i].Mcal, image[i].dMcal, image[i].secz, image[i].nstar, image[i].code); 
+	     image[i].Mcal, image[i].dMcal, image[i].secz, image[i].nstar, image[i].flags); 
     free (timestr);
   }
Index: /branches/cnb_branch_20090215/Ohana/src/imregister/imphot/subset.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/imregister/imphot/subset.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/imregister/imphot/subset.c	(revision 21536)
@@ -24,5 +24,5 @@
     if (!status && criteria.Ntimes) continue;
     if (criteria.PhotcodeSelect && (image[i].photcode != criteria.photcode)) continue;
-    if (criteria.CodeSelect     && (image[i].code != criteria.Code)) continue;
+    if (criteria.CodeSelect     && (image[i].flags != criteria.Code)) continue;
     if (criteria.NameSelect     && strncasecmp (image[i].name, criteria.Name, NameSelectLength)) continue;
 
Index: /branches/cnb_branch_20090215/Ohana/src/libautocode/Makefile.Targets
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libautocode/Makefile.Targets	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/libautocode/Makefile.Targets	(revision 21536)
@@ -1,3 +1,2 @@
-
 AOBJS = \
 $(ASRC)/coords.$(ARCH).o \
@@ -9,4 +8,5 @@
 $(ASRC)/average-ps1-dev-1.$(ARCH).o \
 $(ASRC)/average-ps1-dev-2.$(ARCH).o \
+$(ASRC)/average-ps1-v1.$(ARCH).o \
 $(ASRC)/secfilt.$(ARCH).o \
 $(ASRC)/secfilt-loneos.$(ARCH).o \
@@ -16,4 +16,5 @@
 $(ASRC)/secfilt-ps1-dev-1.$(ARCH).o \
 $(ASRC)/secfilt-ps1-dev-2.$(ARCH).o \
+$(ASRC)/secfilt-ps1-v1.$(ARCH).o \
 $(ASRC)/measure.$(ARCH).o \
 $(ASRC)/measure-loneos.$(ARCH).o \
@@ -23,4 +24,5 @@
 $(ASRC)/measure-ps1-dev-1.$(ARCH).o \
 $(ASRC)/measure-ps1-dev-2.$(ARCH).o \
+$(ASRC)/measure-ps1-v1.$(ARCH).o \
 $(ASRC)/missing.$(ARCH).o \
 $(ASRC)/photcode.$(ARCH).o \
@@ -29,4 +31,5 @@
 $(ASRC)/photcode-ps1-dev-2.$(ARCH).o \
 $(ASRC)/photcode-ps1-dev-3.$(ARCH).o \
+$(ASRC)/photcode-ps1-v1.$(ARCH).o \
 $(ASRC)/image.$(ARCH).o \
 $(ASRC)/image-loneos.$(ARCH).o \
@@ -37,11 +40,13 @@
 $(ASRC)/image-ps1-dev-2.$(ARCH).o \
 $(ASRC)/image-ps1-dev-3.$(ARCH).o \
+$(ASRC)/image-ps1-v1.$(ARCH).o \
 $(ASRC)/regimage.$(ARCH).o \
 $(ASRC)/detreg.$(ARCH).o \
 $(ASRC)/photreg.$(ARCH).o \
 $(ASRC)/photreg-old.$(ARCH).o \
-$(ASRC)/ps1_dev_0.$(ARCH).o \
-$(ASRC)/ps1_dev_1.$(ARCH).o \
-$(ASRC)/smpdata.$(ARCH).o \
+$(ASRC)/cmf-ps1-dev-0.$(ARCH).o \
+$(ASRC)/cmf-ps1-dev-1.$(ARCH).o \
+$(ASRC)/cmf-ps1-v1.$(ARCH).o \
+$(ASRC)/cmf-smpdata.$(ARCH).o \
 $(ASRC)/getstar-ps1-dev-0.$(ARCH).o \
 $(ASRC)/getstar-ps1-dev-1.$(ARCH).o \
@@ -49,5 +54,4 @@
 $(ASRC)/spectrum.$(ARCH).o \
 $(ASRC)/spectrum-ascii.$(ARCH).o \
-$(ASRC)/Stars.$(ARCH).o \
 $(ASRC)/GSCRegion.$(ARCH).o \
 $(ASRC)/AddstarClientOptions.$(ARCH).o \
@@ -63,4 +67,5 @@
 $(AINC)/average-ps1-dev-1.h \
 $(AINC)/average-ps1-dev-2.h \
+$(AINC)/average-ps1-v1.h \
 $(AINC)/secfilt.h \
 $(AINC)/secfilt-loneos.h \
@@ -70,4 +75,5 @@
 $(AINC)/secfilt-ps1-dev-1.h \
 $(AINC)/secfilt-ps1-dev-2.h \
+$(AINC)/secfilt-ps1-v1.h \
 $(AINC)/measure.h \
 $(AINC)/measure-loneos.h \
@@ -77,4 +83,5 @@
 $(AINC)/measure-ps1-dev-1.h \
 $(AINC)/measure-ps1-dev-2.h \
+$(AINC)/measure-ps1-v1.h \
 $(AINC)/missing.h \
 $(AINC)/photcode.h \
@@ -83,4 +90,5 @@
 $(AINC)/photcode-ps1-dev-2.h \
 $(AINC)/photcode-ps1-dev-3.h \
+$(AINC)/photcode-ps1-v1.h \
 $(AINC)/image.h \
 $(AINC)/image-loneos.h \
@@ -91,18 +99,23 @@
 $(AINC)/image-ps1-dev-2.h \
 $(AINC)/image-ps1-dev-3.h \
+$(AINC)/image-ps1-v1.h \
 $(AINC)/regimage.h \
 $(AINC)/detreg.h \
 $(AINC)/photreg.h \
 $(AINC)/photreg-old.h \
-$(AINC)/ps1_dev_0.h \
-$(AINC)/ps1_dev_1.h \
+$(AINC)/cmf-ps1-dev-0.h \
+$(AINC)/cmf-ps1-dev-1.h \
+$(AINC)/cmf-ps1-v1.h \
+$(AINC)/cmf-smpdata.h \
 $(AINC)/getstar-ps1-dev-0.h \
 $(AINC)/getstar-ps1-dev-1.h \
 $(AINC)/getstar-ps1-dev-2.h \
-$(AINC)/smpdata.h \
 $(AINC)/spectrum.h \
 $(AINC)/spectrum-ascii.h \
-$(AINC)/Stars.h \
 $(AINC)/GSCRegion.h \
 $(AINC)/AddstarClientOptions.h \
 $(AINC)/SkyRegion.h
+
+# $(ASRC)/Stars.$(ARCH).o 
+# $(AINC)/Stars.h 
+
Index: /branches/cnb_branch_20090215/Ohana/src/libautocode/def/Stars.d
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libautocode/def/Stars.d	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/libautocode/def/Stars.d	(revision 21536)
@@ -2,10 +2,12 @@
 EXTNAME STARS
 TYPE    BINTABLE
-SIZE    248
+SIZE    278
 
-FIELD     X,                X,          double,    x coordinate on image,	     pixels
-FIELD     Y,                Y,          double,    y coordinate on image,	     pixels
-FIELD     dX,               dX,         double,    x coordinate error,	             pixels
-FIELD     dY,               dY,         double,    y coordinate error,  	     pixels
+* FIELD     Xccd,             X,          double,    x coordinate on image,	     pixels
+* FIELD     Yccd,             Y,          double,    y coordinate on image,	     pixels
+* FIELD     dXccd,            dX,         double,    x coordinate error,	             pixels
+* FIELD     dYccd,            dY,         double,    y coordinate error,  	     pixels
+* FIELD     posangle,         POSANGLE,   float
+* FIELD     pltscale,         PLTSCALE,   float
 FIELD     R,                R,          double,    ra coordinate on sky,	     decimal degrees
 FIELD     D,                D,          double,    dec coordinate on sky,	     decimal degrees
@@ -18,34 +20,37 @@
 FIELD     P,                PAR,        double,    parallax,			     milliarcsec
 FIELD     dP,               PAR_ERR,    double,    parallax error,		     milliarcsec
-FIELD     M,                M,          double,    instrumental mag
-FIELD     dM,               DM,         double,    error on mag
-FIELD     dMcal,            DMCAL,      double,    systematic error on mag
-FIELD     sky,              SKY,        double,    local sky counts
-FIELD     dsky,             dSKY,       double,    local sky error counts
-FIELD     fx,               FX,         double,    object FWHM x-dir,		     pixels?
-FIELD     fy,               FY,         double,    object FWHM y-dir,		     pixels?
-FIELD     df,               DF,         double,    object position angle,	     degrees
-# FIELD     Mgal,             MGAL,       double,    alternative (galaxy) magnitude
-FIELD     Map,              MAP,        double,    alternative (aperture) magnitude
+
+* FIELD     M,                M,          double,    instrumental mag
+* FIELD     dM,               DM,         double,    error on mag
+* FIELD     dMcal,            DMCAL,      double,    systematic error on mag
+* FIELD     Sky,              SKY,        double,    local sky counts
+* FIELD     dSky,             dSKY,       double,    local sky error counts
+* FIELD     fx,               FX,         double,    object FWHM x-dir,		     pixels?
+* FIELD     fy,               FY,         double,    object FWHM y-dir,		     pixels?
+* FIELD     df,               DF,         double,    object position angle,	     degrees
+* FIELD     Mcal,             MCAL,       float,     image cal magnitude
+* FIELD     Map,              MAP,        double,    alternative (aperture) magnitude
 FIELD     Mpeak,            MPEAK,      double,    alternative (peak) magnitude
-FIELD     detID,            ID,         int,       detection identifier
-FIELD     imageID,          IMAGE_ID,   int,       image identifier
+* FIELD     detID,            ID,         int,       detection identifier
+* FIELD     imageID,          IMAGE_ID,   int,       image identifier
 FIELD     found,            FOUND,      int,       found in database catalog?
-FIELD     t,                T,          e_time,    date/time of exposure (UNIX)
-FIELD     dt,               EXPTIME,    float,     exposure time,                    2.5*log(exptime)
-FIELD     psfChisq,         PSF_CHISQ,  float
-FIELD     crNsigma,         CR_NSIGMA,  float
-FIELD     extNsigma,        EXT_NSIGMA, float
-FIELD     psfQual,          PSF_QUAL,   float
-FIELD     Mcal,             MCAL,       float,     image cal mag,	             mag
-FIELD     airmass,          AIRMASS,    float,     (airmass - 1),		     airmass
-FIELD     az,     	    AZ,         float,     azimuth
-FIELD     code,             CODE,       short
-FIELD     nFrames,          N_FRAMES,   short
-FIELD     flags,            FLAGS,      short
-FIELD     dophot,           DOPHOT,     char,      dophot type code
-FIELD     dummy,            DUMMY,      char
-
-# XXX I'm going to need azimuth (or load from image header?)
+* FIELD     t,                T,          e_time,    date/time of exposure (UNIX)
+* FIELD     t_msec,           T_MSEC,     short,     milliseconds of exposure
+* FIELD     dt,               EXPTIME,    float,     exposure time,                    2.5*log(exptime)
+* FIELD     psfQual,          PSF_QUAL,   float
+* FIELD     psfChisq,         PSF_CHISQ,  float
+* FIELD     psfNdof,          PSF_NDOF,   int
+* FIELD     psfNpix,          PSF_NPIX,   int
+* FIELD     crNsigma,         CR_NSIGMA,  float
+* FIELD     extNsigma,        EXT_NSIGMA, float
+* FIELD     Mxx,              MOMENTS_XX, float,     second moment
+* FIELD     Mxy,              MOMENTS_XY, float,     second moment
+* FIELD     Myy,              MOMENTS_YY, float,     second moment
+* FIELD     airmass,          AIRMASS,    float,     (airmass - 1),		     airmass
+* FIELD     az,     	    AZ,         float,     azimuth
+* FIELD     photcode,         CODE,       short
+* FIELD     nFrames,          N_FRAMES,   short
+* FIELD     photFlags,        FLAGS,      short
+FIELD     dummy,            DUMMY,      char[2]
 
 # double:   24 * 8 : 192
@@ -58,2 +63,5 @@
 # define down the types to floats where reasonable (all but R,D)?
 # R,D should be in ICRS, J2000, epoch 2000 : precess as needed, apply p-m as needed
+
+# XXX I'd like to merge this with Measure, but need to be careful about addstarClient -> addstarServer
+# XXX extend photFlags to match actual psphot output
Index: /branches/cnb_branch_20090215/Ohana/src/libautocode/def/average-ps1-v1.d
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libautocode/def/average-ps1-v1.d	(revision 21536)
+++ /branches/cnb_branch_20090215/Ohana/src/libautocode/def/average-ps1-v1.d	(revision 21536)
@@ -0,0 +1,40 @@
+STRUCT       Average_PS1_V1
+EXTNAME      DVO_AVERAGE_PS1_V1
+TYPE         BINTABLE
+SIZE         96
+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 Xp,             SIGMA_POS,   float, 	    position scatter,   	  1/100 arcsec
+FIELD ChiSq,          CHISQ_POS,   float, 	    astrometry analysis chisq
+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 Nextend,        NEXTEND,     unsigned short,  number of extended measurements
+
+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
+
+# 'flags' was called 'code' prior to 2009.02.07
+FIELD flags,          FLAGS,       uint32_t,        average object flags (star; ghost; etc)
+
+# 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)
Index: /branches/cnb_branch_20090215/Ohana/src/libautocode/def/average.d
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libautocode/def/average.d	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/libautocode/def/average.d	(revision 21536)
@@ -2,43 +2,41 @@
 EXTNAME      DVO_AVERAGE
 TYPE         BINTABLE
-SIZE         80
+SIZE         94
 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 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 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 Xp,             SIGMA_POS,   short,           position scatter,             1/100 arcsec
+FIELD ChiSq,          CHISQ_POS,   float,           astrometry analysis chisq
+FIELD Npos,           NUMBER_POS,  unsigned short,  number of detections used for astrometry
 
-FIELD Xp,             SIGMA_POS,   short, 	    position scatter,   	  1/100 arcsec
+# 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 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 code,           code,       unsigned short,   ID code (star; ghost; etc)
-FIELD dummy,          DUMMY,      char[2],          padding
+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
 
-# Pan-STARRS uses a 64-bit detection ID.  keep this in two 32 bit ints
-# for C89 compatibility.  The objID is constructed based on the
-# position of first instatiation.  this is actually quite expensive
-# because we need to include the uniqueness test to construct this,
-# which requires a select for each new object.  Therefore, I will use
-# a table based ID (table ID + object ID), and we will have to
-# re-number the object IDs if we change the table density, OR treat
-# all subdivisions as entries which are from a foreign table.
+# 'flags' was called 'code' prior to 2009.02.07
+FIELD flags,          FLAGS,       uint32_t,        average object flags (star; ghost; etc)
 
-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
+# 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)
 
 # this structure should only be used for internal representations
@@ -47,6 +45,3 @@
 # the index for the secfilt table is just Nsecfilt times the index for the average table.
 
-# the DVO object IDs are generated internally and are not equivalent to the PSPS object IDs
-# probably need to add position chisq
-
-# XXX include the number of measurements used to determine the positional information?
+# *** 20090206 : new fields : ChiSq, Npos, flags (was code, uint16_t), extID
Index: /branches/cnb_branch_20090215/Ohana/src/libautocode/def/cmf-ps1-dev-0.d
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libautocode/def/cmf-ps1-dev-0.d	(revision 21536)
+++ /branches/cnb_branch_20090215/Ohana/src/libautocode/def/cmf-ps1-dev-0.d	(revision 21536)
@@ -0,0 +1,24 @@
+# name of structure type
+STRUCT  PS1_DEV_0
+EXTNAME PS1_DEV_0
+TYPE    BINTABLE
+SIZE    64
+
+# 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 M,      	PSF_INST_MAG,     float,    inst mags,            mags
+FIELD dM,     	PSF_INST_MAG_SIG, float,    inst mag error,       mags
+FIELD Mpeak,    PEAK_FLUX_AS_MAG, float,    inst mag error,       mags
+FIELD sky,    	SKY,              float,    sky flux,             cnts/sec
+FIELD dSky,    	SKY_SIG,          float,    sky flux errorf       cnts/sec
+FIELD psfChisq, PSF_CHISQ,        float,    psf fit chisq
+FIELD fx,     	PSF_WIDTH_X,      float,    semi-major,           pixels
+FIELD fy,     	PSF_WIDTH_Y,      float,    semi-minor,           pixels
+FIELD df,     	PSF_THETA,        float,    ellipse angle,        degrees
+FIELD psfQual, 	PSF_QF,           float,    quality factor
+FIELD nFrames, 	N_FRAMES,         short,    images overlapping peak
+FIELD dummy,  	DUMMY,            short,    padding
Index: /branches/cnb_branch_20090215/Ohana/src/libautocode/def/cmf-ps1-dev-1.d
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libautocode/def/cmf-ps1-dev-1.d	(revision 21536)
+++ /branches/cnb_branch_20090215/Ohana/src/libautocode/def/cmf-ps1-dev-1.d	(revision 21536)
@@ -0,0 +1,26 @@
+# name of structure type
+STRUCT  PS1_DEV_1
+EXTNAME PS1_DEV_1
+TYPE    BINTABLE
+SIZE    72
+
+# 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 M,      	 PSF_INST_MAG,     float,    inst mags,            mags
+FIELD dM,     	 PSF_INST_MAG_SIG, float,    inst mag error,       mags
+FIELD Mpeak,     PEAK_FLUX_AS_MAG, float,    inst mag error,       mags
+FIELD sky,    	 SKY,              float,    sky flux,             cnts/sec
+FIELD dSky,    	 SKY_SIG,          float,    sky flux errorf       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_WIDTH_X,      float,    semi-major,           pixels
+FIELD fy,     	 PSF_WIDTH_Y,      float,    semi-minor,           pixels
+FIELD df,     	 PSF_THETA,        float,    ellipse angle,        degrees
+FIELD psfQual, 	 PSF_QF,           float,    quality factor
+FIELD nFrames, 	 N_FRAMES,         short,    images overlapping peak
+FIELD flags,  	 FLAGS,            short,    padding
Index: /branches/cnb_branch_20090215/Ohana/src/libautocode/def/cmf-ps1-v1.d
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libautocode/def/cmf-ps1-v1.d	(revision 21536)
+++ /branches/cnb_branch_20090215/Ohana/src/libautocode/def/cmf-ps1-v1.d	(revision 21536)
@@ -0,0 +1,78 @@
+# name of structure type
+STRUCT  CMF_PS1_V1
+EXTNAME CMF_PS1_V1
+TYPE    BINTABLE
+SIZE    128
+
+# 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 RA,      	 RA_PSF,    	   float,    PSF RA coord,          degrees
+FIELD DEC,     	 DEC_PSF,    	   float,    PSF DEC coord,         degrees
+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 Map,       AP_MAG_STANDARD,  float,    standard aperture mag, mags
+FIELD apRadius,  AP_MAG_RADIUS,    float,    radius used for fit,   pixels
+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
+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 psfQual, 	 PSF_QF,           float,    quality factor
+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 flags,  	 FLAGS,            int,      analysis flags
+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
+
+# IPP_IDET         1J  IPP_IDET,     	   unsigned i
+# X_PSF       	 1E  X_PSF,    	   float,        
+# Y_PSF       	 1E  Y_PSF,    	   float,        
+# X_PSF_SIG   	 1E  X_PSF_SIG,    	   float,        
+# Y_PSF_SIG   	 1E  Y_PSF_SIG,    	   float,        
+# RA_PSF      	 1E  RA_PSF,    	   float,        
+# DEC_PSF     	 1E  DEC_PSF,    	   float,        
+# POSANGLE    	 1E  POSANGLE,    	   float,        
+# PLTSCALE    	 1E  PLTSCALE,    	   float,        
+# PSF_INST_MAG	 1E  PSF_INST_MAG,     float,          
+# PSF_INST_MAG_SIG 1E  PSF_INST_MAG_SIG, float,        
+# AP_MAG_STANDARD  1E  AP_MAG_STANDARD,  float,        
+# AP_MAG_RADIUS    1E      
+# PEAK_FLUX_AS_MAG 1E  PEAK_FLUX_AS_MAG, float,        
+# CAL_PSF_MAG      1E  CAL_PSF_MAG,      float,        
+# CAL_PSF_MAG_SIG  1E  CAL_PSF_MAG_SIG,  float,        
+# SKY              1E  SKY,              float,        
+# SKY_SIGMA        1E  SKY_SIG,          float,        
+# PSF_CHISQ        1E  PSF_CHISQ,        float,        
+# CR_NSIGMA        1E  CR_NSIGMA,        float,        
+# EXT_NSIGMA       1E  EXT_NSIGMA,       float,        
+# PSF_MAJOR        1E  PSF_MAJOR,        float,        
+# PSF_MINOR        1E  PSF_MINOR,        float,        
+# PSF_THETA        1E  PSF_THETA,        float,        
+# PSF_QF           1E  PSF_QF,           float,        
+# PSF_NDOF         1J  PSF_NDOF,         int,          
+# PSF_NPIX         1J  PSF_NPIX,         int,          
+# MOMENTS_XX       1E  MOMENTS_XX,       float,        
+# MOMENTS_XY       1E  MOMENTS_XY,       float,        
+# MOMENTS_YY       1E  MOMENTS_YY,       float,        
+# N_FRAMES         1I  N_FRAMES,         short,        
+# FLAGS            1J  FLAGS,            int,          
Index: /branches/cnb_branch_20090215/Ohana/src/libautocode/def/cmf-smpdata.d
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libautocode/def/cmf-smpdata.d	(revision 21536)
+++ /branches/cnb_branch_20090215/Ohana/src/libautocode/def/cmf-smpdata.d	(revision 21536)
@@ -0,0 +1,19 @@
+# name of structure type
+STRUCT  SMPData
+EXTNAME SMPFILE
+TYPE    BINTABLE
+SIZE    44
+
+# elements of data structure / FITS table
+FIELD X,      X_PIX,      float,    x coord,              pixels
+FIELD Y,      Y_PIX,      float,    y coord,              pixels
+FIELD M,      MAG_RAW,    float,    inst mags,            mags
+FIELD dM,     MAG_ERR,    float,    inst mag error,       mags
+FIELD Mgal,   MAG_GAL,    float,    galaxy mag,           mags
+FIELD Map,    MAG_AP,     float,    aperture mag,         mags
+FIELD sky,    LOG_SKY,    float,    log-10 of sky,        cnts/sec
+FIELD fx,     FWHM_X,     float,    semi-major,           pixels
+FIELD fy,     FWHM_Y,     float,    semi-minor,           pixels
+FIELD df,     THETA,      float,    ellipse angle,        degrees
+FIELD dophot, DOPHOT,     char,     dophot type,          none
+FIELD dummy,  DUMMY,      char[3],  padding,              none
Index: /branches/cnb_branch_20090215/Ohana/src/libautocode/def/getstar-ps1-v1.d
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libautocode/def/getstar-ps1-v1.d	(revision 21536)
+++ /branches/cnb_branch_20090215/Ohana/src/libautocode/def/getstar-ps1-v1.d	(revision 21536)
@@ -0,0 +1,17 @@
+STRUCT       Getstar_PS1_V1
+EXTNAME      GETSTAR_PS1_V1
+TYPE         BINTABLE
+SIZE         32
+DESCRIPTION  Getstar output file
+
+# elements of data structure / FITS table
+
+# average R,D are epoch & equinox J2000.0
+FIELD R,              RA,         double,           RA,                	       	  decimal degrees 
+FIELD D,              DEC,        double,           DEC,               	       	  decimal degrees 
+FIELD mag,            MAG,        float,            average magnitude in requested photcode
+FIELD c1,             MAG_C1,     float,            average magnitude in color term 1
+FIELD c2,             MAG_C2,     float,            average magnitude in color term 2
+
+FIELD photcode,       PHOTCODE,   unsigned short,   photcode for this mag
+FIELD code,           CODE,       unsigned short,   ID code (star; ghost; etc)
Index: /branches/cnb_branch_20090215/Ohana/src/libautocode/def/image-ps1-v1.d
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libautocode/def/image-ps1-v1.d	(revision 21536)
+++ /branches/cnb_branch_20090215/Ohana/src/libautocode/def/image-ps1-v1.d	(revision 21536)
@@ -0,0 +1,72 @@
+STRUCT       Image_PS1_V1
+EXTNAME      DVO_IMAGE_PS1_V1
+TYPE         BINTABLE
+SIZE         344
+DESCRIPTION  DVO Image Table 
+
+# elements of the image structure
+
+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
+
+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
+
+# should we define the max length of name as a macro?
+FIELD 	  name,             NAME,                 char[121],      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 	  order,            ORDER,                short,      	  Mrel 2D polynomical order 
+FIELD 	  Mx,               MX,                   short,      	  Mrel polyterm
+FIELD 	  My,               MY,                   short,      	  Mrel polyterm
+FIELD 	  Mxx,              MXX,                  short,      	  Mrel polyterm
+FIELD 	  Mxy,              MXY,                  short,      	  Mrel polyterm
+FIELD 	  Myy,              MYY,                  short,      	  Mrel polyterm
+FIELD 	  Mxxx,             MXXX,                 short,      	  Mrel polyterm
+FIELD 	  Mxxy,             MXXY,                 short,      	  Mrel polyterm
+FIELD 	  Mxyy,             MXYY,                 short,      	  Mrel polyterm
+FIELD 	  Myyy,             MYYY,                 short,      	  Mrel polyterm
+FIELD 	  Mxxxx,            MXXXX,                short,      	  Mrel polyterm
+FIELD 	  Mxxxy,            MXXXY,                short,      	  Mrel polyterm
+FIELD 	  Mxxyy,            MXXYY,                short,      	  Mrel polyterm
+FIELD 	  Mxyyy,            MXYYY,                short,      	  Mrel polyterm
+FIELD 	  Myyyy,            MYYYY,                short,      	  Mrel polyterm
+# 40 bytes
Index: /branches/cnb_branch_20090215/Ohana/src/libautocode/def/image.d
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libautocode/def/image.d	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/libautocode/def/image.d	(revision 21536)
@@ -40,5 +40,5 @@
 # 40 bytes
 
-FIELD 	  name,             NAME,                 char[128],      name of original image 
+FIELD 	  name,             NAME,                 char[121],      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
@@ -47,10 +47,8 @@
 FIELD 	  fwhm_y,           FWHM_Y,               unsigned char,  PSF y width,               25*arcsec
 FIELD 	  trate,            TRATE,                unsigned char,  scan rate,                 100 usec/pixel
-FIELD 	  code,             CODE,                 char,           image quality flag
 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
-
-# XXX do we want to use this to handle mosaics?
-# FIELD 	  parentID,         PARENT_ID,            unsigned int,   associated ref image
+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
@@ -73,2 +71,4 @@
 FIELD 	  Myyyy,            MYYYY,                short,      	  Mrel polyterm
 # 40 bytes
+
+# *** 20090206 : new fields : parentID, flags (was code char), changed name to 121 bytes.
Index: /branches/cnb_branch_20090215/Ohana/src/libautocode/def/measure-panstarrs-dev-0.d
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libautocode/def/measure-panstarrs-dev-0.d	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/libautocode/def/measure-panstarrs-dev-0.d	(revision 21536)
@@ -46,5 +46,5 @@
 
 # do we need more resolution than a short? should this be a log?
-FIELD qPSF,           PSF_QF,       short,          psf coverage/quality factor
+FIELD psfQual,        PSF_QF,       short,          psf coverage/quality factor
 
 FIELD dophot,         DOPHOT,       char,           dophot type
Index: /branches/cnb_branch_20090215/Ohana/src/libautocode/def/measure-panstarrs-dev-1.d
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libautocode/def/measure-panstarrs-dev-1.d	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/libautocode/def/measure-panstarrs-dev-1.d	(revision 21536)
@@ -46,5 +46,5 @@
 
 # do we need more resolution than a short? should this be a log?
-FIELD qPSF,           PSF_QF,       short,          psf coverage/quality factor
+FIELD psfQual,        PSF_QF,       short,          psf coverage/quality factor
 
 FIELD dophot,         DOPHOT,       char,           dophot type
Index: /branches/cnb_branch_20090215/Ohana/src/libautocode/def/measure-ps1-dev-1.d
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libautocode/def/measure-ps1-dev-1.d	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/libautocode/def/measure-ps1-dev-1.d	(revision 21536)
@@ -33,5 +33,5 @@
 
 # do we need more resolution than a short? should this be a log?
-FIELD qPSF,           PSF_QF,       float,          psf coverage/quality factor
+FIELD psfQual,        PSF_QF,       float,          psf coverage/quality factor
 FIELD psfChisq,       PSF_CHISQ,    float,          psf coverage/quality factor
 FIELD crNsigma,       CR_NSIGMA,    float,          psf coverage/quality factor
Index: /branches/cnb_branch_20090215/Ohana/src/libautocode/def/measure-ps1-dev-2.d
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libautocode/def/measure-ps1-dev-2.d	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/libautocode/def/measure-ps1-dev-2.d	(revision 21536)
@@ -34,5 +34,5 @@
 
 # do we need more resolution than a short? should this be a log?
-FIELD qPSF,           PSF_QF,       float,          psf coverage/quality factor
+FIELD psfQual,        PSF_QF,       float,          psf coverage/quality factor
 FIELD psfChisq,       PSF_CHISQ,    float,          psf fit chisq
 FIELD crNsigma,       CR_NSIGMA,    float,          Nsigma deviation towards CR
Index: /branches/cnb_branch_20090215/Ohana/src/libautocode/def/measure-ps1-v1.d
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libautocode/def/measure-ps1-v1.d	(revision 21536)
+++ /branches/cnb_branch_20090215/Ohana/src/libautocode/def/measure-ps1-v1.d	(revision 21536)
@@ -0,0 +1,81 @@
+STRUCT       Measure_PS1_V1
+EXTNAME      DVO_MEASURE_PS1_V1
+TYPE         BINTABLE
+SIZE         152
+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 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)
+
+# 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,               pixels
+FIELD Yccd,           Y_CCD,        float,          Y coord on chip,               pixels
+
+# 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 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
+
+# PSPS uses a 64-bit detection ID
+FIELD extID,          EXT_ID,       uint64_t,       external ID (eg PSPS detID)
+
+# do we need more resolution than a short? should this be a log?
+FIELD psfQual,        PSF_QF,       float,          psf coverage/quality factor
+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 crNsigma,       CR_NSIGMA,    float,          Nsigma deviation towards CR
+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 pad,            PAD,          char[6],        padding
+
+# 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
+
+
+# 19 x float
+# 6 x int or unsigned int
+# 11 x short or unsigned short
+# 3 x uint64_t
+
+# = 
Index: /branches/cnb_branch_20090215/Ohana/src/libautocode/def/measure.d
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libautocode/def/measure.d	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/libautocode/def/measure.d	(revision 21536)
@@ -2,57 +2,72 @@
 EXTNAME      DVO_MEASURE
 TYPE         BINTABLE
-SIZE         112
+SIZE         146
 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 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 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 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)
 
 # note that with airmass = 1.0 / cos(90 - alt), we have full alt/az representation
-FIELD airmass,        AIRMASS,      float,          (airmass - 1),		  airmass
+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,               pixels
-FIELD Yccd,           Y_CCD,        float,          Y coord on chip,               pixels
+FIELD Xccd,           X_CCD,        float,          X coord on chip,                pixels
+FIELD Yccd,           Y_CCD,        float,          Y coord on chip,                pixels
 
 # 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 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,         unsigned int,   time in seconds (UNIX)
+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      
 
-# Pan-STARRS uses a 64-bit detection ID.  keep this in two 32 bit ints for backwards compatibility?
 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
+
+# PSPS uses a 64-bit detection ID
+FIELD extID,          EXT_ID,       uint64_t,       external ID (eg PSPS detID)
 
 # do we need more resolution than a short? should this be a log?
-FIELD qPSF,           PSF_QF,       float,          psf coverage/quality factor
+FIELD psfQual,        PSF_QF,       float,          psf coverage/quality factor
 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 crNsigma,       CR_NSIGMA,    float,          Nsigma deviation towards CR
 FIELD extNsigma,      EXT_NSIGMA,   float,          Nsigma deviation towards EXT
 
-FIELD FWx,            FWHM_MAJOR,   short,          object fwhm major axis,       1/100 of arcsec 
-FIELD FWy,            FWHM_MINOR,   short,          object fwhm minor axis,       1/100 of arcsec 
-FIELD theta,          PSF_THETA,    short,          angle wrt ccd X dir,          (0xffff/360) deg
+# 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^2
+FIELD Mxy,            MXY,          short,          second moments in pixel coords, 1/100 of pixels^2
+FIELD Myy,            MYY,          short,          second moments in pixel coords, 1/100 of pixels^2
+
+# convert this to error in pixels on load?
+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 posangle,       POSANGLE,     short,          position angle sky to chip,     (0xffff/360) deg
+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
 
-# convert this to error in arcsec on load?
-FIELD dXccd,          X_CCD_ERR,    short,          X coord error on chip,         pixels
-FIELD dYccd,          Y_CCD_ERR,    short,          Y coord error on chip,         pixels
+# *** 20090206 : new fields : t_msec, extID, Mxx, Mxy, Myy, posangle,
+#                psfNdof, psfNpix, Map_small; deprecated dophot.
+#                Changed dbFlags, photFlags : uint16_t to uint64_t
 
-FIELD dbFlags,        DB_FLAGS,     unsigned short, flags for various uses  
-FIELD photFlags,      PHOT_FLAGS,   unsigned short, flags supplied by photometry program
-
-FIELD stargal,        STAR_GAL,     char,           star-galaxy separator
-
-# absorb these into photFlags?
-FIELD dophot,         DOPHOT,       char,           dophot type
-
-FIELD dummy,          DUMMY,        char[6],        padding
+# XXX unsigned int values are probably not being saved in the FITS file correctly: no BZERO, BSCALE
Index: /branches/cnb_branch_20090215/Ohana/src/libautocode/def/photcode-ps1-v1.d
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libautocode/def/photcode-ps1-v1.d	(revision 21536)
+++ /branches/cnb_branch_20090215/Ohana/src/libautocode/def/photcode-ps1-v1.d	(revision 21536)
@@ -0,0 +1,33 @@
+STRUCT       PhotCode_PS1_V1
+EXTNAME      DVO_PHOTCODE_PS1_V1
+TYPE         BINTABLE
+SIZE         104
+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,      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  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
+
+#   dR_total^2 =  dR_sys^2 + AS * dR_obs^2 + MS * dM_obs^2
+#   dR_sys : systematicAstrometryError
+#   AS     : astrometryErrorScale
+#   MS     : astrometryErrorMagScale
Index: anches/cnb_branch_20090215/Ohana/src/libautocode/def/ps1_dev_0.d
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libautocode/def/ps1_dev_0.d	(revision 21535)
+++ 	(revision )
@@ -1,24 +1,0 @@
-# name of structure type
-STRUCT  PS1_DEV_0
-EXTNAME PS1_DEV_0
-TYPE    BINTABLE
-SIZE    64
-
-# 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 M,      	PSF_INST_MAG,     float,    inst mags,            mags
-FIELD dM,     	PSF_INST_MAG_SIG, float,    inst mag error,       mags
-FIELD Mpeak,    PEAK_FLUX_AS_MAG, float,    inst mag error,       mags
-FIELD sky,    	SKY,              float,    sky flux,             cnts/sec
-FIELD dSky,    	SKY_SIG,          float,    sky flux errorf       cnts/sec
-FIELD psfChisq, PSF_CHISQ,        float,    psf fit chisq
-FIELD fx,     	PSF_WIDTH_X,      float,    semi-major,           pixels
-FIELD fy,     	PSF_WIDTH_Y,      float,    semi-minor,           pixels
-FIELD df,     	PSF_THETA,        float,    ellipse angle,        degrees
-FIELD psfQual, 	PSF_QF,           float,    quality factor
-FIELD nFrames, 	N_FRAMES,         short,    images overlapping peak
-FIELD dummy,  	DUMMY,            short,    padding
Index: anches/cnb_branch_20090215/Ohana/src/libautocode/def/ps1_dev_1.d
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libautocode/def/ps1_dev_1.d	(revision 21535)
+++ 	(revision )
@@ -1,26 +1,0 @@
-# name of structure type
-STRUCT  PS1_DEV_1
-EXTNAME PS1_DEV_1
-TYPE    BINTABLE
-SIZE    72
-
-# 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 M,      	 PSF_INST_MAG,     float,    inst mags,            mags
-FIELD dM,     	 PSF_INST_MAG_SIG, float,    inst mag error,       mags
-FIELD Mpeak,     PEAK_FLUX_AS_MAG, float,    inst mag error,       mags
-FIELD sky,    	 SKY,              float,    sky flux,             cnts/sec
-FIELD dSky,    	 SKY_SIG,          float,    sky flux errorf       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_WIDTH_X,      float,    semi-major,           pixels
-FIELD fy,     	 PSF_WIDTH_Y,      float,    semi-minor,           pixels
-FIELD df,     	 PSF_THETA,        float,    ellipse angle,        degrees
-FIELD psfQual, 	 PSF_QF,           float,    quality factor
-FIELD nFrames, 	 N_FRAMES,         short,    images overlapping peak
-FIELD flags,  	 FLAGS,            short,    padding
Index: /branches/cnb_branch_20090215/Ohana/src/libautocode/def/secfilt-ps1-v1.d
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libautocode/def/secfilt-ps1-v1.d	(revision 21536)
+++ /branches/cnb_branch_20090215/Ohana/src/libautocode/def/secfilt-ps1-v1.d	(revision 21536)
@@ -0,0 +1,14 @@
+STRUCT       SecFilt_PS1_V1
+EXTNAME      DVO_SECFILT_PS1_V1
+TYPE         BINTABLE
+SIZE         20
+DESCRIPTION  DVO SecFilt : Secondary Filter Data 
+
+# 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
Index: /branches/cnb_branch_20090215/Ohana/src/libautocode/def/secfilt.d
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libautocode/def/secfilt.d	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/libautocode/def/secfilt.d	(revision 21536)
@@ -2,5 +2,5 @@
 EXTNAME      DVO_SECFILT
 TYPE         BINTABLE
-SIZE         16
+SIZE         18
 DESCRIPTION  DVO SecFilt : Secondary Filter Data 
 
@@ -11,3 +11,6 @@
 FIELD  Ncode, NCODE,    short,                number of detections in band
 FIELD  Nused, NUSED,    short,                number of detections used in average
-FIELD  dummy, JUNK,     short,                place holder
+FIELD  M_20,  MAG_20,   short,                lower 20percent mag,      millimags
+FIELD  M_80,  MAG_80,   short,                upper 20percent mag,      millimags
+
+# *** 20090206 : new fields : M_20, M_80; dropped dummy
Index: anches/cnb_branch_20090215/Ohana/src/libautocode/def/smpdata.d
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libautocode/def/smpdata.d	(revision 21535)
+++ 	(revision )
@@ -1,19 +1,0 @@
-# name of structure type
-STRUCT  SMPData
-EXTNAME SMPFILE
-TYPE    BINTABLE
-SIZE    44
-
-# elements of data structure / FITS table
-FIELD X,      X_PIX,      float,    x coord,              pixels
-FIELD Y,      Y_PIX,      float,    y coord,              pixels
-FIELD M,      MAG_RAW,    float,    inst mags,            mags
-FIELD dM,     MAG_ERR,    float,    inst mag error,       mags
-FIELD Mgal,   MAG_GAL,    float,    galaxy mag,           mags
-FIELD Map,    MAG_AP,     float,    aperture mag,         mags
-FIELD sky,    LOG_SKY,    float,    log-10 of sky,        cnts/sec
-FIELD fx,     FWHM_X,     float,    semi-major,           pixels
-FIELD fy,     FWHM_Y,     float,    semi-minor,           pixels
-FIELD df,     THETA,      float,    ellipse angle,        degrees
-FIELD dophot, DOPHOT,     char,     dophot type,          none
-FIELD dummy,  DUMMY,      char[3],  padding,              none
Index: /branches/cnb_branch_20090215/Ohana/src/libautocode/doc/autocode.txt
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libautocode/doc/autocode.txt	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/libautocode/doc/autocode.txt	(revision 21536)
@@ -1,2 +1,12 @@
+
+2009.02.07
+
+The autocode tables currently use type names which are ambiguous in
+terms of their actual sizes in bits.  I've added the intNN_t and
+uintNN_t types -- this requires --use-gnu99 with configure
+
+see libdvo/doc/notes.txt for instructions on adding new dvo catalog formats
+
+2007.00.00
 
 This directory contains a collection of autocoded FITS I/O routines
Index: /branches/cnb_branch_20090215/Ohana/src/libautocode/generate
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libautocode/generate	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/libautocode/generate	(revision 21536)
@@ -114,4 +114,5 @@
 	
 	# rawshort is a short without byteswapping
+	# rawshort is a patch for old photreg tables
 
 	$pt1 = 0;
@@ -124,8 +125,22 @@
 	if ($type eq "int")    	      { $pt1 = "J"; }
 	if ($type eq "unsigned int")  { $pt1 = "J"; }
-	if ($type eq "e_time") 	      { $pt1 = "J"; }
+
+	if ($type eq "int8_t") 	      { $pt1 = "B"; }
+	if ($type eq "uint8_t")       { $pt1 = "B"; }
+	if ($type eq "int16_t")       { $pt1 = "I"; }
+	if ($type eq "uint16_t")      { $pt1 = "I"; }
+	if ($type eq "int32_t")       { $pt1 = "J"; }
+	if ($type eq "uint32_t")      { $pt1 = "J"; }
+
+	# FITS tables do not allow for 64bit integers.  we need to
+	# write these by splitting the value into high and low 32 bit values
+	if ($type eq "int64_t")       { $pt1 = "J"; $Np = 2*$Np; }
+	if ($type eq "uint64_t")      { $pt1 = "J"; $Np = 2*$Np; }
+
 	if ($type eq "float")  	      { $pt1 = "E"; }
 	if ($type eq "double") 	      { $pt1 = "D"; }
 
+	# special 'elixir' types:
+	if ($type eq "e_time") 	      { $pt1 = "J"; }
 	if ($type eq "e_void") 	      { $pt1 = "B"; $Np = 8*$Np; }
 	# e_void is a 64 bit pointer, cast to size_t.  its value is not loaded
@@ -146,5 +161,4 @@
 	printf FILE "%-20s 1.0, 0.0);\n", "\"$unit[$i]\", ";
     }
-
 }
 
@@ -217,8 +231,22 @@
 	if ($type eq "int")    	      { $pt1 = sprintf "I%s", $length; }
 	if ($type eq "unsigned int")  { $pt1 = sprintf "I%s", $length; }
-	if ($type eq "e_time") 	      { $pt1 = sprintf "I%s", $length; }
+
+	if ($type eq "int8_t") 	      { $pt1 = sprintf "I%s", $length; }
+	if ($type eq "uint8_t")       { $pt1 = sprintf "I%s", $length; }
+	if ($type eq "int16_t")       { $pt1 = sprintf "I%s", $length; }
+	if ($type eq "uint16_t")      { $pt1 = sprintf "I%s", $length; }
+	if ($type eq "int32_t")       { $pt1 = sprintf "I%s", $length; }
+	if ($type eq "uint32_t")      { $pt1 = sprintf "I%s", $length; }
+
+	# FITS tables do not allow for 64bit integers.  we need to
+	# write these by splitting the value into high and low 32 bit values
+	if ($type eq "int64_t")       { $pt1 = sprintf "I%s", $length; }
+	if ($type eq "uint64_t")      { $pt1 = sprintf "I%s", $length; }
+
 	if ($type eq "float")  	      { $pt1 = sprintf "F%s", $length; }
 	if ($type eq "double") 	      { $pt1 = sprintf "F%s", $length; }
 
+	# special 'elixir' types:
+	if ($type eq "e_time") 	      { $pt1 = sprintf "I%s", $length; }
 	if ($type eq "e_void") 	      { $pt1 = sprintf "I%s", $length; }
 
@@ -283,12 +311,29 @@
 	if ($type eq "unsigned char") { $N +=   $Np; next; }
 	if ($type eq "rawshort")      { $N += 2*$Np; next; }
+
 	if ($type eq "short")  	      { $T = "BYTE"; $n = 2; }
 	if ($type eq "unsigned short"){ $T = "BYTE"; $n = 2; }
 	if ($type eq "int")    	      { $T = "WORD"; $n = 4; }
 	if ($type eq "unsigned int")  { $T = "WORD"; $n = 4; }
+
+	if ($type eq "int8_t") 	      { $N +=   $Np; next; }
+	if ($type eq "uint8_t")       { $N +=   $Np; next; }
+	if ($type eq "int16_t")       { $T = "BYTE"; $n = 2; }
+	if ($type eq "uint16_t")      { $T = "BYTE"; $n = 2; }
+	if ($type eq "int32_t")       { $T = "WORD"; $n = 4; }
+	if ($type eq "uint32_t")      { $T = "WORD"; $n = 4; }
+
+	# FITS tables do not allow for 64bit integers.  we need to
+	# write these by splitting the value into high and low 32 bit values
+	if ($type eq "int64_t")       { $T = "WORD"; $n = 4; $Np = 2*$Np; }
+	if ($type eq "uint64_t")      { $T = "WORD"; $n = 4; $Np = 2*$Np; }
+
+	if ($type eq "float")  	      { $T = "WORD"; $n = 4; }
+	if ($type eq "double") 	      { $T = "DBLE"; $n = 8; }
+
+	# special 'elixir' types:
 	if ($type eq "e_time") 	      { $T = "WORD"; $n = 4; }
 	if ($type eq "e_void") 	      { $T = "DBLE"; $n = 8; }
-	if ($type eq "float")  	      { $T = "WORD"; $n = 4; }
-	if ($type eq "double") 	      { $T = "DBLE"; $n = 8; }
+
 	if (!$n) { die "unknown type $type"; }
 	for ($j = 0; $j < $Np; $j++) {
@@ -318,8 +363,23 @@
 	if ($type eq "int")    	       { $Nbytes += 4*$Np; $valid = 1; }
 	if ($type eq "unsigned int")   { $Nbytes += 4*$Np; $valid = 1; }
+
+	if ($type eq "int8_t") 	       { $Nbytes += 1*$Np; $valid = 1; }
+	if ($type eq "uint8_t")        { $Nbytes += 1*$Np; $valid = 1; }
+	if ($type eq "int16_t")        { $Nbytes += 2*$Np; $valid = 1; }
+	if ($type eq "uint16_t")       { $Nbytes += 2*$Np; $valid = 1; }
+	if ($type eq "int32_t")        { $Nbytes += 4*$Np; $valid = 1; }
+	if ($type eq "uint32_t")       { $Nbytes += 4*$Np; $valid = 1; }
+
+	# FITS tables do not allow for 64bit integers.  we need to
+	# write these by splitting the value into high and low 32 bit values
+	if ($type eq "int64_t")        { $Nbytes += 8*$Np; $valid = 1; }
+	if ($type eq "uint64_t")       { $Nbytes += 8*$Np; $valid = 1; }
+
+	if ($type eq "float")  	       { $Nbytes += 4*$Np; $valid = 1; }
+	if ($type eq "double") 	       { $Nbytes += 8*$Np; $valid = 1; }
+
+	# special 'elixir' types:
 	if ($type eq "e_time") 	       { $Nbytes += 4*$Np; $valid = 1; }
 	if ($type eq "e_void") 	       { $Nbytes += 8*$Np; $valid = 1; }
-	if ($type eq "float")  	       { $Nbytes += 4*$Np; $valid = 1; }
-	if ($type eq "double") 	       { $Nbytes += 8*$Np; $valid = 1; }
 	if (!$valid) { die "unknown type $type"; }
     }
Index: /branches/cnb_branch_20090215/Ohana/src/libdvo/Makefile
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libdvo/Makefile	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/libdvo/Makefile	(revision 21536)
@@ -31,5 +31,6 @@
 $(DESTINC)/ps1_dev_1_defs.h \
 $(DESTINC)/ps1_dev_2_defs.h \
-$(DESTINC)/ps1_dev_3_defs.h
+$(DESTINC)/ps1_dev_3_defs.h \
+$(DESTINC)/ps1_v1_defs.h
 
 INCS = $(DEFS) $(DESTINC)/dvo.h $(DESTINC)/autocode.h
@@ -65,4 +66,5 @@
 $(SRC)/dvo_convert_PS1_DEV_2.$(ARCH).o \
 $(SRC)/dvo_convert_PS1_DEV_3.$(ARCH).o \
+$(SRC)/dvo_convert_PS1_V1.$(ARCH).o \
 $(SRC)/skyregion_io.$(ARCH).o    \
 $(SRC)/skyregion_gsc.$(ARCH).o    \
Index: /branches/cnb_branch_20090215/Ohana/src/libdvo/doc/notes.txt
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libdvo/doc/notes.txt	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/libdvo/doc/notes.txt	(revision 21536)
@@ -2,9 +2,9 @@
 Adding a new dvo catalog format.  Assume the new format name is 'foo'.
 
-1) create the autocode definition files for average, measure, secfilt, image
-   these files must be a subset of the internal versions of these same
-   tables.  if you intend to add fields which don't exist in the
-   internal tables, you must update the internal tables as well.  the
-   naming convention is: average-foo.d, etc.
+1) create the autocode definition files for average, measure, secfilt,
+   image, and photcode.  these files must be a subset of the internal
+   versions of these same tables.  if you intend to add fields which
+   don't exist in the internal tables, you must update the internal
+   tables as well.  the naming convention is: average-foo.d, etc.
 
 2) add the new definition files to libautocode/Makefile.Targets (both
@@ -22,19 +22,26 @@
  (libdvo/src/dvo_catalog.c).  The name should be "FOO".
 
-6) add entry for structure size in dvo_catalog_load_raw
-   (libdvo/src/dvo_catalog_raw.c), since this is not available from
-   the header.
+6) in libdvo/src/dvo_catalog_raw.c, update the FORMAT_CASE lists to
+   include the new STRUCT name.
 
-7) add entries in ReadRawAverage, WriteRawAverage, ReadRawMeasure,
-   WriteRawMeasure, ReadRawSecFilt, WriteRawSecFilt.  Make sure to use
-   the new STRUCT names. the conversion function gfit_convert_Foo will
-   be automatically generated.
+7) create a new conversion file dvo_convert_foo.c and define the
+   internal to Foo conversions.
 
-8) add entry in WriteRawAverage, making sure to use the new STRUCT
-   name. the conversion function gfit_convert_Foo will be
-   automatically generated.  
+8) add the new format to the list of FORMAT conversion in dvo_convert.c.
 
-9) create a new conversion file dvo_convert_foo.c and define the
-   internal to Foo conversions.
+9) any changes to the internal format need to be reflected in the
+   functions in the dvo_convert_*.c files.  These files are defined so
+   that changed fields are sequential in the functions.  This should
+   make is easy to identify the new changes needed.
+
+10) add the new format to the section at the end of dvo_image.c
+
+11) add the new format to the dvo_image_raw.c
+
+12) add the photcode format conversions to libdvo/src/LoadPhotcodesFITS.c
+
+12) switch the output photcode format conversion ina libdvo/src/SavePhotcodesFITS.c
+
+13) Add the conversion functions to the header file libdvo/include/foo_defs.h
 
 * Note some esoteric format issues:  
@@ -54,2 +61,26 @@
     keywords.
 
+----
+
+20090207 : adding PS1_V1
+
+measure: 
+ new fields : t_msec, extID, Mxx, Mxy, Myy, dTccd; deprecated dophot
+ dbFlags, photFlags : uint16_t to uint64_t
+
+average:
+ new fields : ChiSq, Npos, flags (was code, uint16_t), extID
+
+secfilt:
+ new fields : M_20, M_80; dropped dummy
+
+image:
+ new fields : parentID, flags (was code char), changed name to 121 bytes.
+
+photcode:
+ new fields : NONE
+
+** parentID was added to enable easy lookups from chip->fpa for mosaic
+   astrometry.  In old databases, this conversion was done by making
+   the match via the time and photcode.  This conversion needs to be
+   done on load...
Index: /branches/cnb_branch_20090215/Ohana/src/libdvo/include/dvo.h
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libdvo/include/dvo.h	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/libdvo/include/dvo.h	(revision 21536)
@@ -18,5 +18,6 @@
 	      DVO_FORMAT_PS1_DEV_1,
 	      DVO_FORMAT_PS1_DEV_2,
-	      DVO_FORMAT_PS1_DEV_3
+	      DVO_FORMAT_PS1_DEV_3,
+	      DVO_FORMAT_PS1_V1
 } DVOTableFormat;
 
@@ -407,4 +408,5 @@
 # include "ps1_dev_2_defs.h"
 # include "ps1_dev_3_defs.h"
+# include "ps1_v1_defs.h"
 
 /*** DVO image db I/O Functions ***/
@@ -444,5 +446,4 @@
 void sort_image_subset (Image *image, int *subset, int N);
 void sort_coords_index (double *X, double *Y, int *S, int N);
-void sort_stars_ra (Stars *stars, int N);
 void sort_regions (SkyRegion *region, int N);
 
Index: /branches/cnb_branch_20090215/Ohana/src/libdvo/include/ps1_v1_defs.h
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libdvo/include/ps1_v1_defs.h	(revision 21536)
+++ /branches/cnb_branch_20090215/Ohana/src/libdvo/include/ps1_v1_defs.h	(revision 21536)
@@ -0,0 +1,11 @@
+Image 		       	*Image_PS1_V1_ToInternal (Image_PS1_V1 *in, int Nvalues);
+Image_PS1_V1    	*ImageInternalTo_PS1_V1 (Image *in, int Nvalues);
+Average 	       	*Average_PS1_V1_ToInternal (Average_PS1_V1 *in, int Nvalues, SecFilt **primary);
+Average_PS1_V1          *AverageInternalTo_PS1_V1 (Average *in, int Nvalues, SecFilt *primary);
+Measure 	       	*Measure_PS1_V1_ToInternal (Measure_PS1_V1 *in, int Nvalues);
+Measure_PS1_V1          *MeasureInternalTo_PS1_V1 (Measure *in, int Nvalues);
+SecFilt 	       	*SecFilt_PS1_V1_ToInternal (SecFilt_PS1_V1 *in, int Nvalues);
+SecFilt_PS1_V1          *SecFiltInternalTo_PS1_V1 (SecFilt *in, int Nvalues);
+
+PhotCode                *PhotCode_PS1_V1_To_Internal (PhotCode_PS1_V1 *in, int Nvalues);
+PhotCode_PS1_V1         *PhotCode_Internal_To_PS1_V1 (PhotCode *in, int Nvalues);
Index: /branches/cnb_branch_20090215/Ohana/src/libdvo/src/LoadPhotcodesFITS.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libdvo/src/LoadPhotcodesFITS.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/libdvo/src/LoadPhotcodesFITS.c	(revision 21536)
@@ -40,5 +40,11 @@
   gfits_scan (&db.theader, "EXTNAME", "%s", 1, extname);
 
-  if (!strcmp (extname, "DVO_PHOTCODE") || !strcmp (extname, "DVO_PHOTCODE_ELIXIR")) {
+  if (!strcmp (extname, "DVO_PHOTCODE")) {
+    PhotCode_Elixir *photcode_elixir = gfits_table_get_PhotCode_Elixir (&db.ftable, &Ncode, &db.swapped);
+    photcode = PhotCode_Elixir_To_Internal (photcode_elixir, Ncode);
+    free (photcode_elixir);
+  } 
+
+  if (!strcmp (extname, "DVO_PHOTCODE_ELIXIR")) {
     PhotCode_Elixir *photcode_elixir = gfits_table_get_PhotCode_Elixir (&db.ftable, &Ncode, &db.swapped);
     photcode = PhotCode_Elixir_To_Internal (photcode_elixir, Ncode);
@@ -62,4 +68,10 @@
     photcode = PhotCode_PS1_DEV_3_To_Internal (photcode_ps1_dev_3, Ncode);
     free (photcode_ps1_dev_3);
+  } 
+
+  if (!strcmp (extname, "DVO_PHOTCODE_PS1_V1")) {
+    PhotCode_PS1_V1 *photcode_ps1_v1 = gfits_table_get_PhotCode_PS1_V1 (&db.ftable, &Ncode, &db.swapped);
+    photcode = PhotCode_PS1_V1_To_Internal (photcode_ps1_v1, Ncode);
+    free (photcode_ps1_v1);
   } 
 
Index: /branches/cnb_branch_20090215/Ohana/src/libdvo/src/SavePhotcodesFITS.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libdvo/src/SavePhotcodesFITS.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/libdvo/src/SavePhotcodesFITS.c	(revision 21536)
@@ -29,9 +29,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_DEV_3 *photcode_output = PhotCode_Internal_To_PS1_DEV_3 (table[0].code, table[0].Ncode);
+  PhotCode_PS1_V1 *photcode_output = PhotCode_Internal_To_PS1_V1 (table[0].code, table[0].Ncode);
 
   /* convert FITS format data to internal format (byteswaps & EXTNAME) */
   gfits_db_create (&db);
-  gfits_table_set_PhotCode_PS1_DEV_3 (&db.ftable, photcode_output, table[0].Ncode);
+  gfits_table_set_PhotCode_PS1_V1 (&db.ftable, photcode_output, table[0].Ncode);
   gfits_db_save (&db);
   gfits_db_close (&db);
Index: /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvo_catalog.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvo_catalog.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvo_catalog.c	(revision 21536)
@@ -52,4 +52,5 @@
   if (!strcasecmp (catformat, "PS1_DEV_1"))       return (DVO_FORMAT_PS1_DEV_1);
   if (!strcasecmp (catformat, "PS1_DEV_2"))       return (DVO_FORMAT_PS1_DEV_2);
+  if (!strcasecmp (catformat, "PS1_V1"))          return (DVO_FORMAT_PS1_V1);
   return (DVO_FORMAT_UNDEF);
 }
Index: /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvo_catalog_raw.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvo_catalog_raw.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvo_catalog_raw.c	(revision 21536)
@@ -86,4 +86,5 @@
       FORMAT_CASE (PS1_DEV_1, PS1_DEV_1);
       FORMAT_CASE (PS1_DEV_2, PS1_DEV_2);
+      FORMAT_CASE (PS1_V1,    PS1_V1);
 
     default:
@@ -271,4 +272,5 @@
   if (catalog[0].catformat == DVO_FORMAT_PS1_DEV_1)       gfits_modify (&catalog[0].header, "FORMAT", "%s", 1, "PS1_DEV_1");
   if (catalog[0].catformat == DVO_FORMAT_PS1_DEV_2)       gfits_modify (&catalog[0].header, "FORMAT", "%s", 1, "PS1_DEV_2");
+  if (catalog[0].catformat == DVO_FORMAT_PS1_V1)          gfits_modify (&catalog[0].header, "FORMAT", "%s", 1, "PS1_V1");
 
   /* rewind file pointers and truncate file */
@@ -366,4 +368,5 @@
       FORMAT_CASE (PS1_DEV_1, PS1_DEV_1);
       FORMAT_CASE (PS1_DEV_2, PS1_DEV_2);
+      FORMAT_CASE (PS1_V1,    PS1_V1);
 
     default:
@@ -412,4 +415,5 @@
       FORMAT_CASE (PS1_DEV_1, PS1_DEV_1);
       FORMAT_CASE (PS1_DEV_2, PS1_DEV_2);
+      FORMAT_CASE (PS1_V1,    PS1_V1);
 
     default:
@@ -462,4 +466,5 @@
       FORMAT_CASE (PS1_DEV_1, PS1_DEV_1);
       FORMAT_CASE (PS1_DEV_2, PS1_DEV_2);
+      FORMAT_CASE (PS1_V1,    PS1_V1);
 
     default:
@@ -508,4 +513,5 @@
       FORMAT_CASE (PS1_DEV_1, PS1_DEV_1);
       FORMAT_CASE (PS1_DEV_2, PS1_DEV_2);
+      FORMAT_CASE (PS1_V1,    PS1_V1);
 
     default:
@@ -558,4 +564,5 @@
       FORMAT_CASE (PS1_DEV_1, PS1_DEV_1);
       FORMAT_CASE (PS1_DEV_2, PS1_DEV_2);
+      FORMAT_CASE (PS1_V1,    PS1_V1);
 
     default:
@@ -604,4 +611,5 @@
       FORMAT_CASE (PS1_DEV_1, PS1_DEV_1);
       FORMAT_CASE (PS1_DEV_2, PS1_DEV_2);
+      FORMAT_CASE (PS1_V1,    PS1_V1);
 
     default:
Index: /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvo_convert.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvo_convert.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvo_convert.c	(revision 21536)
@@ -49,4 +49,5 @@
   CONVERT_FORMAT ("DVO_AVERAGE_PS1_DEV_1",       PS1_DEV_1,       PS1_DEV_1);
   CONVERT_FORMAT ("DVO_AVERAGE_PS1_DEV_2",       PS1_DEV_2,       PS1_DEV_2);
+  CONVERT_FORMAT ("DVO_AVERAGE_PS1_V1",          PS1_V1,          PS1_V1);
 # undef CONVERT_FORMAT
 
@@ -79,4 +80,5 @@
       FORMAT_CASE (PS1_DEV_1,       PS1_DEV_1);
       FORMAT_CASE (PS1_DEV_2,       PS1_DEV_2);
+      FORMAT_CASE (PS1_V1,          PS1_V1);
 # undef FORMAT_CASE
 
@@ -122,4 +124,5 @@
   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);
 # undef CONVERT_FORMAT
 
@@ -152,4 +155,5 @@
       FORMAT_CASE (PS1_DEV_1,       PS1_DEV_1);
       FORMAT_CASE (PS1_DEV_2,       PS1_DEV_2);
+      FORMAT_CASE (PS1_V1,          PS1_V1);
 # undef FORMAT_CASE
 
@@ -195,4 +199,5 @@
   CONVERT_FORMAT ("DVO_SECFILT_PS1_DEV_1",       PS1_DEV_1,       PS1_DEV_1);
   CONVERT_FORMAT ("DVO_SECFILT_PS1_DEV_2",       PS1_DEV_2,       PS1_DEV_2);
+  CONVERT_FORMAT ("DVO_SECFILT_PS1_V1",          PS1_V1,          PS1_V1);
 # undef CONVERT_FORMAT
 
@@ -225,4 +230,5 @@
       FORMAT_CASE (PS1_DEV_1,       PS1_DEV_1);
       FORMAT_CASE (PS1_DEV_2,       PS1_DEV_2);
+      FORMAT_CASE (PS1_V1,          PS1_V1);
 # undef FORMAT_CASE
 
@@ -288,5 +294,9 @@
   CONVERT_FORMAT ("DVO_IMAGE_PS1_DEV_1",       PS1_DEV_1,       PS1_DEV_1);
   CONVERT_FORMAT ("DVO_IMAGE_PS1_DEV_2",       PS1_DEV_2,       PS1_DEV_2);
-  CONVERT_FORMAT ("DVO_IMAGE_PS1_DEV_3",       PS1_DEV_3,       PS1_DEV_3);
+  CONVERT_FORMAT ("DVO_IMAGE_PS1_V1",          PS1_V1,          PS1_V1);
+
+  // XXX Not sure this was ever actually used -- it was not complete...
+  // CONVERT_FORMAT ("DVO_IMAGE_PS1_DEV_3",       PS1_DEV_3,       PS1_DEV_3);
+
 # undef CONVERT_FORMAT
 
@@ -322,5 +332,8 @@
       FORMAT_CASE (PS1_DEV_1,       PS1_DEV_1);
       FORMAT_CASE (PS1_DEV_2,       PS1_DEV_2);
-      FORMAT_CASE (PS1_DEV_3,       PS1_DEV_3);
+      FORMAT_CASE (PS1_V1,          PS1_V1);
+
+      // XXX not sure this was actually used: it was incomplete
+      // FORMAT_CASE (PS1_DEV_3,       PS1_DEV_3);
 # undef FORMAT_CASE
 
@@ -372,5 +385,9 @@
       FORMAT_CASE (PS1_DEV_1,       PS1_DEV_1);
       FORMAT_CASE (PS1_DEV_2,       PS1_DEV_2);
-      FORMAT_CASE (PS1_DEV_3,       PS1_DEV_3);
+      FORMAT_CASE (PS1_V1,          PS1_V1);
+
+      // XXX not sure this was used, it was incomplete
+      // FORMAT_CASE (PS1_DEV_3,       PS1_DEV_3);
+
 # undef FORMAT_CASE
 
Index: /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvo_convert_PS1_DEV_1.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvo_convert_PS1_DEV_1.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvo_convert_PS1_DEV_1.c	(revision 21536)
@@ -15,5 +15,4 @@
     out[i].M          = in[i].M;
     out[i].Mcal       = in[i].Mcal;
-    out[i].Map        = in[i].Mgal;
     out[i].dM         = in[i].dM;
     out[i].dt         = in[i].dt;
@@ -28,5 +27,5 @@
     out[i].detID      = in[i].detID;
     out[i].imageID    = in[i].imageID;
-    out[i].qPSF       = in[i].qPSF;
+    out[i].psfQual    = in[i].psfQual;
     out[i].psfChisq   = in[i].psfChisq;
     out[i].crNsigma   = in[i].crNsigma;
@@ -40,6 +39,22 @@
     out[i].dbFlags    = in[i].dbFlags;
     out[i].photFlags  = in[i].photFlags;
-    out[i].stargal    = in[i].stargal;
-    out[i].dophot     = in[i].dophot;
+
+    // changed or added for PS1_DEV_2
+    out[i].Map        = in[i].Mgal;
+    out[i].dMcal      = 0; 
+
+    // changed or added for PS1_V1
+    out[i].photFlags  = in[i].photFlags | (in[i].dophot << 16);
+    out[i].t_msec     = 0;
+    out[i].extID      = 0;
+    out[i].objID      = 0;
+    out[i].catID      = 0;
+    out[i].Mxx 	      = 0.0;
+    out[i].Mxy 	      = 0.0;
+    out[i].Myy        = 0.0;
+    out[i].posangle   = 0;
+    out[i].pltscale   = 0;
+    out[i].psfNdof    = 0;
+    out[i].psfNpix    = 0;
   }
   return (out);
@@ -58,5 +73,4 @@
     out[i].M          = in[i].M;
     out[i].Mcal       = in[i].Mcal;
-    out[i].Mgal       = in[i].Map;
     out[i].dM         = in[i].dM;
     out[i].dt         = in[i].dt;
@@ -71,5 +85,5 @@
     out[i].detID      = in[i].detID;
     out[i].imageID    = in[i].imageID;
-    out[i].qPSF       = in[i].qPSF;
+    out[i].psfQual    = in[i].psfQual;
     out[i].psfChisq   = in[i].psfChisq;
     out[i].crNsigma   = in[i].crNsigma;
@@ -82,7 +96,11 @@
     out[i].dYccd      = in[i].dYccd;
     out[i].dbFlags    = in[i].dbFlags;
-    out[i].photFlags  = in[i].photFlags;
-    out[i].stargal    = in[i].stargal;
-    out[i].dophot     = in[i].dophot;
+
+    // changed or added for PS1_DEV_2
+    out[i].Mgal       = in[i].Map;
+
+    // changed or added for PS1_V1
+    out[i].photFlags  = in[i].photFlags & 0x0000ffff;
+    out[i].dophot     = in[i].photFlags >> 16;
   }
   return (out);
@@ -101,9 +119,4 @@
     out[i].D        	 = in[i].D;      
     out[i].Xp       	 = in[i].Xp;     
-    out[i].Nmeasure      = in[i].Nm;     
-    out[i].Nmissing      = in[i].Nn;     
-    out[i].code     	 = in[i].code;   
-    out[i].measureOffset = in[i].offset; 
-    out[i].missingOffset = in[i].missing;
     out[i].dR       	 = in[i].dR;
     out[i].dD       	 = in[i].dD;
@@ -116,4 +129,18 @@
     out[i].objID 	 = in[i].objID;
     out[i].catID 	 = in[i].catID;
+
+    // changed or added for PS1_DEV_2
+    out[i].Nmeasure      = in[i].Nm;     
+    out[i].Nmissing      = in[i].Nn;     
+    out[i].measureOffset = in[i].offset; 
+    out[i].missingOffset = in[i].missing;
+    out[i].Nextend       = 0;
+    out[i].extendOffset  = 0;
+
+    // changed or added for PS1_V1
+    out[i].flags    	 = in[i].code;   
+    out[i].ChiSq       	 = 0.0;
+    out[i].Npos       	 = 0.0;
+    out[i].extID 	 = 0;
   }
   return (out);
@@ -129,22 +156,26 @@
 
   for (i = 0; i < Nvalues; i++) {
-    out[i].R        = in[i].R;      
-    out[i].D        = in[i].D;      
-    out[i].Xp       = in[i].Xp;     
-    out[i].Nm       = in[i].Nmeasure;     
-    out[i].Nn       = in[i].Nmissing;     
-    out[i].code     = in[i].code;   
-    out[i].offset   = in[i].measureOffset; 
-    out[i].missing  = in[i].missingOffset;
-    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].objID    = in[i].objID;
-    out[i].catID    = in[i].catID;
+    out[i].R        	 = in[i].R;      
+    out[i].D        	 = in[i].D;      
+    out[i].Xp       	 = in[i].Xp;     
+    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].objID    	 = in[i].objID;
+    out[i].catID    	 = in[i].catID;
+
+    // changed or added for PS1_DEV_2
+    out[i].Nm       	 = in[i].Nmeasure;     
+    out[i].Nn       	 = in[i].Nmissing;     
+    out[i].offset   	 = in[i].measureOffset; 
+    out[i].missing  	 = in[i].missingOffset;
+
+    // changed or added for PS1_V1
+    out[i].code          = in[i].flags;   
   }
   return (out);
@@ -164,4 +195,8 @@
     out[i].Ncode = in[i].Ncode;
     out[i].Nused = in[i].Nused;
+
+    // changed or added for PS1_V1
+    out[i].M_20  = 0;      
+    out[i].M_80  = 0;      
  }
   return (out);
@@ -218,5 +253,4 @@
     out[i].fwhm_y	    = in[i].fwhm_y;
     out[i].trate	    = in[i].trate;
-    out[i].code		    = in[i].code;
     out[i].ccdnum	    = in[i].ccdnum;
     out[i].imageID	    = in[i].imageID;
@@ -237,4 +271,12 @@
     out[i].Mxyyy	    = in[i].Mxyyy;
     out[i].Myyyy	    = in[i].Myyyy;
+
+    // changed or added for PS1_DEV_2
+    out[i].externID	    = 0;
+    out[i].sourceID	    = 0;
+
+    // changed or added for PS1_V1
+    out[i].flags	    = in[i].code;
+    out[i].parentID	    = 0;
   }
   return (out);
@@ -275,5 +317,4 @@
     out[i].fwhm_y	    = in[i].fwhm_y;
     out[i].trate	    = in[i].trate;
-    out[i].code		    = in[i].code;
     out[i].ccdnum	    = in[i].ccdnum;
     out[i].imageID	    = in[i].imageID;
@@ -294,4 +335,46 @@
     out[i].Mxyyy	    = in[i].Mxyyy;
     out[i].Myyyy	    = in[i].Myyyy;
+
+    // changed or added for PS1_V1
+    out[i].code		    = in[i].flags;
+  }
+  return (out);
+}
+
+PhotCode *PhotCode_PS1_DEV_1_To_Internal (PhotCode_PS1_DEV_1 *in, int Nvalues) {
+
+  int i;
+  PhotCode *out;
+
+  ALLOCATE (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].astromErrMagScale = in[i].astromErrMagScale;
+    out[i].photomErrSys      = in[i].photomErrSys;
+
+    // changed or added for PS1_DEV_2
+    out[i].astromErrSys      = 0.0;
+    out[i].astromErrScale    = 0.0;
+
+    // changed or added for PS1_V1 (also PS1_DEV_3, deprecated)
+    out[i].photomPoorMask      = 0;
+    out[i].photomBadMask       = 0;
+    out[i].astromPoorMask      = 0;
+    out[i].astromBadMask       = 0;
   }
   return (out);
@@ -323,44 +406,5 @@
     out[i].astromErrMagScale = out[i].astromErrMagScale;
     out[i].photomErrSys      = out[i].photomErrSys;
-
-  }
-  return (out);
-}
-
-PhotCode *PhotCode_PS1_DEV_1_To_Internal (PhotCode_PS1_DEV_1 *in, int Nvalues) {
-
-  int i;
-  PhotCode *out;
-
-  ALLOCATE (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;           
-
-    // not defined in PS1_DEV_1
-    out[i].astromErrSys      = 0.0;
-    out[i].astromErrScale    = 0.0;
-    out[i].astromErrMagScale = in[i].astromErrMagScale;
-    out[i].photomErrSys      = in[i].photomErrSys;
-
-    memcpy (out[i].X, in[i].X, 4*sizeof(float));            
-
-    out[i].photomPoorMask      = 0;
-    out[i].photomBadMask       = 0;
-    out[i].astromPoorMask      = 0;
-    out[i].astromBadMask       = 0;
-  }
-  return (out);
-}
+  }
+  return (out);
+}
Index: /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvo_convert_PS1_DEV_2.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvo_convert_PS1_DEV_2.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvo_convert_PS1_DEV_2.c	(revision 21536)
@@ -29,5 +29,5 @@
     out[i].detID      = in[i].detID;
     out[i].imageID    = in[i].imageID;
-    out[i].qPSF       = in[i].qPSF;
+    out[i].psfQual    = in[i].psfQual;
     out[i].psfChisq   = in[i].psfChisq;
     out[i].crNsigma   = in[i].crNsigma;
@@ -40,7 +40,18 @@
     out[i].dYccd      = in[i].dYccd;
     out[i].dbFlags    = in[i].dbFlags;
-    out[i].photFlags  = in[i].photFlags;
-    out[i].stargal    = in[i].stargal;
-    out[i].dophot     = in[i].dophot;
+
+    // changed or added for PS1_V1
+    out[i].photFlags  = in[i].photFlags | (in[i].dophot << 16);
+    out[i].t_msec     = 0;
+    out[i].extID      = 0;
+    out[i].objID      = 0;
+    out[i].catID      = 0;
+    out[i].Mxx 	      = 0.0;
+    out[i].Mxy 	      = 0.0;
+    out[i].Myy        = 0.0;
+    out[i].posangle   = 0;
+    out[i].pltscale   = 0;
+    out[i].psfNdof    = 0;
+    out[i].psfNpix    = 0;
   }
   return (out);
@@ -73,5 +84,5 @@
     out[i].detID      = in[i].detID;
     out[i].imageID    = in[i].imageID;
-    out[i].qPSF       = in[i].qPSF;
+    out[i].psfQual    = in[i].psfQual;
     out[i].psfChisq   = in[i].psfChisq;
     out[i].crNsigma   = in[i].crNsigma;
@@ -84,7 +95,8 @@
     out[i].dYccd      = in[i].dYccd;
     out[i].dbFlags    = in[i].dbFlags;
-    out[i].photFlags  = in[i].photFlags;
-    out[i].stargal    = in[i].stargal;
-    out[i].dophot     = in[i].dophot;
+
+    // changed or added for PS1_V1
+    out[i].photFlags  = in[i].photFlags & 0x0000ffff;
+    out[i].dophot     = in[i].photFlags >> 16;
   }
   return (out);
@@ -114,5 +126,4 @@
     out[i].Nmissing      = in[i].Nmissing;     
     out[i].Nextend       = in[i].Nextend;     
-    out[i].code     	 = in[i].code;   
     out[i].measureOffset = in[i].measureOffset; 
     out[i].missingOffset = in[i].missingOffset;
@@ -120,4 +131,10 @@
     out[i].objID 	 = in[i].objID;
     out[i].catID 	 = in[i].catID;
+
+    // changed or added for PS1_V1
+    out[i].flags    	 = in[i].code;   
+    out[i].ChiSq       	 = 0.0;
+    out[i].Npos       	 = 0.0;
+    out[i].extID 	 = 0;
   }
   return (out);
@@ -147,5 +164,4 @@
     out[i].Nmissing      = in[i].Nmissing;     
     out[i].Nextend       = in[i].Nextend;     
-    out[i].code     	 = in[i].code;   
     out[i].measureOffset = in[i].measureOffset; 
     out[i].missingOffset = in[i].missingOffset;
@@ -153,4 +169,7 @@
     out[i].objID 	 = in[i].objID;
     out[i].catID 	 = in[i].catID;
+
+    // changed or added for PS1_V1
+    out[i].code     	 = in[i].flags;   
   }
   return (out);
@@ -170,4 +189,8 @@
     out[i].Ncode = in[i].Ncode;
     out[i].Nused = in[i].Nused;
+
+    // changed or added for PS1_V1
+    out[i].M_20  = 0;      
+    out[i].M_80  = 0;      
  }
   return (out);
@@ -201,5 +224,5 @@
     memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
 
-    strncpy (out[i].name, in[i].name, 63); // out[128], int[64]
+    strncpy (out[i].name, in[i].name, 63); // out[121], int[64]
     out[i].name[63] = 0; // force termination
 
@@ -224,5 +247,4 @@
     out[i].fwhm_y	    = in[i].fwhm_y;
     out[i].trate	    = in[i].trate;
-    out[i].code		    = in[i].code;
     out[i].ccdnum	    = in[i].ccdnum;
     out[i].imageID	    = in[i].imageID;
@@ -245,4 +267,8 @@
     out[i].Mxyyy	    = in[i].Mxyyy;
     out[i].Myyyy	    = in[i].Myyyy;
+
+    // changed or added for PS1_V1
+    out[i].flags	    = in[i].code;
+    out[i].parentID	    = 0;
   }
   return (out);
@@ -259,5 +285,5 @@
     memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
 
-    strncpy (out[i].name, in[i].name, 63); // in[128], out[64]
+    strncpy (out[i].name, in[i].name, 63); // in[121], out[64]
     out[i].name[63] = 0; // force termination
 
@@ -282,5 +308,4 @@
     out[i].fwhm_y	    = in[i].fwhm_y;
     out[i].trate	    = in[i].trate;
-    out[i].code		    = in[i].code;
     out[i].ccdnum	    = in[i].ccdnum;
     out[i].imageID	    = in[i].imageID;
@@ -303,14 +328,17 @@
     out[i].Mxyyy	    = in[i].Mxyyy;
     out[i].Myyyy	    = in[i].Myyyy;
-  }
-  return (out);
-}
-
-PhotCode_PS1_DEV_2 *PhotCode_Internal_To_PS1_DEV_2 (PhotCode *in, int Nvalues) {
-
-  int i;
-  PhotCode_PS1_DEV_2 *out;
-
-  ALLOCATE (out, PhotCode_PS1_DEV_2, Nvalues);
+
+    // changed or added for PS1_V1
+    out[i].code		    = in[i].flags;
+  }
+  return (out);
+}
+
+PhotCode *PhotCode_PS1_DEV_2_To_Internal (PhotCode_PS1_DEV_2 *in, int Nvalues) {
+
+  int i;
+  PhotCode *out;
+
+  ALLOCATE (out, PhotCode, Nvalues);
 
   for (i = 0; i < Nvalues; i++) {
@@ -334,14 +362,20 @@
     out[i].astromErrMagScale = in[i].astromErrMagScale;
     out[i].photomErrSys      = in[i].photomErrSys;
-  }
-  return (out);
-}
-
-PhotCode *PhotCode_PS1_DEV_2_To_Internal (PhotCode_PS1_DEV_2 *in, int Nvalues) {
-
-  int i;
-  PhotCode *out;
-
-  ALLOCATE (out, PhotCode, Nvalues);
+
+    // changed or added for PS1_V1 (also PS1_DEV_3, deprecated)
+    out[i].photomPoorMask      = 0;
+    out[i].photomBadMask       = 0;
+    out[i].astromPoorMask      = 0;
+    out[i].astromBadMask       = 0;
+  }
+  return (out);
+}
+
+PhotCode_PS1_DEV_2 *PhotCode_Internal_To_PS1_DEV_2 (PhotCode *in, int Nvalues) {
+
+  int i;
+  PhotCode_PS1_DEV_2 *out;
+
+  ALLOCATE (out, PhotCode_PS1_DEV_2, Nvalues);
 
   for (i = 0; i < Nvalues; i++) {
@@ -365,10 +399,5 @@
     out[i].astromErrMagScale = in[i].astromErrMagScale;
     out[i].photomErrSys      = in[i].photomErrSys;
-
-    out[i].photomPoorMask      = 0;
-    out[i].photomBadMask       = 0;
-    out[i].astromPoorMask      = 0;
-    out[i].astromBadMask       = 0;
-  }
-  return (out);
-}
+  }
+  return (out);
+}
Index: /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvo_convert_PS1_DEV_3.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvo_convert_PS1_DEV_3.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvo_convert_PS1_DEV_3.c	(revision 21536)
@@ -3,5 +3,5 @@
 /* convert PS1_DEV_3 formats to internal formats */
 
-// XXX EAM I am not yet ready to commit to a full PS1_DEV_3 release, but I am providing image and photcode conversion
+// We only provide image and photcode conversion
 
 Image *Image_PS1_DEV_3_ToInternal (Image_PS1_DEV_3 *in, int Nvalues) {
@@ -38,5 +38,4 @@
     out[i].fwhm_y	    = in[i].fwhm_y;
     out[i].trate	    = in[i].trate;
-    out[i].code		    = in[i].code;
     out[i].ccdnum	    = in[i].ccdnum;
     out[i].imageID	    = in[i].imageID;
@@ -59,4 +58,8 @@
     out[i].Mxyyy	    = in[i].Mxyyy;
     out[i].Myyyy	    = in[i].Myyyy;
+
+    // changed or added for PS1_V1
+    out[i].flags	    = in[i].code;
+    out[i].parentID	    = 0;
   }
   return (out);
@@ -96,5 +99,4 @@
     out[i].fwhm_y	    = in[i].fwhm_y;
     out[i].trate	    = in[i].trate;
-    out[i].code		    = in[i].code;
     out[i].ccdnum	    = in[i].ccdnum;
     out[i].imageID	    = in[i].imageID;
@@ -117,4 +119,43 @@
     out[i].Mxyyy	    = in[i].Mxyyy;
     out[i].Myyyy	    = in[i].Myyyy;
+
+    // changed or added for PS1_V1
+    out[i].code		    = in[i].flags;
+  }
+  return (out);
+}
+
+PhotCode *PhotCode_PS1_DEV_3_To_Internal (PhotCode_PS1_DEV_3 *in, int Nvalues) {
+
+  int i;
+  PhotCode *out;
+
+  ALLOCATE (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);
@@ -157,37 +198,2 @@
 }
 
-PhotCode *PhotCode_PS1_DEV_3_To_Internal (PhotCode_PS1_DEV_3 *in, int Nvalues) {
-
-  int i;
-  PhotCode *out;
-
-  ALLOCATE (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);
-}
Index: /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvo_convert_PS1_V1.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvo_convert_PS1_V1.c	(revision 21536)
+++ /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvo_convert_PS1_V1.c	(revision 21536)
@@ -0,0 +1,409 @@
+# include <dvo.h>
+
+/* convert PS1_V1 formats to internal formats */
+
+Measure *Measure_PS1_V1_ToInternal (Measure_PS1_V1 *in, int Nvalues) {
+
+  int i;
+  Measure *out;
+
+  ALLOCATE (out, Measure, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    out[i].dR         = in[i].dR;
+    out[i].dD         = in[i].dD;
+    out[i].M          = in[i].M;
+    out[i].Mcal       = in[i].Mcal;
+    out[i].Map        = in[i].Map;
+    out[i].dM         = in[i].dM;
+    out[i].dMcal      = in[i].dMcal;
+    out[i].dt         = in[i].dt;
+    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].Sky        = in[i].Sky;
+    out[i].dSky       = in[i].dSky;
+    out[i].t          = in[i].t;
+    out[i].t_msec     = in[i].t_msec;
+    out[i].averef     = in[i].averef;
+    out[i].detID      = in[i].detID;
+    out[i].imageID    = in[i].imageID;
+    out[i].objID      = in[i].objID;
+    out[i].catID      = in[i].catID;
+    out[i].extID      = in[i].extID;
+    out[i].psfQual    = in[i].psfQual;
+    out[i].psfChisq   = in[i].psfChisq;
+    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;
+    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].dXccd      = in[i].dXccd;
+    out[i].dYccd      = in[i].dYccd;
+    out[i].posangle   = in[i].posangle;
+    out[i].pltscale   = in[i].pltscale;
+    out[i].photcode   = in[i].photcode;
+    out[i].dbFlags    = in[i].dbFlags;
+    out[i].photFlags  = in[i].photFlags;
+  }
+  return (out);
+}
+
+Measure_PS1_V1 *MeasureInternalTo_PS1_V1 (Measure *in, int Nvalues) {
+
+  int i;
+  Measure_PS1_V1 *out;
+
+  ALLOCATE (out, Measure_PS1_V1, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    out[i].dR         = in[i].dR;
+    out[i].dD         = in[i].dD;
+    out[i].M          = in[i].M;
+    out[i].Mcal       = in[i].Mcal;
+    out[i].Map        = in[i].Map;
+    out[i].dM         = in[i].dM;
+    out[i].dMcal      = in[i].dMcal;
+    out[i].dt         = in[i].dt;
+    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].Sky        = in[i].Sky;
+    out[i].dSky       = in[i].dSky;
+    out[i].t          = in[i].t;
+    out[i].t_msec     = in[i].t_msec;
+    out[i].averef     = in[i].averef;
+    out[i].detID      = in[i].detID;
+    out[i].imageID    = in[i].imageID;
+    out[i].objID      = in[i].objID;
+    out[i].catID      = in[i].catID;
+    out[i].extID      = in[i].extID;
+    out[i].psfQual    = in[i].psfQual;
+    out[i].psfChisq   = in[i].psfChisq;
+    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;
+    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].dXccd      = in[i].dXccd;
+    out[i].dYccd      = in[i].dYccd;
+    out[i].posangle   = in[i].posangle;
+    out[i].pltscale   = in[i].pltscale;
+    out[i].photcode   = in[i].photcode;
+    out[i].dbFlags    = in[i].dbFlags;
+    out[i].photFlags  = in[i].photFlags;
+  }
+  return (out);
+}
+
+// 'primary' is needed to conform with the API for Loneos and Elixir, but is not used
+Average *Average_PS1_V1_ToInternal (Average_PS1_V1 *in, int Nvalues, SecFilt **primary) {
+
+  int i;
+  Average *out;
+
+  ALLOCATE (out, Average, 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].Xp       	 = in[i].Xp;     
+    out[i].ChiSq       	 = in[i].ChiSq;     
+    out[i].Npos       	 = in[i].Npos;     
+    out[i].Nmeasure      = in[i].Nmeasure;     
+    out[i].Nmissing      = in[i].Nmissing;     
+    out[i].Nextend       = in[i].Nextend;     
+    out[i].measureOffset = in[i].measureOffset; 
+    out[i].missingOffset = in[i].missingOffset;
+    out[i].extendOffset  = in[i].extendOffset;
+    out[i].flags     	 = in[i].flags;   
+    out[i].objID 	 = in[i].objID;
+    out[i].catID 	 = in[i].catID;
+    out[i].extID 	 = in[i].extID;
+  }
+  return (out);
+}
+
+// 'primary' is needed to conform with the API for Loneos and Elixir, but is not used
+Average_PS1_V1 *AverageInternalTo_PS1_V1 (Average *in, int Nvalues, SecFilt *primary) {
+
+  int i;
+  Average_PS1_V1 *out;
+
+  ALLOCATE (out, Average_PS1_V1, 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].Xp       	 = in[i].Xp;     
+    out[i].ChiSq       	 = in[i].ChiSq;     
+    out[i].Npos       	 = in[i].Npos;     
+    out[i].Nmeasure      = in[i].Nmeasure;     
+    out[i].Nmissing      = in[i].Nmissing;     
+    out[i].Nextend       = in[i].Nextend;     
+    out[i].measureOffset = in[i].measureOffset; 
+    out[i].missingOffset = in[i].missingOffset;
+    out[i].extendOffset  = in[i].extendOffset;
+    out[i].flags     	 = in[i].flags;   
+    out[i].objID 	 = in[i].objID;
+    out[i].catID 	 = in[i].catID;
+    out[i].extID 	 = in[i].extID;
+  }
+  return (out);
+}
+
+SecFilt *SecFilt_PS1_V1_ToInternal (SecFilt_PS1_V1 *in, int Nvalues) {
+
+  int i;
+  SecFilt *out;
+
+  ALLOCATE (out, SecFilt, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    out[i].M     = in[i].M;      
+    out[i].dM    = in[i].dM;      
+    out[i].Xm    = in[i].Xm;     
+    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);
+}
+
+SecFilt_PS1_V1 *SecFiltInternalTo_PS1_V1 (SecFilt *in, int Nvalues) {
+
+  int i;
+  SecFilt_PS1_V1 *out;
+
+  ALLOCATE (out, SecFilt_PS1_V1, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    out[i].M     = in[i].M;      
+    out[i].dM    = in[i].dM;      
+    out[i].Xm    = in[i].Xm;     
+    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);
+}
+
+Image *Image_PS1_V1_ToInternal (Image_PS1_V1 *in, int Nvalues) {
+
+  int i;
+  Image *out;
+
+  ALLOCATE (out, Image, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    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
+
+    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].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;
+
+    out[i].order	    = in[i].order;
+    out[i].Mx		    = in[i].Mx;
+    out[i].My		    = in[i].My;
+    out[i].Mxx		    = in[i].Mxx;
+    out[i].Mxy		    = in[i].Mxy;
+    out[i].Myy		    = in[i].Myy;
+    out[i].Mxxx		    = in[i].Mxxx;
+    out[i].Mxxy		    = in[i].Mxxy;
+    out[i].Mxyy		    = in[i].Mxyy;
+    out[i].Myyy		    = in[i].Myyy;
+    out[i].Mxxxx	    = in[i].Mxxxx;
+    out[i].Mxxxy	    = in[i].Mxxxy;
+    out[i].Mxxyy	    = in[i].Mxxyy;
+    out[i].Mxyyy	    = in[i].Mxyyy;
+    out[i].Myyyy	    = in[i].Myyyy;
+  }
+  return (out);
+}
+
+Image_PS1_V1 *ImageInternalTo_PS1_V1 (Image *in, int Nvalues) {
+
+  int i;
+  Image_PS1_V1 *out;
+
+  ALLOCATE (out, Image_PS1_V1, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    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
+
+    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].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;
+
+    out[i].order	    = in[i].order;
+    out[i].Mx		    = in[i].Mx;
+    out[i].My		    = in[i].My;
+    out[i].Mxx		    = in[i].Mxx;
+    out[i].Mxy		    = in[i].Mxy;
+    out[i].Myy		    = in[i].Myy;
+    out[i].Mxxx		    = in[i].Mxxx;
+    out[i].Mxxy		    = in[i].Mxxy;
+    out[i].Mxyy		    = in[i].Mxyy;
+    out[i].Myyy		    = in[i].Myyy;
+    out[i].Mxxxx	    = in[i].Mxxxx;
+    out[i].Mxxxy	    = in[i].Mxxxy;
+    out[i].Mxxyy	    = in[i].Mxxyy;
+    out[i].Mxyyy	    = in[i].Mxyyy;
+    out[i].Myyyy	    = in[i].Myyyy;
+  }
+  return (out);
+}
+
+PhotCode *PhotCode_PS1_V1_To_Internal (PhotCode_PS1_V1 *in, int Nvalues) {
+
+  int i;
+  PhotCode *out;
+
+  ALLOCATE (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_V1 *PhotCode_Internal_To_PS1_V1 (PhotCode *in, int Nvalues) {
+
+  int i;
+  PhotCode_PS1_V1 *out;
+
+  ALLOCATE (out, PhotCode_PS1_V1, 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);
+}
Index: /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvo_convert_elixir.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvo_convert_elixir.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvo_convert_elixir.c	(revision 21536)
@@ -10,4 +10,9 @@
 
   for (i = 0; i < Nvalues; i++) {
+    out[i].FWx 	    = in[i].FWx;
+    out[i].t        = in[i].t;
+    out[i].averef   = in[i].averef;
+
+    // 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;
@@ -16,38 +21,47 @@
     out[i].dt       = (in[i].dt      == NAN_S_SHORT) ? NAN : in[i].dt     * 0.001;
     out[i].Mcal     = (in[i].Mcal    == NAN_S_SHORT) ? NAN : in[i].Mcal   * 0.001;
-
-    // 2008.02.26 : I've renamed Mgal to Map, and intend it to be used per aperture
-    // magnitudes.  Most uses of Mgal in the past were actually aperture (isophotal) mags
     out[i].Map      = (in[i].Mgal    == NAN_S_SHORT) ? NAN : in[i].Mgal   * 0.001;
     out[i].airmass  = (in[i].airmass == NAN_S_SHORT) ? NAN : in[i].airmass* 0.001;
-    out[i].FWx 	    = in[i].FWx;
     out[i].FWy 	    = in[i].fwy * in[i].FWx * 0.01;
     out[i].theta    = in[i].theta*(0x10000 / 0x100);
-    out[i].dophot   = in[i].dophot;
     out[i].photcode = in[i].source;
-    out[i].t        = in[i].t;
-    out[i].averef   = in[i].averef;
-    out[i].dbFlags  = in[i].flags;
     
-    /* these can be determined if needed / desired */
-    out[i].Xccd     = 0;
-    out[i].Yccd     = 0;
-    out[i].dXccd    = 0;
-    out[i].dYccd    = 0;
-
-    /* these do not have a corresponding value */
+    // added for PANSTARRS_DEV_0
+    out[i].Xccd      = 0;  // determine on-the-fly
+    out[i].Yccd      = 0;  // determine on-the-fly
+    out[i].dXccd     = 0;
+    out[i].dYccd     = 0;
     out[i].az        = 0;
-    out[i].stargal   = 0;
     out[i].Sky       = 0;
     out[i].dSky      = 0;
-    out[i].qPSF      = 0;
+    out[i].psfQual   = 0;
     out[i].psfChisq  = 0;
     out[i].crNsigma  = 0;
     out[i].extNsigma = 0;
-    out[i].photFlags = 0;
-
-    /* XXX add these later */
-    out[i].detID = 0;
-    out[i].imageID = 0;
+    out[i].detID     = 0;  // determine on-the-fly
+    out[i].imageID   = 0;  // determine on-the-fly
+
+    // changed or added for PS1_DEV_1 (2008.02.26)
+    out[i].dbFlags    = in[i].flags;
+    out[i].detID      = 0;
+    out[i].imageID    = 0;
+
+    // changed or added for PS1_DEV_2
+    out[i].Map        = in[i].Mgal;
+    out[i].dMcal      = 0; 
+
+    // changed or added for PS1_V1
+    out[i].photFlags  = in[i].dophot << 16;
+    out[i].t_msec     = 0;
+    out[i].extID      = 0;
+    out[i].objID      = 0;
+    out[i].catID      = 0;
+    out[i].Mxx 	      = 0.0;
+    out[i].Mxy 	      = 0.0;
+    out[i].Myy        = 0.0;
+    out[i].posangle   = 0;
+    out[i].pltscale   = 0;
+    out[i].psfNdof    = 0;
+    out[i].psfNpix    = 0;
   }
   return (out);
@@ -63,4 +77,9 @@
 
   for (i = 0; i < Nvalues; i++) {
+    out[i].FWx 	   = in[i].FWx;
+    out[i].t       = in[i].t;
+    out[i].averef  = in[i].averef;
+
+    // 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;
@@ -71,4 +90,7 @@
     out[i].Mgal     = isnan(in[i].Map    ) ? NAN_S_SHORT : in[i].Map     * 1000.0;
     out[i].airmass  = isnan(in[i].airmass) ? NAN_S_SHORT : in[i].airmass * 1000.0;
+    out[i].fwy 	    = in[i].FWy * 100.0 / in[i].FWx;
+    out[i].theta    = in[i].theta*(0x100/ 0x10000);
+    out[i].source   = in[i].photcode;
 
     if (out[i].M < 0) {
@@ -76,12 +98,9 @@
     }
 
-    out[i].FWx 	   = in[i].FWx;
-    out[i].fwy 	   = in[i].FWy * 100.0 / in[i].FWx;
-    out[i].theta   = in[i].theta*(0x100/ 0x10000);
-    out[i].dophot  = in[i].dophot;
-    out[i].source  = in[i].photcode;
-    out[i].t       = in[i].t;
-    out[i].averef  = in[i].averef;
+    // changed or added for PS1_DEV_1 (2008.02.26)
     out[i].flags   = in[i].dbFlags;
+
+    // changed or added for PS1_V1
+    out[i].dophot  = in[i].photFlags >> 16;
   }
   return (out);
@@ -101,11 +120,14 @@
     out[i].D       	 = in[i].D;      
     out[i].Xp      	 = in[i].Xp;     
-    out[i].Nmeasure 	 = in[i].Nm;     
-    out[i].Nmissing 	 = in[i].Nn;     
-    out[i].code     	 = in[i].code;   
-    out[i].measureOffset = in[i].offset; 
-    out[i].missingOffset = in[i].missing;
-
-    /* these don't exist in Elixir */
+
+    // 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].dM    = (in[i].dM == NAN_S_SHORT) ? NAN : in[i].dM * 0.001;      
+    primary[0][i].Xm    = in[i].Xm;     
+
+    primary[0][i].Ncode = 0;     
+    primary[0][i].Nused = 0;
+
+    // added for PANSTARRS_DEV_0
     out[i].dR      = 0;
     out[i].dD      = 0;
@@ -116,14 +138,20 @@
     out[i].P       = 0;
     out[i].dP      = 0;
-
-    /* XXX add these later */
-    out[i].objID   = 0;
-    out[i].catID   = 0;
-
-    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].Ncode = 0;     
-    primary[0][i].Nused = 0;
+    out[i].objID   = 0; // determine on-the-fly
+    out[i].catID   = 0; // determine on-the-fly
+
+    // changed or added for PS1_DEV_2
+    out[i].Nmeasure 	 = in[i].Nm;     
+    out[i].Nmissing 	 = in[i].Nn;     
+    out[i].measureOffset = in[i].offset; 
+    out[i].missingOffset = in[i].missing;
+    out[i].Nextend       = 0;
+    out[i].extendOffset  = 0;
+
+    // changed or added for PS1_V1
+    out[i].flags    	 = in[i].code;   
+    out[i].ChiSq       	 = 0.0;
+    out[i].Npos       	 = 0.0;
+    out[i].extID 	 = 0;
   }
   return (out);
@@ -142,13 +170,18 @@
     out[i].D       = in[i].D;      
     out[i].Xp      = in[i].Xp;     
-    out[i].Nm      = in[i].Nmeasure;     
-    out[i].Nn      = in[i].Nmissing;     
-    out[i].code    = in[i].code;   
-    out[i].offset  = in[i].measureOffset; 
-    out[i].missing = in[i].missingOffset;
-
+
+    // 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].dM      = isnan(primary[i].dM) ? NAN_S_SHORT : primary[i].dM  * 1000.0;
     out[i].Xm      = primary[i].Xm;     
+
+    // changed or added for PS1_DEV_2
+    out[i].Nm      = in[i].Nmeasure;     
+    out[i].Nn      = in[i].Nmissing;     
+    out[i].offset  = in[i].measureOffset; 
+    out[i].missing = in[i].missingOffset;
+
+    // changed or added for PS1_V1
+    out[i].code    = in[i].flags;   
   }
   return (out);
@@ -164,9 +197,15 @@
 
   for (i = 0; i < Nvalues; i++) {
+    out[i].Xm    = in[i].Xm;     
+
+    // added or changed for PANSTARRS_DEV_0
     out[i].M     = (in[i].M  == NAN_S_SHORT) ? NAN : in[i].M   * 0.001;
     out[i].dM    = (in[i].dM == NAN_S_SHORT) ? NAN : in[i].dM  * 0.001;
-    out[i].Xm    = in[i].Xm;     
     out[i].Ncode = 0;
     out[i].Nused = 0;
+
+    // changed or added for PS1_V1
+    out[i].M_20  = 0;      
+    out[i].M_80  = 0;      
   }
   return (out);
@@ -182,7 +221,9 @@
 
   for (i = 0; i < Nvalues; i++) {
+    out[i].Xm    = in[i].Xm;     
+
+    // added or changed for PANSTARRS_DEV_0
     out[i].M     = isnan(in[i].M)  ? NAN_S_SHORT : in[i].M   * 1000.0;
     out[i].dM    = isnan(in[i].dM) ? NAN_S_SHORT : in[i].dM  * 1000.0;
-    out[i].Xm    = in[i].Xm;     
   }
   return (out);
@@ -207,9 +248,4 @@
     out[i].NX	    	    = in[i].NX;
     out[i].NY	    	    = in[i].NY;
-    out[i].secz    	    = (in[i].secz     == NAN_S_SHORT) ? NAN : in[i].secz     * 0.001;
-    out[i].apmifit  	    = (in[i].apmifit  == NAN_S_SHORT) ? NAN : in[i].apmifit  * 0.001;
-    out[i].dapmifit  	    = (in[i].dapmifit == NAN_S_SHORT) ? NAN : in[i].dapmifit * 0.001;
-    out[i].Mcal   	    = (in[i].Mcal     == NAN_S_SHORT) ? NAN : in[i].Mcal     * 0.001;
-    out[i].dMcal   	    = (in[i].dMcal    == NAN_S_SHORT) ? NAN : in[i].dMcal    * 0.001;
     out[i].Xm	    	    = in[i].Xm;
     out[i].photcode   	    = in[i].source;
@@ -221,5 +257,4 @@
     out[i].fwhm_y	    = in[i].fwhm_y;
     out[i].trate	    = in[i].trate;
-    out[i].code		    = in[i].code;
     out[i].ccdnum	    = in[i].ccdnum;
 
@@ -240,10 +275,21 @@
     out[i].Myyyy	    = in[i].Myyyy;
 
-    /* XXX add these later */
-    out[i].imageID = 0;
-
-    // not available in ELIXIR
+    // added or changed for PANSTARRS_DEV_0
+    out[i].secz    	    = (in[i].secz     == NAN_S_SHORT) ? NAN : in[i].secz     * 0.001;
+    out[i].apmifit  	    = (in[i].apmifit  == NAN_S_SHORT) ? NAN : in[i].apmifit  * 0.001;
+    out[i].dapmifit  	    = (in[i].dapmifit == NAN_S_SHORT) ? NAN : in[i].dapmifit * 0.001;
+    out[i].Mcal   	    = (in[i].Mcal     == NAN_S_SHORT) ? NAN : in[i].Mcal     * 0.001;
+    out[i].dMcal   	    = (in[i].dMcal    == NAN_S_SHORT) ? NAN : in[i].dMcal    * 0.001;
     out[i].sidtime  	    = NAN;
     out[i].latitude  	    = NAN;
+    out[i].imageID          = 0; // determine on-the-fly
+
+    // changed or added for PS1_DEV_2
+    out[i].externID	    = 0;
+    out[i].sourceID	    = 0;
+
+    // changed or added for PS1_V1
+    out[i].flags	    = in[i].code;
+    out[i].parentID	    = 0;
   }
   return (out);
@@ -268,9 +314,5 @@
     out[i].NX	    	    = in[i].NX;
     out[i].NY	    	    = in[i].NY;
-    out[i].secz    	    = isnan(in[i].secz    ) ? NAN_S_SHORT : in[i].secz     * 1000.0;
-    out[i].apmifit    	    = isnan(in[i].apmifit ) ? NAN_S_SHORT : in[i].apmifit  * 1000.0;
-    out[i].dapmifit    	    = isnan(in[i].dapmifit) ? NAN_S_SHORT : in[i].dapmifit * 1000.0;
-    out[i].Mcal    	    = isnan(in[i].Mcal    ) ? NAN_S_SHORT : in[i].Mcal     * 1000.0;
-    out[i].dMcal    	    = isnan(in[i].dMcal   ) ? NAN_S_SHORT : in[i].dMcal    * 1000.0;
+
     out[i].Xm	    	    = in[i].Xm;
     out[i].source   	    = in[i].photcode;
@@ -282,5 +324,4 @@
     out[i].fwhm_y	    = in[i].fwhm_y;
     out[i].trate	    = in[i].trate;
-    out[i].code		    = in[i].code;
     out[i].ccdnum	    = in[i].ccdnum;
 
@@ -300,14 +341,24 @@
     out[i].Mxyyy	    = in[i].Mxyyy;
     out[i].Myyyy	    = in[i].Myyyy;
-  }
-  return (out);
-}
-
-PhotCode_Elixir *PhotCode_Internal_To_Elixir (PhotCode *in, int Nvalues) {
-
-  int i;
-  PhotCode_Elixir *out;
-
-  ALLOCATE (out, PhotCode_Elixir, Nvalues);
+
+    // added or changed for PANSTARRS_DEV_0
+    out[i].secz    	    = isnan(in[i].secz    ) ? NAN_S_SHORT : in[i].secz     * 1000.0;
+    out[i].apmifit    	    = isnan(in[i].apmifit ) ? NAN_S_SHORT : in[i].apmifit  * 1000.0;
+    out[i].dapmifit    	    = isnan(in[i].dapmifit) ? NAN_S_SHORT : in[i].dapmifit * 1000.0;
+    out[i].Mcal    	    = isnan(in[i].Mcal    ) ? NAN_S_SHORT : in[i].Mcal     * 1000.0;
+    out[i].dMcal    	    = isnan(in[i].dMcal   ) ? NAN_S_SHORT : in[i].dMcal    * 1000.0;
+
+    // changed or added for PS1_V1
+    out[i].code		    = in[i].flags;
+  }
+  return (out);
+}
+
+PhotCode *PhotCode_Elixir_To_Internal (PhotCode_Elixir *in, int Nvalues) {
+
+  int i;
+  PhotCode *out;
+
+  ALLOCATE (out, PhotCode, Nvalues);
 
   for (i = 0; i < Nvalues; i++) {
@@ -326,14 +377,28 @@
     out[i].Nc    = in[i].Nc;           
     memcpy (out[i].X, in[i].X, 4*sizeof(float));            
-  }
-  return (out);
-}
-
-PhotCode *PhotCode_Elixir_To_Internal (PhotCode_Elixir *in, int Nvalues) {
-
-  int i;
-  PhotCode *out;
-
-  ALLOCATE (out, PhotCode, Nvalues);
+
+    // changed or added for PS1_DEV_1
+    out[i].astromErrMagScale = 0.0;
+    out[i].photomErrSys      = 0.0;
+
+    // changed or added for PS1_DEV_2
+    out[i].astromErrSys      = 0.0;
+    out[i].astromErrScale    = 0.0;
+
+    // changed or added for PS1_V1 (also PS1_DEV_3, deprecated)
+    out[i].photomPoorMask      = 0;
+    out[i].photomBadMask       = 0;
+    out[i].astromPoorMask      = 0;
+    out[i].astromBadMask       = 0;
+  }
+  return (out);
+}
+
+PhotCode_Elixir *PhotCode_Internal_To_Elixir (PhotCode *in, int Nvalues) {
+
+  int i;
+  PhotCode_Elixir *out;
+
+  ALLOCATE (out, PhotCode_Elixir, Nvalues);
 
   for (i = 0; i < Nvalues; i++) {
@@ -352,16 +417,5 @@
     out[i].Nc    = in[i].Nc;           
     memcpy (out[i].X, in[i].X, 4*sizeof(float));            
-
-    // not defined in Elixir:
-    out[i].astromErrSys      = 0.0;
-    out[i].astromErrScale    = 0.0;
-    out[i].astromErrMagScale = 0.0;
-    out[i].photomErrSys      = 0.0;
-
-    out[i].photomPoorMask      = 0;
-    out[i].photomBadMask       = 0;
-    out[i].astromPoorMask      = 0;
-    out[i].astromBadMask       = 0;
-  }
-  return (out);
-}
+  }
+  return (out);
+}
Index: /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvo_convert_loneos.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvo_convert_loneos.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvo_convert_loneos.c	(revision 21536)
@@ -10,46 +10,60 @@
 
   for (i = 0; i < Nvalues; i++) {
-    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;
-    out[i].Mcal      = (in[i].Mcal    == NAN_S_SHORT) ? NAN : in[i].Mcal   * 0.001;
-    out[i].dophot    = in[i].dophot;
-    out[i].photcode  = in[i].source;
-    out[i].t         = in[i].t;
-
-    /* flags and averef are now split */
+    out[i].t        = in[i].t;
+
+    // added or changed for ELIXIR
     out[i].averef    =  in[i].averef & 0x00ffffff;
     out[i].dbFlags   = (in[i].averef & 0xff000000) >> 24;
-
-    /* these values don't exist in the Loneos format */
-
-    // 2008.02.26 : I've renamed Mgal to Map, and intend it to be used per aperture
-    // magnitudes.  Most uses of Mgal in the past were actually aperture (isophotal) mags
-    out[i].Map       = out[i].M;
+    out[i].t         = in[i].t;
     out[i].dt        = 0;
     out[i].airmass   = 0;
+    out[i].FWy 	     = 0;
+    out[i].FWx       = 0;
+    out[i].theta     = 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;
+    out[i].Mcal     = (in[i].Mcal    == NAN_S_SHORT) ? NAN : in[i].Mcal   * 0.001;
+    out[i].Map      = (in[i].M       == NAN_S_SHORT) ? NAN : in[i].M      * 0.001;
+    out[i].photcode = in[i].source;
+    
+    // added for PANSTARRS_DEV_0
+    out[i].Xccd      = 0;  // determine on-the-fly
+    out[i].Yccd      = 0;  // determine on-the-fly
+    out[i].dXccd     = 0;
+    out[i].dYccd     = 0;
     out[i].az        = 0;
-    out[i].FWx 	     = 0;
-    out[i].FWy 	     = 0;
-    out[i].theta     = 0;
-    out[i].stargal   = 0;
     out[i].Sky       = 0;
     out[i].dSky      = 0;
-    out[i].qPSF      = 0;
+    out[i].psfQual   = 0;
     out[i].psfChisq  = 0;
     out[i].crNsigma  = 0;
     out[i].extNsigma = 0;
-    out[i].photFlags = 0;
-
-    /* these can be determined if needed / desired */
-    out[i].Xccd     = 0;
-    out[i].Yccd     = 0;
-    out[i].dXccd    = 0;
-    out[i].dYccd    = 0;
-
-    /* XXX add these later */
-    out[i].detID = 0;
-    out[i].imageID = 0;
+    out[i].detID     = 0;  // determine on-the-fly
+    out[i].imageID   = 0;  // determine on-the-fly
+
+    // changed or added for PS1_DEV_1 (2008.02.26)
+    out[i].detID      = 0;
+    out[i].imageID    = 0;
+
+    // changed or added for PS1_DEV_2
+    out[i].dMcal      = 0; 
+
+    // changed or added for PS1_V1
+    out[i].photFlags  = in[i].dophot << 16;
+    out[i].t_msec     = 0;
+    out[i].extID      = 0;
+    out[i].objID      = 0;
+    out[i].catID      = 0;
+    out[i].Mxx 	      = 0.0;
+    out[i].Mxy 	      = 0.0;
+    out[i].Myy        = 0.0;
+    out[i].posangle   = 0;
+    out[i].pltscale   = 0;
+    out[i].psfNdof    = 0;
+    out[i].psfNpix    = 0;
   }
   return (out);
@@ -65,4 +79,6 @@
 
   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;
@@ -70,5 +86,4 @@
     out[i].dM     = isnan(in[i].dM     ) ? NAN_U_CHAR  : in[i].dM      * 1000.0;
     out[i].Mcal   = isnan(in[i].Mcal   ) ? NAN_S_SHORT : in[i].Mcal    * 1000.0;
-    out[i].dophot = in[i].dophot;
     out[i].source = in[i].photcode;
     out[i].t      = in[i].t;
@@ -76,4 +91,7 @@
     /* flags and averef are merged in Loneos */
     out[i].averef =  (in[i].averef & 0x00ffffff) | (in[i].dbFlags << 24);
+
+    // changed or added for PS1_V1
+    out[i].dophot  = in[i].photFlags >> 16;
   }
   return (out);
@@ -93,11 +111,15 @@
     out[i].D       	 = in[i].D;      
     out[i].Xp      	 = in[i].Xp;     
-    out[i].Nmeasure      = in[i].Nm;     
-    out[i].Nmissing      = in[i].Nn;     
-    out[i].code    	 = in[i].code;   
-    out[i].measureOffset = in[i].offset; 
-    out[i].missingOffset = in[i].missing;
-
-    /* these don't exist in Loneos */
+
+    // added for ELIXIR
+    primary[0][i].dM    = NAN;
+
+    // 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].Ncode = 0;     
+    primary[0][i].Nused = 0;
+
+    // added for PANSTARRS_DEV_0
     out[i].dR      = 0;
     out[i].dD      = 0;
@@ -108,14 +130,20 @@
     out[i].P       = 0;
     out[i].dP      = 0;
-
-    /* XXX add these later */
-    out[i].objID   = 0;
-    out[i].catID   = 0;
-
-    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].dM = NAN;
-    primary[0][i].Ncode = 0;     
-    primary[0][i].Nused = 0;
+    out[i].objID   = 0; // determine on-the-fly
+    out[i].catID   = 0; // determine on-the-fly
+
+    // changed or added for PS1_DEV_2
+    out[i].Nmeasure 	 = in[i].Nm;     
+    out[i].Nmissing 	 = in[i].Nn;     
+    out[i].measureOffset = in[i].offset; 
+    out[i].missingOffset = in[i].missing;
+    out[i].Nextend       = 0;
+    out[i].extendOffset  = 0;
+
+    // changed or added for PS1_V1
+    out[i].flags    	 = in[i].code;   
+    out[i].ChiSq       	 = 0.0;
+    out[i].Npos       	 = 0.0;
+    out[i].extID 	 = 0;
   }
   return (out);
@@ -134,12 +162,17 @@
     out[i].D       = in[i].D;      
     out[i].Xp      = in[i].Xp;     
+
+    // 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;     
+
+    // changed or added for PS1_DEV_2
     out[i].Nm      = in[i].Nmeasure;     
     out[i].Nn      = in[i].Nmissing;     
-    out[i].code    = in[i].code;   
     out[i].offset  = in[i].measureOffset; 
     out[i].missing = in[i].missingOffset;
 
-    out[i].M       = isnan(primary[i].M)  ? NAN_S_SHORT : primary[i].M   * 1000.0;
-    out[i].Xm      = primary[i].Xm;     
+    // changed or added for PS1_V1
+    out[i].code    = in[i].flags;   
   }
   return (out);
@@ -155,9 +188,17 @@
 
   for (i = 0; i < Nvalues; i++) {
+    out[i].Xm    = in[i].Xm;      
+
+    // added for ELIXIR
+    out[i].dM    = NAN;
+
+    // added or changed for PANSTARRS_DEV_0
     out[i].M     = (in[i].M  == NAN_S_SHORT) ? NAN : in[i].M * 0.001;
-    out[i].Xm    = in[i].Xm;      
-    out[i].dM    = NAN;
     out[i].Ncode = 0;
     out[i].Nused = 0;
+
+    // changed or added for PS1_V1
+    out[i].M_20  = 0;      
+    out[i].M_80  = 0;      
   }
   return (out);
@@ -173,6 +214,8 @@
 
   for (i = 0; i < Nvalues; i++) {
+    out[i].Xm   = in[i].Xm;      
+
+    // added or changed for PANSTARRS_DEV_0
     out[i].M    = isnan(in[i].M)  ? NAN_S_SHORT : in[i].M * 1000.0;
-    out[i].Xm   = in[i].Xm;      
   }
   return (out);
@@ -197,10 +240,4 @@
     out[i].NX	    	    = in[i].NX;
     out[i].NY	    	    = in[i].NY;
-
-    out[i].secz    	    = (in[i].secz     == NAN_S_SHORT) ? NAN : in[i].secz     * 0.001;
-    out[i].apmifit  	    = (in[i].apmifit  == NAN_S_SHORT) ? NAN : in[i].apmifit  * 0.001;
-    out[i].dapmifit  	    = (in[i].dapmifit == NAN_S_SHORT) ? NAN : in[i].dapmifit * 0.001;
-    out[i].Mcal   	    = (in[i].Mcal     == NAN_S_SHORT) ? NAN : in[i].Mcal     * 0.001;
-    out[i].dMcal   	    = (in[i].dMcal    == NAN_S_SHORT) ? NAN : in[i].dMcal    * 0.001;
 
     out[i].Xm	    	    = in[i].Xm;
@@ -213,6 +250,6 @@
     out[i].fwhm_y	    = in[i].fwhm_y;
     out[i].trate	    = in[i].trate;
-    out[i].code		    = in[i].code;
     out[i].ccdnum	    = in[i].ccdnum;
+
     out[i].order	    = in[i].order;
     out[i].Mx		    = in[i].Mx;
@@ -231,6 +268,21 @@
     out[i].Myyyy	    = in[i].Myyyy;
 
-    /* XXX add these later */
-    out[i].imageID = 0;
+    // added or changed for PANSTARRS_DEV_0
+    out[i].secz    	    = (in[i].secz     == NAN_S_SHORT) ? NAN : in[i].secz     * 0.001;
+    out[i].apmifit  	    = (in[i].apmifit  == NAN_S_SHORT) ? NAN : in[i].apmifit  * 0.001;
+    out[i].dapmifit  	    = (in[i].dapmifit == NAN_S_SHORT) ? NAN : in[i].dapmifit * 0.001;
+    out[i].Mcal   	    = (in[i].Mcal     == NAN_S_SHORT) ? NAN : in[i].Mcal     * 0.001;
+    out[i].dMcal   	    = (in[i].dMcal    == NAN_S_SHORT) ? NAN : in[i].dMcal    * 0.001;
+    out[i].sidtime  	    = NAN;
+    out[i].latitude  	    = NAN;
+    out[i].imageID          = 0; // determine on-the-fly
+
+    // changed or added for PS1_DEV_2
+    out[i].externID	    = 0;
+    out[i].sourceID	    = 0;
+
+    // changed or added for PS1_V1
+    out[i].flags	    = in[i].code;
+    out[i].parentID	    = 0;
   }
   return (out);
@@ -255,10 +307,4 @@
     out[i].NX	    	    = in[i].NX;
     out[i].NY	    	    = in[i].NY;
-
-    out[i].secz    	    = isnan(in[i].secz    ) ? NAN_S_SHORT : in[i].secz     * 1000.0;
-    out[i].apmifit    	    = isnan(in[i].apmifit ) ? NAN_S_SHORT : in[i].apmifit  * 1000.0;
-    out[i].dapmifit    	    = isnan(in[i].dapmifit) ? NAN_S_SHORT : in[i].dapmifit * 1000.0;
-    out[i].Mcal    	    = isnan(in[i].Mcal    ) ? NAN_S_SHORT : in[i].Mcal     * 1000.0;
-    out[i].dMcal    	    = isnan(in[i].dMcal   ) ? NAN_S_SHORT : in[i].dMcal    * 1000.0;
 
     out[i].Xm	    	    = in[i].Xm;
@@ -271,6 +317,6 @@
     out[i].fwhm_y	    = in[i].fwhm_y;
     out[i].trate	    = in[i].trate;
-    out[i].code		    = in[i].code;
     out[i].ccdnum	    = in[i].ccdnum;
+
     out[i].order	    = in[i].order;
     out[i].Mx		    = in[i].Mx;
@@ -288,5 +334,15 @@
     out[i].Mxyyy	    = in[i].Mxyyy;
     out[i].Myyyy	    = in[i].Myyyy;
-  }
-  return (out);
-}
+
+    // added or changed for PANSTARRS_DEV_0
+    out[i].secz    	    = isnan(in[i].secz    ) ? NAN_S_SHORT : in[i].secz     * 1000.0;
+    out[i].apmifit    	    = isnan(in[i].apmifit ) ? NAN_S_SHORT : in[i].apmifit  * 1000.0;
+    out[i].dapmifit    	    = isnan(in[i].dapmifit) ? NAN_S_SHORT : in[i].dapmifit * 1000.0;
+    out[i].Mcal    	    = isnan(in[i].Mcal    ) ? NAN_S_SHORT : in[i].Mcal     * 1000.0;
+    out[i].dMcal    	    = isnan(in[i].dMcal   ) ? NAN_S_SHORT : in[i].dMcal    * 1000.0;
+
+    // changed or added for PS1_V1
+    out[i].code		    = in[i].flags;
+  }
+  return (out);
+}
Index: /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvo_convert_panstarrs_DEV_0.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvo_convert_panstarrs_DEV_0.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvo_convert_panstarrs_DEV_0.c	(revision 21536)
@@ -16,7 +16,4 @@
     out[i].Mcal       = in[i].Mcal;
 
-    // 2008.02.26 : I've renamed Mgal to Map, and intend it to be used per aperture
-    // magnitudes.  Most uses of Mgal in the past were actually aperture (isophotal) mags
-    out[i].Map        = in[i].Mgal;
     out[i].airmass    = in[i].airmass;
     out[i].az         = in[i].az;
@@ -25,25 +22,43 @@
     out[i].FWy 	      = in[i].FWy;
     out[i].theta      = in[i].theta;
-    out[i].dophot     = in[i].dophot;
     out[i].photcode   = in[i].photcode;
     out[i].t          = in[i].t;
     out[i].averef     = in[i].averef;
-    out[i].dbFlags    = in[i].flags;
     out[i].Xccd       = in[i].Xccd;
     out[i].Yccd       = in[i].Yccd;
     out[i].dXccd      = in[i].dXccd;
     out[i].dYccd      = in[i].dYccd;
-    out[i].stargal    = in[i].stargal;
     out[i].Sky        = in[i].Sky;
     out[i].dSky       = in[i].dSky;
-    out[i].qPSF       = (in[i].qPSF == NAN_S_SHORT) ? NAN : in[i].qPSF;
+
+    // 2008.02.26 : I've renamed Mgal to Map, and intend it to be used per aperture
+    // magnitudes.  Most uses of Mgal in the past were actually aperture (isophotal) mags
+
+    // changed or added for PS1_DEV_1 (2008.02.26)
+    out[i].psfQual    = (in[i].psfQual == NAN_S_SHORT) ? NAN : in[i].psfQual;
+    out[i].dbFlags    = in[i].flags;
     out[i].detID      = in[i].detID_lo;
     out[i].imageID    = in[i].imageID_lo;
-
-    // these don't have a correspondence
-    out[i].psfChisq  = 0;
-    out[i].crNsigma  = 0;
-    out[i].extNsigma = 0;
-    out[i].photFlags = 0;
+    out[i].psfChisq   = 0;
+    out[i].crNsigma   = 0;
+    out[i].extNsigma  = 0;
+
+    // changed or added for PS1_DEV_2
+    out[i].Map        = in[i].Mgal;
+    out[i].dMcal      = 0; 
+
+    // changed or added for PS1_V1
+    out[i].photFlags  = in[i].dophot << 16;
+    out[i].t_msec     = 0;
+    out[i].extID      = 0;
+    out[i].objID      = 0;
+    out[i].catID      = 0;
+    out[i].Mxx 	      = 0.0;
+    out[i].Mxy 	      = 0.0;
+    out[i].Myy        = 0.0;
+    out[i].posangle   = 0;
+    out[i].pltscale   = 0;
+    out[i].psfNdof    = 0;
+    out[i].psfNpix    = 0;
   }
   return (out);
@@ -64,5 +79,4 @@
     out[i].dM         = in[i].dM;
     out[i].Mcal       = in[i].Mcal;
-    out[i].Mgal       = in[i].Map;
     out[i].airmass    = in[i].airmass;
     out[i].az         = in[i].az;
@@ -71,21 +85,28 @@
     out[i].FWy 	      = in[i].FWy;
     out[i].theta      = in[i].theta;
-    out[i].dophot     = in[i].dophot;
     out[i].photcode   = in[i].photcode;
     out[i].t          = in[i].t;
     out[i].averef     = in[i].averef;
-    out[i].flags      = in[i].dbFlags;
     out[i].Xccd       = in[i].Xccd;
     out[i].Yccd       = in[i].Yccd;
     out[i].dXccd      = in[i].dXccd;
     out[i].dYccd      = in[i].dYccd;
-    out[i].stargal    = in[i].stargal;
     out[i].Sky        = in[i].Sky;
     out[i].dSky       = in[i].dSky;
-    out[i].qPSF       = isnan(in[i].qPSF) ? NAN_S_SHORT : in[i].qPSF;
+
+    // changed or added for PS1_DEV_1 (2008.02.26)
+    out[i].flags      = in[i].dbFlags;
+    out[i].psfQual    = isnan(in[i].psfQual) ? NAN_S_SHORT : in[i].psfQual;
     out[i].detID_hi   = 0;
     out[i].detID_lo   = in[i].detID;
     out[i].imageID_hi = 0;
     out[i].imageID_lo = in[i].imageID;
+
+    // changed or added for PS1_DEV_2
+    out[i].Mgal       = in[i].Map;
+
+    // changed or added for PS1_V1
+    // out[i].photFlags  = in[i].photFlags & 0x0000ffff; (only dophot pre PS1_DEV_1)
+    out[i].dophot     = in[i].photFlags >> 16;
   }
   return (out);
@@ -105,9 +126,4 @@
     out[i].D        	 = in[i].D;      
     out[i].Xp       	 = in[i].Xp;     
-    out[i].Nmeasure      = in[i].Nm;     
-    out[i].Nmissing      = in[i].Nn;     
-    out[i].code          = in[i].code;   
-    out[i].measureOffset = in[i].offset; 
-    out[i].missingOffset = in[i].missing;
     out[i].dR       	 = in[i].dR;
     out[i].dD       	 = in[i].dD;
@@ -120,4 +136,18 @@
     out[i].objID 	 = in[i].objID;
     out[i].catID 	 = in[i].catID;
+
+    // changed or added for PS1_DEV_2
+    out[i].Nmeasure      = in[i].Nm;     
+    out[i].Nmissing      = in[i].Nn;     
+    out[i].measureOffset = in[i].offset; 
+    out[i].missingOffset = in[i].missing;
+    out[i].Nextend       = 0;
+    out[i].extendOffset  = 0;
+
+    // changed or added for PS1_V1
+    out[i].flags    	 = in[i].code;   
+    out[i].ChiSq       	 = 0.0;
+    out[i].Npos       	 = 0.0;
+    out[i].extID 	 = 0;
   }
   return (out);
@@ -137,9 +167,4 @@
     out[i].D        = in[i].D;      
     out[i].Xp       = in[i].Xp;     
-    out[i].Nm       = in[i].Nmeasure;     
-    out[i].Nn       = in[i].Nmissing;     
-    out[i].code     = in[i].code;   
-    out[i].offset   = in[i].measureOffset; 
-    out[i].missing  = in[i].missingOffset;
     out[i].dR       = in[i].dR;
     out[i].dD       = in[i].dD;
@@ -152,4 +177,13 @@
     out[i].objID    = in[i].objID;
     out[i].catID    = in[i].catID;
+
+    // changed or added for PS1_DEV_2
+    out[i].Nm       = in[i].Nmeasure;     
+    out[i].Nn       = in[i].Nmissing;     
+    out[i].offset   = in[i].measureOffset; 
+    out[i].missing  = in[i].missingOffset;
+
+    // changed or added for PS1_V1
+    out[i].code          = in[i].flags;   
   }
   return (out);
@@ -170,4 +204,8 @@
     out[i].Ncode = in[i].Ncode;
     out[i].Nused = in[i].Nused;
+
+    // changed or added for PS1_V1
+    out[i].M_20  = 0;      
+    out[i].M_80  = 0;      
  }
   return (out);
@@ -226,7 +264,5 @@
     out[i].fwhm_y	    = in[i].fwhm_y;
     out[i].trate	    = in[i].trate;
-    out[i].code		    = in[i].code;
     out[i].ccdnum	    = in[i].ccdnum;
-    out[i].imageID	    = in[i].imageID_lo;
 
     out[i].order	    = in[i].order;
@@ -245,4 +281,15 @@
     out[i].Mxyyy	    = in[i].Mxyyy;
     out[i].Myyyy	    = in[i].Myyyy;
+
+    // changed or added for PS1_DEV_1
+    out[i].imageID	    = in[i].imageID_lo;
+
+    // changed or added for PS1_DEV_2
+    out[i].externID	    = 0;
+    out[i].sourceID	    = 0;
+
+    // changed or added for PS1_V1
+    out[i].flags	    = in[i].code;
+    out[i].parentID	    = 0;
   }
   return (out);
@@ -283,8 +330,5 @@
     out[i].fwhm_y	    = in[i].fwhm_y;
     out[i].trate	    = in[i].trate;
-    out[i].code		    = in[i].code;
     out[i].ccdnum	    = in[i].ccdnum;
-    out[i].imageID_hi	    = 0;
-    out[i].imageID_lo	    = in[i].imageID;
 
     out[i].order	    = in[i].order;
@@ -303,5 +347,12 @@
     out[i].Mxyyy	    = in[i].Mxyyy;
     out[i].Myyyy	    = in[i].Myyyy;
-  }
-  return (out);
-}
+
+    // changed or added for PS1_DEV_1
+    out[i].imageID_hi	    = 0;
+    out[i].imageID_lo	    = in[i].imageID;
+
+    // changed or added for PS1_V1
+    out[i].code		    = in[i].flags;
+  }
+  return (out);
+}
Index: /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvo_convert_panstarrs_DEV_1.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvo_convert_panstarrs_DEV_1.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvo_convert_panstarrs_DEV_1.c	(revision 21536)
@@ -16,7 +16,4 @@
     out[i].Mcal       = in[i].Mcal;
 
-    // 2008.02.26 : I've renamed Mgal to Map, and intend it to be used per aperture
-    // magnitudes.  Most uses of Mgal in the past were actually aperture (isophotal) mags
-    out[i].Map        = in[i].Mgal;
     out[i].airmass    = in[i].airmass;
     out[i].az         = in[i].az;
@@ -25,25 +22,43 @@
     out[i].FWy 	      = in[i].FWy;
     out[i].theta      = in[i].theta;
-    out[i].dophot     = in[i].dophot;
     out[i].photcode   = in[i].photcode;
     out[i].t          = in[i].t;
     out[i].averef     = in[i].averef;
-    out[i].dbFlags    = in[i].flags;
     out[i].Xccd       = in[i].Xccd;
     out[i].Yccd       = in[i].Yccd;
     out[i].dXccd      = in[i].dXccd;
     out[i].dYccd      = in[i].dYccd;
-    out[i].stargal    = in[i].stargal;
     out[i].Sky        = in[i].Sky;
     out[i].dSky       = in[i].dSky;
-    out[i].qPSF       = (in[i].qPSF == NAN_S_SHORT) ? NAN : in[i].qPSF;
+
+    // 2008.02.26 : I've renamed Mgal to Map, and intend it to be used per aperture
+    // magnitudes.  Most uses of Mgal in the past were actually aperture (isophotal) mags
+
+    // changed or added for PS1_DEV_1 (2008.02.26)
+    out[i].psfQual    = (in[i].psfQual == NAN_S_SHORT) ? NAN : in[i].psfQual;
+    out[i].dbFlags    = in[i].flags;
     out[i].detID      = in[i].detID_lo;
     out[i].imageID    = in[i].imageID_lo;
-
-    // these don't have a correspondence
-    out[i].psfChisq  = 0;
-    out[i].crNsigma  = 0;
-    out[i].extNsigma = 0;
-    out[i].photFlags = 0;
+    out[i].psfChisq   = 0;
+    out[i].crNsigma   = 0;
+    out[i].extNsigma  = 0;
+
+    // changed or added for PS1_DEV_2
+    out[i].Map        = in[i].Mgal;
+    out[i].dMcal      = 0; 
+
+    // changed or added for PS1_V1
+    out[i].photFlags  = in[i].dophot << 16;
+    out[i].t_msec     = 0;
+    out[i].extID      = 0;
+    out[i].objID      = 0;
+    out[i].catID      = 0;
+    out[i].Mxx 	      = 0.0;
+    out[i].Mxy 	      = 0.0;
+    out[i].Myy        = 0.0;
+    out[i].posangle   = 0;
+    out[i].pltscale   = 0;
+    out[i].psfNdof    = 0;
+    out[i].psfNpix    = 0;
   }
   return (out);
@@ -64,5 +79,4 @@
     out[i].dM         = in[i].dM;
     out[i].Mcal       = in[i].Mcal;
-    out[i].Mgal       = in[i].Map;
     out[i].airmass    = in[i].airmass;
     out[i].az         = in[i].az;
@@ -71,21 +85,28 @@
     out[i].FWy 	      = in[i].FWy;
     out[i].theta      = in[i].theta;
-    out[i].dophot     = in[i].dophot;
     out[i].photcode   = in[i].photcode;
     out[i].t          = in[i].t;
     out[i].averef     = in[i].averef;
-    out[i].flags      = in[i].dbFlags;
     out[i].Xccd       = in[i].Xccd;
     out[i].Yccd       = in[i].Yccd;
     out[i].dXccd      = in[i].dXccd;
     out[i].dYccd      = in[i].dYccd;
-    out[i].stargal    = in[i].stargal;
     out[i].Sky        = in[i].Sky;
     out[i].dSky       = in[i].dSky;
-    out[i].qPSF       = isnan(in[i].qPSF) ? NAN_S_SHORT : in[i].qPSF;
+
+    // changed or added for PS1_DEV_1 (2008.02.26)
+    out[i].flags      = in[i].dbFlags;
+    out[i].psfQual    = isnan(in[i].psfQual) ? NAN_S_SHORT : in[i].psfQual;
     out[i].detID_hi   = 0;
     out[i].detID_lo   = in[i].detID;
     out[i].imageID_hi = 0;
     out[i].imageID_lo = in[i].imageID;
+
+    // changed or added for PS1_DEV_2
+    out[i].Mgal       = in[i].Map;
+
+    // changed or added for PS1_V1
+    // out[i].photFlags  = in[i].photFlags & 0x0000ffff; (only dophot pre PS1_DEV_1)
+    out[i].dophot     = in[i].photFlags >> 16;
   }
   return (out);
@@ -105,9 +126,4 @@
     out[i].D        	 = in[i].D;      
     out[i].Xp       	 = in[i].Xp;     
-    out[i].Nmeasure      = in[i].Nm;     
-    out[i].Nmissing      = in[i].Nn;     
-    out[i].code     	 = in[i].code;   
-    out[i].measureOffset = in[i].offset; 
-    out[i].missingOffset = in[i].missing;
     out[i].dR       	 = in[i].dR;
     out[i].dD       	 = in[i].dD;
@@ -120,4 +136,18 @@
     out[i].objID 	 = in[i].objID;
     out[i].catID 	 = in[i].catID;
+
+    // changed or added for PS1_DEV_2
+    out[i].Nmeasure      = in[i].Nm;     
+    out[i].Nmissing      = in[i].Nn;     
+    out[i].measureOffset = in[i].offset; 
+    out[i].missingOffset = in[i].missing;
+    out[i].Nextend       = 0;
+    out[i].extendOffset  = 0;
+
+    // changed or added for PS1_V1
+    out[i].flags    	 = in[i].code;   
+    out[i].ChiSq       	 = 0.0;
+    out[i].Npos       	 = 0.0;
+    out[i].extID 	 = 0;
   }
   return (out);
@@ -137,9 +167,4 @@
     out[i].D        = in[i].D;      
     out[i].Xp       = in[i].Xp;     
-    out[i].Nm       = in[i].Nmeasure;     
-    out[i].Nn       = in[i].Nmissing;     
-    out[i].code     = in[i].code;   
-    out[i].offset   = in[i].measureOffset; 
-    out[i].missing  = in[i].missingOffset;
     out[i].dR       = in[i].dR;
     out[i].dD       = in[i].dD;
@@ -152,4 +177,13 @@
     out[i].objID    = in[i].objID;
     out[i].catID    = in[i].catID;
+
+    // changed or added for PS1_DEV_2
+    out[i].Nm       = in[i].Nmeasure;     
+    out[i].Nn       = in[i].Nmissing;     
+    out[i].offset   = in[i].measureOffset; 
+    out[i].missing  = in[i].missingOffset;
+
+    // changed or added for PS1_V1
+    out[i].code          = in[i].flags;   
   }
   return (out);
@@ -170,4 +204,8 @@
     out[i].Ncode = in[i].Ncode;
     out[i].Nused = in[i].Nused;
+
+    // changed or added for PS1_V1
+    out[i].M_20  = 0;      
+    out[i].M_80  = 0;      
  }
   return (out);
@@ -226,7 +264,5 @@
     out[i].fwhm_y	    = in[i].fwhm_y;
     out[i].trate	    = in[i].trate;
-    out[i].code		    = in[i].code;
     out[i].ccdnum	    = in[i].ccdnum;
-    out[i].imageID	    = in[i].imageID_lo;
 
     out[i].order	    = in[i].order;
@@ -245,4 +281,15 @@
     out[i].Mxyyy	    = in[i].Mxyyy;
     out[i].Myyyy	    = in[i].Myyyy;
+
+    // changed or added for PS1_DEV_1
+    out[i].imageID	    = in[i].imageID_lo;
+
+    // changed or added for PS1_DEV_2
+    out[i].externID	    = 0;
+    out[i].sourceID	    = 0;
+
+    // changed or added for PS1_V1
+    out[i].flags	    = in[i].code;
+    out[i].parentID	    = 0;
   }
   return (out);
@@ -283,8 +330,5 @@
     out[i].fwhm_y	    = in[i].fwhm_y;
     out[i].trate	    = in[i].trate;
-    out[i].code		    = in[i].code;
     out[i].ccdnum	    = in[i].ccdnum;
-    out[i].imageID_hi	    = 0;
-    out[i].imageID_lo	    = in[i].imageID;
 
     out[i].order	    = in[i].order;
@@ -303,5 +347,15 @@
     out[i].Mxyyy	    = in[i].Mxyyy;
     out[i].Myyyy	    = in[i].Myyyy;
-  }
-  return (out);
-}
+
+    // changed or added for PS1_DEV_1
+    out[i].imageID_hi	    = 0;
+    out[i].imageID_lo	    = in[i].imageID;
+
+    // changed or added for PS1_V1
+    out[i].code		    = in[i].flags;
+  }
+  return (out);
+}
+
+// XXX no photcode conversions?  this may be from before we had a photcode FITS table...
+
Index: /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvo_image.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvo_image.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvo_image.c	(revision 21536)
@@ -196,4 +196,5 @@
   if (db[0].format == DVO_FORMAT_PS1_DEV_2)       gfits_modify (&db[0].header, "FORMAT", "%s", 1, "PS1_DEV_2");
   if (db[0].format == DVO_FORMAT_PS1_DEV_3)       gfits_modify (&db[0].header, "FORMAT", "%s", 1, "PS1_DEV_3");
+  if (db[0].format == DVO_FORMAT_PS1_V1)          gfits_modify (&db[0].header, "FORMAT", "%s", 1, "PS1_V1");
   
   return;
Index: /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvo_image_raw.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvo_image_raw.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvo_image_raw.c	(revision 21536)
@@ -54,4 +54,6 @@
   if (db[0].format == DVO_FORMAT_PS1_DEV_1)       ImageSize = sizeof(Image_PS1_DEV_1);
   if (db[0].format == DVO_FORMAT_PS1_DEV_2)       ImageSize = sizeof(Image_PS1_DEV_2);
+  if (db[0].format == DVO_FORMAT_PS1_DEV_3)       ImageSize = sizeof(Image_PS1_DEV_3);
+  if (db[0].format == DVO_FORMAT_PS1_V1)          ImageSize = sizeof(Image_PS1_V1);
 
   /* check that filesize makes sense */
@@ -78,4 +80,6 @@
   if (db[0].format == DVO_FORMAT_PS1_DEV_1)       gfits_table_mkheader_Image_PS1_DEV_1 (&db[0].theader);
   if (db[0].format == DVO_FORMAT_PS1_DEV_2)       gfits_table_mkheader_Image_PS1_DEV_2 (&db[0].theader);
+  if (db[0].format == DVO_FORMAT_PS1_DEV_3)       gfits_table_mkheader_Image_PS1_DEV_3 (&db[0].theader);
+  if (db[0].format == DVO_FORMAT_PS1_V1)          gfits_table_mkheader_Image_PS1_V1 (&db[0].theader);
     
   /* read data from file */
Index: /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvosorts.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvosorts.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/libdvo/src/dvosorts.c	(revision 21536)
@@ -46,16 +46,4 @@
 }
 
-void sort_stars_ra (Stars *stars, int N) {
-
-# define SWAPFUNC(A,B){ Stars tmp; tmp = stars[A]; stars[A] = stars[B]; stars[B] = tmp; }
-# define COMPARE(A,B)(stars[A].R < stars[B].R)
-
-  OHANA_SORT (N, COMPARE, SWAPFUNC);
-
-# undef SWAPFUNC
-# undef COMPARE
-
-}
-
 void sort_regions (SkyRegion *region, int N) {
 
@@ -70,2 +58,16 @@
 }
 
+# if (0)
+// deprecated along with Stars as an autocode type
+void sort_stars_ra (Stars *stars, int N) {
+
+# define SWAPFUNC(A,B){ Stars tmp; tmp = stars[A]; stars[A] = stars[B]; stars[B] = tmp; }
+# define COMPARE(A,B)(stars[A].R < stars[B].R)
+
+  OHANA_SORT (N, COMPARE, SWAPFUNC);
+
+# undef SWAPFUNC
+# undef COMPARE
+
+}
+# endif
Index: /branches/cnb_branch_20090215/Ohana/src/libohana/include/ohana.h
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/libohana/include/ohana.h	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/libohana/include/ohana.h	(revision 21536)
@@ -6,4 +6,5 @@
 # include <time.h>
 # include <stdlib.h>
+# include <stdint.h>
 # include <string.h>
 # include <sys/socket.h>
Index: /branches/cnb_branch_20090215/Ohana/src/opihi/cmd.data/Makefile
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/opihi/cmd.data/Makefile	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/opihi/cmd.data/Makefile	(revision 21536)
@@ -20,5 +20,5 @@
 $(SRC)/accum.$(ARCH).o		\
 $(SRC)/applyfit2d.$(ARCH).o	\
-$(SRC)/applyfit.$(ARCH).o	\
+$(SRC)/applyfit1d.$(ARCH).o	\
 $(SRC)/box.$(ARCH).o		\
 $(SRC)/book.$(ARCH).o		\
@@ -26,5 +26,5 @@
 $(SRC)/center.$(ARCH).o	\
 $(SRC)/clear.$(ARCH).o		\
-$(SRC)/clip.$(ARCH).o		\
+$(SRC)/imclip.$(ARCH).o		\
 $(SRC)/close.$(ARCH).o		\
 $(SRC)/concat.$(ARCH).o	\
@@ -44,6 +44,6 @@
 $(SRC)/fft1d.$(ARCH).o		\
 $(SRC)/fft2d.$(ARCH).o		\
+$(SRC)/fit1d.$(ARCH).o		\
 $(SRC)/fit2d.$(ARCH).o		\
-$(SRC)/fit.$(ARCH).o		\
 $(SRC)/gaussj.$(ARCH).o	\
 $(SRC)/gaussdeviate.$(ARCH).o	\
@@ -107,5 +107,5 @@
 $(SRC)/spline_apply.$(ARCH).o	\
 $(SRC)/spline_construct.$(ARCH).o \
-$(SRC)/stats.$(ARCH).o		   \
+$(SRC)/imstats.$(ARCH).o	   \
 $(SRC)/style.$(ARCH).o		   \
 $(SRC)/subraster.$(ARCH).o	   \
@@ -131,5 +131,5 @@
 $(SRC)/vroll.$(ARCH).o		   \
 $(SRC)/vsmooth.$(ARCH).o	\
-$(SRC)/vstat.$(ARCH).o		   \
+$(SRC)/vstats.$(ARCH).o		   \
 $(SRC)/wd.$(ARCH).o		   \
 $(SRC)/write_vectors.$(ARCH).o	   \
Index: anches/cnb_branch_20090215/Ohana/src/opihi/cmd.data/applyfit.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/opihi/cmd.data/applyfit.c	(revision 21535)
+++ 	(revision )
@@ -1,66 +1,0 @@
-# include "data.h"
-
-int applyfit (int argc, char **argv) {
-  
-  int i, j, order;
-  char *c, name[64];
-  double *C, X;
-  opihi_flt *y;
-  Vector *xvec, *yvec;
-
-  if (argc != 3) {
-    gprint (GP_ERR, "USAGE: applyfit x y\n");
-    return (FALSE);
-  }
-
-  c = get_variable ("Cn");
-  if (c == NULL) {
-    gprint (GP_ERR, "no fit available\n");
-    return (FALSE);
-  }
-  order = atof (c);
-  free (c);
-
-  if ((xvec = SelectVector (argv[1], OLDVECTOR, TRUE)) == NULL) return (FALSE);    
-  if ((yvec = SelectVector (argv[2], ANYVECTOR, TRUE)) == NULL) return (FALSE);    
-
-  ALLOCATE (C, double, order+1);
-  for (i = 0; i < order + 1; i++) {
-    sprintf (name, "C%d", i);
-    c = get_variable (name);
-    if (c == NULL) {
-      gprint (GP_ERR, "missing fit term %d\n", i);
-      return (FALSE);
-    }
-    C[i] = atof (c);
-    free (c);
-  }
-
-  ResetVector (yvec, OPIHI_FLT, xvec[0].Nelements);
-  bzero (yvec[0].elements.Flt, sizeof(opihi_flt)*yvec[0].Nelements);
-  y = yvec[0].elements.Flt;
-
-  if (xvec[0].type == OPIHI_FLT) {
-    opihi_flt *x = xvec[0].elements.Flt;
-    for (j = 0; j < xvec[0].Nelements; j++, x++, y++) {
-      X = 1;
-      for (i = 0; i < order + 1; i++) {
-	*y += C[i]*X;
-	X = X * (*x);
-      }
-    }
-  } else {
-    opihi_int *x = xvec[0].elements.Int;
-    for (j = 0; j < xvec[0].Nelements; j++, x++, y++) {
-      X = 1;
-      for (i = 0; i < order + 1; i++) {
-	*y += C[i]*X;
-	X = X * (*x);
-      }
-    }
-  }
-
-  free (C);
-  return (TRUE);
-
-}
Index: /branches/cnb_branch_20090215/Ohana/src/opihi/cmd.data/applyfit1d.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/opihi/cmd.data/applyfit1d.c	(revision 21536)
+++ /branches/cnb_branch_20090215/Ohana/src/opihi/cmd.data/applyfit1d.c	(revision 21536)
@@ -0,0 +1,66 @@
+# include "data.h"
+
+int applyfit1d (int argc, char **argv) {
+  
+  int i, j, order;
+  char *c, name[64];
+  double *C, X;
+  opihi_flt *y;
+  Vector *xvec, *yvec;
+
+  if (argc != 3) {
+    gprint (GP_ERR, "USAGE: applyfit x y\n");
+    return (FALSE);
+  }
+
+  c = get_variable ("Cn");
+  if (c == NULL) {
+    gprint (GP_ERR, "no fit available\n");
+    return (FALSE);
+  }
+  order = atof (c);
+  free (c);
+
+  if ((xvec = SelectVector (argv[1], OLDVECTOR, TRUE)) == NULL) return (FALSE);    
+  if ((yvec = SelectVector (argv[2], ANYVECTOR, TRUE)) == NULL) return (FALSE);    
+
+  ALLOCATE (C, double, order+1);
+  for (i = 0; i < order + 1; i++) {
+    sprintf (name, "C%d", i);
+    c = get_variable (name);
+    if (c == NULL) {
+      gprint (GP_ERR, "missing fit term %d\n", i);
+      return (FALSE);
+    }
+    C[i] = atof (c);
+    free (c);
+  }
+
+  ResetVector (yvec, OPIHI_FLT, xvec[0].Nelements);
+  bzero (yvec[0].elements.Flt, sizeof(opihi_flt)*yvec[0].Nelements);
+  y = yvec[0].elements.Flt;
+
+  if (xvec[0].type == OPIHI_FLT) {
+    opihi_flt *x = xvec[0].elements.Flt;
+    for (j = 0; j < xvec[0].Nelements; j++, x++, y++) {
+      X = 1;
+      for (i = 0; i < order + 1; i++) {
+	*y += C[i]*X;
+	X = X * (*x);
+      }
+    }
+  } else {
+    opihi_int *x = xvec[0].elements.Int;
+    for (j = 0; j < xvec[0].Nelements; j++, x++, y++) {
+      X = 1;
+      for (i = 0; i < order + 1; i++) {
+	*y += C[i]*X;
+	X = X * (*x);
+      }
+    }
+  }
+
+  free (C);
+  return (TRUE);
+
+}
Index: anches/cnb_branch_20090215/Ohana/src/opihi/cmd.data/clip.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/opihi/cmd.data/clip.c	(revision 21535)
+++ 	(revision )
@@ -1,73 +1,0 @@
-# include "data.h"
-
-int clip (int argc, char **argv) {
-
-  int i, Npix, DO_NAN, DO_INF, N;
-  double min, Vmin, max, Vmax, nan_val, inf_val;
-  float *in;
-  Buffer *buf;
-
-  inf_val = nan_val = min = Vmin = max = Vmax = 0;
-
-  DO_NAN = FALSE;
-  if ((N = get_argument (argc, argv, "-nan"))) {
-    remove_argument (N, &argc, argv);
-    nan_val  = atof(argv[N]);
-    remove_argument (N, &argc, argv);
-    DO_NAN = TRUE;
-  }
-
-  DO_INF = FALSE;
-  if ((N = get_argument (argc, argv, "-inf"))) {
-    remove_argument (N, &argc, argv);
-    inf_val  = atof(argv[N]);
-    remove_argument (N, &argc, argv);
-    DO_INF = TRUE;
-  }
-
-  if ((argc != 6) && (!(DO_INF || DO_NAN))) {
-    gprint (GP_ERR, "USAGE: clip (buffer) [min Vmin max Vmax] [-inf val] [-nan val]\n");
-    return (FALSE);
-  }
-
-  if ((buf = SelectBuffer (argv[1], OLDBUFFER, TRUE)) == NULL) return (FALSE);
-
-  if (argc == 6) {
-    min = atof (argv[2]);
-    Vmin = atof (argv[3]);
-    max = atof (argv[4]);
-    Vmax = atof (argv[5]);
-  }
-
-  Npix = buf[0].matrix.Naxis[0]*buf[0].matrix.Naxis[1];
-  in = (float *) buf[0].matrix.buffer;
-
-  if (argc == 6) {
-    for (i = 0; i < Npix; i++, in++) {
-      if (*in < min) 
-	*in = Vmin;
-      if (*in > max)
-	*in = Vmax;
-    }
-  }
-  in = (float *) buf[0].matrix.buffer;
-  if (DO_NAN) {
-    for (i = 0; i < Npix; i++, in++) {
-      if (isnan (*in)) {
-	*in = nan_val;
-      }
-    }
-  }
-  in = (float *) buf[0].matrix.buffer;
-  if (DO_INF) {
-    for (i = 0; i < Npix; i++, in++) {
-      if (!finite (*in)) {
-	*in = inf_val;
-      }
-    }
-  }
-  return (TRUE);
-
-}
-
-
Index: anches/cnb_branch_20090215/Ohana/src/opihi/cmd.data/fit.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/opihi/cmd.data/fit.c	(revision 21535)
+++ 	(revision )
@@ -1,234 +1,0 @@
-# include "data.h"
-
-int fit (int argc, char **argv) {
-  
-  double **c, **b, *s, X, Y, dY, dY2;
-  double ClipNSigma, mean, sigma, maxsigma;
-  int i, j, nterm, mterm, order, Npt, Nmask;
-  int N, Weight, Quiet, ClipNiter;
-  Vector *xvec, *yvec, *dyvec;
-  opihi_flt *x, *y, *dy, *yf, *yfit;
-  char name[64], *mask;
-
-  Quiet = FALSE;
-  if ((N = get_argument (argc, argv, "-q"))) {
-    Quiet = TRUE;
-    remove_argument (N, &argc, argv);
-  }
-  if ((N = get_argument (argc, argv, "-quiet"))) {
-    Quiet = TRUE;
-    remove_argument (N, &argc, argv);
-  }
-
-  ClipNSigma = 0;
-  ClipNiter  = 1;
-  if ((N = get_argument (argc, argv, "-clip"))) {
-    remove_argument (N, &argc, argv);
-    ClipNSigma = atof(argv[N]);
-    remove_argument (N, &argc, argv);
-    ClipNiter  = atof(argv[N]);
-    remove_argument (N, &argc, argv);
-  }
-
-  dy = NULL;
-  dyvec = NULL;
-  Weight = FALSE;
-  if ((N = get_argument (argc, argv, "-dy"))) {
-    remove_argument (N, &argc, argv);
-    if ((dyvec = SelectVector (argv[N], OLDVECTOR, TRUE)) == NULL) return (FALSE);    
-    remove_argument (N, &argc, argv);
-    Weight = TRUE;
-  }
-
-  if (argc != 4) {
-    gprint (GP_ERR, "USAGE: fit x y order [-dy wt] [-quiet/-q] [-clip Nsigma Niter]\n");
-    return (FALSE);
-  }
-
-  if ((xvec = SelectVector (argv[1], OLDVECTOR, TRUE)) == NULL) return (FALSE);    
-  if ((yvec = SelectVector (argv[2], OLDVECTOR, TRUE)) == NULL) return (FALSE);    
-
-  if (xvec[0].Nelements != yvec[0].Nelements) {
-    gprint (GP_ERR, "vectors must have same length\n");
-    return (FALSE);
-  }
-  REQUIRE_VECTOR_FLT (xvec, FALSE); 
-  REQUIRE_VECTOR_FLT (yvec, FALSE); 
-
-  if (Weight) {
-    REQUIRE_VECTOR_FLT (dyvec, FALSE); 
-    if (xvec[0].Nelements != dyvec[0].Nelements) {
-      gprint (GP_ERR, "vectors must have same length\n");
-      return (FALSE);
-    }
-  }
- 
-
-  /* nterm is number of polynomial terms, starting at x^0 */
-  order = atof (argv[3]);
-  nterm = order + 1;
-  mterm = 2*nterm;
-
-  ALLOCATE (yfit, opihi_flt, xvec[0].Nelements);
-  ALLOCATE (mask, char, xvec[0].Nelements);
-  memset (mask, 0, xvec[0].Nelements);
-
-  ALLOCATE (s, double, mterm);
-  ALLOCATE (b, double *, nterm);
-  ALLOCATE (c, double *, nterm);
-  for (i = 0; i < nterm; i++) {
-    ALLOCATE (c[i], double, nterm);
-    ALLOCATE (b[i], double, 1);
-  }
-
-  Nmask = 0;
-  sigma = 0.0;
-
-  for (N = 0; N < ClipNiter; N++) {
-
-    /* init registers for current pass */
-    memset (s, 0, mterm*sizeof(double));
-    for (i = 0; i < nterm; i++) {
-      memset (c[i], 0, nterm*sizeof(double));
-      memset (b[i], 0, sizeof(double));
-    }
-
-    /* perform linear fit */
-    x = xvec[0].elements.Flt;
-    y = yvec[0].elements.Flt;
-    if (Weight) dy = dyvec[0].elements.Flt;
-
-    for (i = 0; i < xvec[0].Nelements; i++, x++, y++) {
-      if (mask[i]) continue;
-      if (!(finite(*x) && finite(*y))) continue;
-      dY = 1.0;
-      if (Weight) { 
-	dY = 1.0 / SQ(*dy);
-	dy ++;
-      }
-      X = 1*dY;
-      Y = *y*dY;
-      for (j = 0; j < nterm; j++) {
-	s[j] += X;
-	b[j][0] += Y;
-	X = X * (*x);
-	Y = Y * (*x);
-      }
-      for (j = nterm; j < mterm; j++) {
-	s[j] += X;
-	X = X * (*x);
-      }
-    }
-    for (i = 0; i < nterm; i++) {
-      for (j = 0; j < nterm; j++) {
-	c[i][j] = s[i + j];
-      }
-    }
-    if (!dgaussjordan (c, b, nterm, 1)) goto escape;
-
-    /* generate fitted values */
-    x = xvec[0].elements.Flt;
-    yf = yfit;
-    for (i = 0; i < xvec[0].Nelements; i++, x++, yf++) {
-      if (!finite(*x)) continue;
-      *yf = 0;
-      X = 1;
-      for (j = 0; j < order + 1; j++) {
-	*yf += b[j][0]*X;
-	X = X * (*x);
-      }
-    }
-
-    /* measure fit residual scatter */
-    x  = xvec[0].elements.Flt;
-    y  = yvec[0].elements.Flt;
-    yf = yfit;
-    dY = dY2 = 0;
-    for (i = Npt = 0; i < xvec[0].Nelements; i++, x++, y++, yf++) {
-      if (mask[i]) continue;
-      if (!finite(*x)) continue;
-      dY  += (*y - *yf);
-      dY2 += SQ(*y - *yf);
-      Npt ++;
-    }
-    mean  = dY / Npt;
-    sigma = sqrt (fabs(dY2/Npt - SQ(mean)));
-    maxsigma = ClipNSigma * sigma;
-
-    /* mask outlier points */
-    x  = xvec[0].elements.Flt;
-    y  = yvec[0].elements.Flt;
-    yf = yfit;
-    Nmask = 0;
-    for (i = 0; ClipNSigma && (i < xvec[0].Nelements); i++, x++, y++, yf++) {
-      dY = (*y - *yf);
-      if (fabs(dY) > maxsigma) {
-	mask[i] = TRUE;
-	Nmask ++;
-      } else {
-	mask[i] = FALSE;
-      }	
-    }
-  }
-      
-  /* print & save basic fit parameters */
-  if (!Quiet) gprint (GP_ERR, "y = ");
-  for (i = 0; i < nterm; i++) {
-    sprintf (name, "C%d", i);
-    set_variable (name, b[i][0]);
-    if (!Quiet) gprint (GP_ERR, "%f x^%d ", b[i][0], i);
-  }
-  sprintf (name, "Cn");
-  set_variable (name, (double) order);
-  
-  /* print & save basic fit parameters */
-  if (!Quiet) gprint (GP_ERR, "\n");
-  if (!Quiet) gprint (GP_ERR, "    ");
-  for (i = 0; i < nterm; i++) {
-    sprintf (name, "dC%d", i);
-    set_variable (name, sqrt(c[i][i]));
-    if (!Quiet) gprint (GP_ERR, "%f     ", sqrt(c[i][i]));
-  }
-  if (!Quiet) gprint (GP_ERR, "\n");
-
-  set_variable ("dC", sigma);
-  set_variable ("Cnv", (xvec[0].Nelements - Nmask));
-
-  /* save mask and yfit for testing? */
-  if (1) { 
-    Vector *fvec, *mvec;
-    if ((fvec = SelectVector ("yfit", ANYVECTOR, TRUE)) == NULL) return (FALSE);    
-    if ((mvec = SelectVector ("mask", ANYVECTOR, TRUE)) == NULL) return (FALSE);    
-    free (fvec[0].elements.Flt);
-    fvec[0].elements.Flt = yfit;
-    fvec[0].Nelements = xvec[0].Nelements;
-    mvec[0].Nelements = xvec[0].Nelements;
-
-    REALLOCATE (mvec[0].elements.Flt, opihi_flt, xvec[0].Nelements);
-    for (i = 0; i < xvec[0].Nelements; i++) {
-      mvec[0].elements.Flt[i] = mask[i];
-    }
-  } else {
-    free (yfit);
-  }
-  free (mask);
-
-  for (i = 0; i < nterm; i++) {
-    free (b[i]);
-    free (c[i]);
-  }
-  free (b);
-  free (c);
-  free (s);
-  return (TRUE);
-
-escape:
-  for (i = 0; i < nterm; i++) {
-    free (b[i]);
-    free (c[i]);
-  }
-  free (b);
-  free (c);
-  free (s);
-  return (FALSE);
-}
Index: /branches/cnb_branch_20090215/Ohana/src/opihi/cmd.data/fit1d.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/opihi/cmd.data/fit1d.c	(revision 21536)
+++ /branches/cnb_branch_20090215/Ohana/src/opihi/cmd.data/fit1d.c	(revision 21536)
@@ -0,0 +1,234 @@
+# include "data.h"
+
+int fit1d (int argc, char **argv) {
+  
+  double **c, **b, *s, X, Y, dY, dY2;
+  double ClipNSigma, mean, sigma, maxsigma;
+  int i, j, nterm, mterm, order, Npt, Nmask;
+  int N, Weight, Quiet, ClipNiter;
+  Vector *xvec, *yvec, *dyvec;
+  opihi_flt *x, *y, *dy, *yf, *yfit;
+  char name[64], *mask;
+
+  Quiet = FALSE;
+  if ((N = get_argument (argc, argv, "-q"))) {
+    Quiet = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+  if ((N = get_argument (argc, argv, "-quiet"))) {
+    Quiet = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+
+  ClipNSigma = 0;
+  ClipNiter  = 1;
+  if ((N = get_argument (argc, argv, "-clip"))) {
+    remove_argument (N, &argc, argv);
+    ClipNSigma = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+    ClipNiter  = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  dy = NULL;
+  dyvec = NULL;
+  Weight = FALSE;
+  if ((N = get_argument (argc, argv, "-dy"))) {
+    remove_argument (N, &argc, argv);
+    if ((dyvec = SelectVector (argv[N], OLDVECTOR, TRUE)) == NULL) return (FALSE);    
+    remove_argument (N, &argc, argv);
+    Weight = TRUE;
+  }
+
+  if (argc != 4) {
+    gprint (GP_ERR, "USAGE: fit x y order [-dy wt] [-quiet/-q] [-clip Nsigma Niter]\n");
+    return (FALSE);
+  }
+
+  if ((xvec = SelectVector (argv[1], OLDVECTOR, TRUE)) == NULL) return (FALSE);    
+  if ((yvec = SelectVector (argv[2], OLDVECTOR, TRUE)) == NULL) return (FALSE);    
+
+  if (xvec[0].Nelements != yvec[0].Nelements) {
+    gprint (GP_ERR, "vectors must have same length\n");
+    return (FALSE);
+  }
+  REQUIRE_VECTOR_FLT (xvec, FALSE); 
+  REQUIRE_VECTOR_FLT (yvec, FALSE); 
+
+  if (Weight) {
+    REQUIRE_VECTOR_FLT (dyvec, FALSE); 
+    if (xvec[0].Nelements != dyvec[0].Nelements) {
+      gprint (GP_ERR, "vectors must have same length\n");
+      return (FALSE);
+    }
+  }
+ 
+
+  /* nterm is number of polynomial terms, starting at x^0 */
+  order = atof (argv[3]);
+  nterm = order + 1;
+  mterm = 2*nterm;
+
+  ALLOCATE (yfit, opihi_flt, xvec[0].Nelements);
+  ALLOCATE (mask, char, xvec[0].Nelements);
+  memset (mask, 0, xvec[0].Nelements);
+
+  ALLOCATE (s, double, mterm);
+  ALLOCATE (b, double *, nterm);
+  ALLOCATE (c, double *, nterm);
+  for (i = 0; i < nterm; i++) {
+    ALLOCATE (c[i], double, nterm);
+    ALLOCATE (b[i], double, 1);
+  }
+
+  Nmask = 0;
+  sigma = 0.0;
+
+  for (N = 0; N < ClipNiter; N++) {
+
+    /* init registers for current pass */
+    memset (s, 0, mterm*sizeof(double));
+    for (i = 0; i < nterm; i++) {
+      memset (c[i], 0, nterm*sizeof(double));
+      memset (b[i], 0, sizeof(double));
+    }
+
+    /* perform linear fit */
+    x = xvec[0].elements.Flt;
+    y = yvec[0].elements.Flt;
+    if (Weight) dy = dyvec[0].elements.Flt;
+
+    for (i = 0; i < xvec[0].Nelements; i++, x++, y++) {
+      if (mask[i]) continue;
+      if (!(finite(*x) && finite(*y))) continue;
+      dY = 1.0;
+      if (Weight) { 
+	dY = 1.0 / SQ(*dy);
+	dy ++;
+      }
+      X = 1*dY;
+      Y = *y*dY;
+      for (j = 0; j < nterm; j++) {
+	s[j] += X;
+	b[j][0] += Y;
+	X = X * (*x);
+	Y = Y * (*x);
+      }
+      for (j = nterm; j < mterm; j++) {
+	s[j] += X;
+	X = X * (*x);
+      }
+    }
+    for (i = 0; i < nterm; i++) {
+      for (j = 0; j < nterm; j++) {
+	c[i][j] = s[i + j];
+      }
+    }
+    if (!dgaussjordan (c, b, nterm, 1)) goto escape;
+
+    /* generate fitted values */
+    x = xvec[0].elements.Flt;
+    yf = yfit;
+    for (i = 0; i < xvec[0].Nelements; i++, x++, yf++) {
+      if (!finite(*x)) continue;
+      *yf = 0;
+      X = 1;
+      for (j = 0; j < order + 1; j++) {
+	*yf += b[j][0]*X;
+	X = X * (*x);
+      }
+    }
+
+    /* measure fit residual scatter */
+    x  = xvec[0].elements.Flt;
+    y  = yvec[0].elements.Flt;
+    yf = yfit;
+    dY = dY2 = 0;
+    for (i = Npt = 0; i < xvec[0].Nelements; i++, x++, y++, yf++) {
+      if (mask[i]) continue;
+      if (!finite(*x)) continue;
+      dY  += (*y - *yf);
+      dY2 += SQ(*y - *yf);
+      Npt ++;
+    }
+    mean  = dY / Npt;
+    sigma = sqrt (fabs(dY2/Npt - SQ(mean)));
+    maxsigma = ClipNSigma * sigma;
+
+    /* mask outlier points */
+    x  = xvec[0].elements.Flt;
+    y  = yvec[0].elements.Flt;
+    yf = yfit;
+    Nmask = 0;
+    for (i = 0; ClipNSigma && (i < xvec[0].Nelements); i++, x++, y++, yf++) {
+      dY = (*y - *yf);
+      if (fabs(dY) > maxsigma) {
+	mask[i] = TRUE;
+	Nmask ++;
+      } else {
+	mask[i] = FALSE;
+      }	
+    }
+  }
+      
+  /* print & save basic fit parameters */
+  if (!Quiet) gprint (GP_ERR, "y = ");
+  for (i = 0; i < nterm; i++) {
+    sprintf (name, "C%d", i);
+    set_variable (name, b[i][0]);
+    if (!Quiet) gprint (GP_ERR, "%f x^%d ", b[i][0], i);
+  }
+  sprintf (name, "Cn");
+  set_variable (name, (double) order);
+  
+  /* print & save basic fit parameters */
+  if (!Quiet) gprint (GP_ERR, "\n");
+  if (!Quiet) gprint (GP_ERR, "    ");
+  for (i = 0; i < nterm; i++) {
+    sprintf (name, "dC%d", i);
+    set_variable (name, sqrt(c[i][i]));
+    if (!Quiet) gprint (GP_ERR, "%f     ", sqrt(c[i][i]));
+  }
+  if (!Quiet) gprint (GP_ERR, "\n");
+
+  set_variable ("dC", sigma);
+  set_variable ("Cnv", (xvec[0].Nelements - Nmask));
+
+  /* save mask and yfit for testing? */
+  if (1) { 
+    Vector *fvec, *mvec;
+    if ((fvec = SelectVector ("yfit", ANYVECTOR, TRUE)) == NULL) return (FALSE);    
+    if ((mvec = SelectVector ("mask", ANYVECTOR, TRUE)) == NULL) return (FALSE);    
+    free (fvec[0].elements.Flt);
+    fvec[0].elements.Flt = yfit;
+    fvec[0].Nelements = xvec[0].Nelements;
+    mvec[0].Nelements = xvec[0].Nelements;
+
+    REALLOCATE (mvec[0].elements.Flt, opihi_flt, xvec[0].Nelements);
+    for (i = 0; i < xvec[0].Nelements; i++) {
+      mvec[0].elements.Flt[i] = mask[i];
+    }
+  } else {
+    free (yfit);
+  }
+  free (mask);
+
+  for (i = 0; i < nterm; i++) {
+    free (b[i]);
+    free (c[i]);
+  }
+  free (b);
+  free (c);
+  free (s);
+  return (TRUE);
+
+escape:
+  for (i = 0; i < nterm; i++) {
+    free (b[i]);
+    free (c[i]);
+  }
+  free (b);
+  free (c);
+  free (s);
+  return (FALSE);
+}
Index: /branches/cnb_branch_20090215/Ohana/src/opihi/cmd.data/imclip.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/opihi/cmd.data/imclip.c	(revision 21536)
+++ /branches/cnb_branch_20090215/Ohana/src/opihi/cmd.data/imclip.c	(revision 21536)
@@ -0,0 +1,73 @@
+# include "data.h"
+
+int imclip (int argc, char **argv) {
+
+  int i, Npix, DO_NAN, DO_INF, N;
+  double min, Vmin, max, Vmax, nan_val, inf_val;
+  float *in;
+  Buffer *buf;
+
+  inf_val = nan_val = min = Vmin = max = Vmax = 0;
+
+  DO_NAN = FALSE;
+  if ((N = get_argument (argc, argv, "-nan"))) {
+    remove_argument (N, &argc, argv);
+    nan_val  = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+    DO_NAN = TRUE;
+  }
+
+  DO_INF = FALSE;
+  if ((N = get_argument (argc, argv, "-inf"))) {
+    remove_argument (N, &argc, argv);
+    inf_val  = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+    DO_INF = TRUE;
+  }
+
+  if ((argc != 6) && (!(DO_INF || DO_NAN))) {
+    gprint (GP_ERR, "USAGE: clip (buffer) [min Vmin max Vmax] [-inf val] [-nan val]\n");
+    return (FALSE);
+  }
+
+  if ((buf = SelectBuffer (argv[1], OLDBUFFER, TRUE)) == NULL) return (FALSE);
+
+  if (argc == 6) {
+    min = atof (argv[2]);
+    Vmin = atof (argv[3]);
+    max = atof (argv[4]);
+    Vmax = atof (argv[5]);
+  }
+
+  Npix = buf[0].matrix.Naxis[0]*buf[0].matrix.Naxis[1];
+  in = (float *) buf[0].matrix.buffer;
+
+  if (argc == 6) {
+    for (i = 0; i < Npix; i++, in++) {
+      if (*in < min) 
+	*in = Vmin;
+      if (*in > max)
+	*in = Vmax;
+    }
+  }
+  in = (float *) buf[0].matrix.buffer;
+  if (DO_NAN) {
+    for (i = 0; i < Npix; i++, in++) {
+      if (isnan (*in)) {
+	*in = nan_val;
+      }
+    }
+  }
+  in = (float *) buf[0].matrix.buffer;
+  if (DO_INF) {
+    for (i = 0; i < Npix; i++, in++) {
+      if (!finite (*in)) {
+	*in = inf_val;
+      }
+    }
+  }
+  return (TRUE);
+
+}
+
+
Index: /branches/cnb_branch_20090215/Ohana/src/opihi/cmd.data/imstats.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/opihi/cmd.data/imstats.c	(revision 21536)
+++ /branches/cnb_branch_20090215/Ohana/src/opihi/cmd.data/imstats.c	(revision 21536)
@@ -0,0 +1,125 @@
+# include "data.h"
+
+int imstats (int argc, char **argv) {
+  
+  int i, j, Nmode, Imode;
+  double Npix, N1, N2, max, min, range, median, mode, IgnoreValue;
+  float *V;
+  int sx, sy, nx, ny, *hist, Nhist, bin;
+  int Ignore, Quiet, N;
+  Buffer *buf;
+
+  IgnoreValue = 0;
+  Ignore = FALSE;
+  if ((N = get_argument (argc, argv, "-ignore"))) {
+    Ignore = TRUE;
+    remove_argument (N, &argc, argv);
+    IgnoreValue = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  Quiet = FALSE;
+  if ((N = get_argument (argc, argv, "-q"))) {
+    Quiet = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+  if ((N = get_argument (argc, argv, "-quiet"))) {
+    Quiet = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+
+  if ((argc != 2) && (argc != 6)) {
+    gprint (GP_ERR, "USAGE: stats <buffer> sx sy nx ny\n");
+    gprint (GP_ERR, "OR:    stats <buffer>\n");
+    return (FALSE);
+  }
+
+  if ((buf = SelectBuffer (argv[1], OLDBUFFER, TRUE)) == NULL) return (FALSE);
+
+  if (argc == 6) {
+    sx = strcmp (argv[2], "-") ? atof (argv[2]) : 0;
+    sy = strcmp (argv[3], "-") ? atof (argv[3]) : 0;
+    nx = strcmp (argv[4], "-") ? atof (argv[4]) : buf[0].matrix.Naxis[0];
+    ny = strcmp (argv[5], "-") ? atof (argv[5]) : buf[0].matrix.Naxis[1];
+  } else {
+    sx = 0;
+    sy = 0;
+    nx = buf[0].matrix.Naxis[0];
+    ny = buf[0].matrix.Naxis[1];
+  }
+
+  Npix = N1 = N2 = 0;
+  if ((sx < 0) || (sy < 0) || 
+      (sx+nx > buf[0].matrix.Naxis[0]) || 
+      (sy+ny > buf[0].matrix.Naxis[1])) {
+    gprint (GP_ERR, "region out of range\n");
+    return (FALSE);
+  }
+
+  max = -1e32;
+  min = +1e32;
+  for (j = sy; j < sy + ny; j++) {
+    V = (float *)(buf[0].matrix.buffer) + j*buf[0].matrix.Naxis[0] + sx; 
+    for (i = 0; i < nx; i++, V++) {
+      if (Ignore && (fabs (*V - IgnoreValue) < 1e-8)) continue;
+      if (isnan(*V)) continue;
+      if (isinf(*V)) continue;
+      N1 += *V;
+      N2 += (*V)*(*V);
+      Npix += 1.0;
+      max = MAX (max, *V);
+      min = MIN (min, *V);
+    }
+  }
+  N1 = N1 / Npix;
+
+/* calculate mode, median */
+  median = mode = 0.5*(max + min);
+  if ((max - min) != 0) {
+    range = 0xffff / (max - min);
+    ALLOCATE (hist, int, 0x10000);
+    bzero (hist, 0x10000*sizeof(int));
+    for (j = sy; j < sy + ny; j++) {
+      V = (float *)(buf[0].matrix.buffer) + j*buf[0].matrix.Naxis[0] + sx; 
+      for (i = 0; i < nx; i++, V++) {
+	if (Ignore && (fabs (*V - IgnoreValue) < 1e-8)) continue;
+	if (isnan(*V)) continue;
+	if (isinf(*V)) continue;
+	bin = MIN (MAX (0, (*V - min) * range), 0xffff);
+	hist[bin] ++;
+      }
+    }
+    Nhist = 0;
+    for (i = 0; (i < 0xffff) && (Nhist < 0.5*Npix); i++) 
+      Nhist += hist[i];
+    median = i / range + min;
+    Nmode = hist[0];
+    Imode = 0;
+    for (i = 1; i < 0x10000; i++) {
+      if (hist[i] > Nmode) {
+	Nmode = hist[i];
+	Imode = i;
+      }
+    }
+    mode = Imode / range + min;
+    free (hist);
+  }  
+  
+  if (!Quiet) {
+    gprint (GP_LOG, "  mean    stdev    min     max   median   Npix   Total\n");
+    gprint (GP_LOG, "%7.4g %7.4g %7.4g %7.4g %7.4g %7.0f %7.4g\n", N1, sqrt (N2/Npix - N1*N1), 
+	    min, max, median, Npix, Npix*N1);
+  }
+
+  set_variable ("MIN",    min);
+  set_variable ("MAX",    max);
+  set_variable ("MEDIAN", median);
+  set_variable ("MEAN",   N1);
+  set_variable ("MODE",   mode);
+  set_variable ("TOTAL",  N1*Npix);
+  set_variable ("NPIX",   Npix);
+  set_variable ("SIGMA",  sqrt (N2/Npix - N1*N1));
+
+  return (TRUE);
+}
+
Index: /branches/cnb_branch_20090215/Ohana/src/opihi/cmd.data/init.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/opihi/cmd.data/init.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/opihi/cmd.data/init.c	(revision 21536)
@@ -3,4 +3,5 @@
 int accum            PROTO((int, char **));
 int applyfit         PROTO((int, char **));
+int applyfit1d       PROTO((int, char **));
 int applyfit2d       PROTO((int, char **));
 int box              PROTO((int, char **));
@@ -11,4 +12,5 @@
 int clear            PROTO((int, char **));
 int clip             PROTO((int, char **));
+int imclip           PROTO((int, char **));
 int close_device     PROTO((int, char **));
 int concat           PROTO((int, char **));
@@ -29,6 +31,7 @@
 int fft1d            PROTO((int, char **));
 int fft2d            PROTO((int, char **));
+int fit              PROTO((int, char **));
+int fit1d            PROTO((int, char **));
 int fit2d            PROTO((int, char **));
-int fit              PROTO((int, char **));
 int gaussjordan      PROTO((int, char **));
 int gaussdeviate     PROTO((int, char **));
@@ -92,4 +95,5 @@
 int spline_construct_cmd PROTO((int, char **));
 int stats            PROTO((int, char **));
+int imstats          PROTO((int, char **));
 int style            PROTO((int, char **));
 int subraster        PROTO((int, char **));
@@ -113,5 +117,5 @@
 int vload            PROTO((int, char **));
 int vzload           PROTO((int, char **));
-int vstat            PROTO((int, char **));
+int vstats           PROTO((int, char **));
 int vroll            PROTO((int, char **));
 int vpop             PROTO((int, char **));
@@ -124,17 +128,20 @@
 static Command cmds[] = {  
   {1, "accum",        accum,            "accumulate vector values in another vector"},
-  {1, "applyfit",     applyfit,         "apply fit to new vector"},
+  {1, "applyfit",     applyfit1d,       "apply 1-d fit to new vector"},
+  {1, "applyfit1d",   applyfit1d,       "apply 1-d fit to new vector"},
   {1, "applyfit2d",   applyfit2d,       "apply 2-d fit to new vector"},
+  {1, "book",         book_command,     "commands to manipulate book/page/word data"},
   {1, "box",          box,              "draw a box on the plot"},
-  {1, "book",         book_command,     "commands to manipulate book/page/word data"},
+  {1, "buffers",      list_buffers,     "list the currently allocated buffers (images)"},
+  {1, "images",       list_buffers,     "list the currently allocated images"},
   {1, "center",       center,           "center image on coords"},
-  {1, "parity",       parity,           "set image parity"},
   {1, "circstats",    circstats,        "circular statistics"},
   {1, "clear",        clear,            "erase plot"},
-  {1, "clip",         clip,             "clip values in a buffer to be within a range"},
+  {1, "clip",         imclip,           "clip values in an image to be within a range"},
   {1, "close",        close_device,     "close the current display device"},
-  {1, "concat",       concat,           "reduce vector dimension"},
+  {1, "concat",       concat,           "append values to the end of a vector"},
   {1, "contour",      contour,          "create contour from image"},
   {1, "create",       create,           "create a new vector"},
+  {1, "vcreate",      create,           "create a new vector"},
   {1, "cumulative",   cumulative,       "build a cumulative histogram from a specific histogram"},
   {1, "cursor",       cursor,           "get coords from cursor"},
@@ -143,81 +150,87 @@
   {1, "dbconnect",    dbconnect,        "setup mysql db connection"},
   {1, "dbselect",     dbselect,         "extract vectors from mysql database table"},
-  {1, "delete",       delete,           "delete vectors or matrices"},
+  {1, "delete",       delete,           "delete vectors or images"},
   {1, "device",       device,           "set / get current graphics device"},
-  {1, "dimendown",    dimendown,        "convert matrix to vector"},
-  {1, "dimenup",      dimenup,          "convert vector to matrix"},
-  {1, "erase",        erase,            "erase objects on an overlay"},
-  {1, "extract",      extract,          "extract a portion of a buffer into another buffer"},
-  {1, "fft1d",        fft1d,            "fft on the pixel-stream in an image"},
+  {1, "dimendown",    dimendown,        "convert image to vector"},
+  {1, "dimenup",      dimenup,          "convert vector to image"},
+  {1, "dot",          dot,              "plot a single point"},
+  {1, "erase",        erase,            "erase objects on an image overlay"},
+  {1, "extract",      extract,          "extract a portion of a image into another image"},
+  {1, "fft1d",        fft1d,            "fft on a vector"},
   {1, "fft2d",        fft2d,            "fft on an image"},
-  {1, "fit",          fit,              "fit polynomial to vector pair"},
+  {1, "fit",          fit1d,            "fit polynomial to vector pair"},
+  {1, "fit1d",        fit1d,            "fit polynomial to vector pair"},
   {1, "fit2d",        fit2d,            "fit 2-d polynomial to vector triplet"},
-  {1, "gaussj",       gaussjordan,      "solve Ax = B (N-D)"},
   {1, "gaussdev",     gaussdeviate,     "generate a gaussian deviate vector"},
   {1, "gaussint",     gaussintegral,    "return the integrated gaussian vector"},
-  {1, "grid",         grid,             "plot cartesian grid"},
-  {1, "gridify",      gridify,          "convert vector triplet to buffer"},
+  {1, "gaussj",       gaussjordan,      "solve Ax = B (N-Dimensional)"},
+  {1, "grid",         grid,             "plot cartesian grid on graph"},
+  {1, "gridify",      gridify,          "convert vector triplet to image (same as vgrid?)"},
   {1, "grow",         grow,             "grow a mask"},
-  {1, "ungridify",    ungridify,        "convert buffer region to vector triplet"},
-  {1, "header",       header,           "print buffer header"},
+  {1, "header",       header,           "print image header"},
   {1, "histogram",    histogram,        "generate histogram from vector"},
+  {1, "imbin",        rebin,            "rebin image data by factor of N"},
+  {1, "imclip",       imclip,           "clip values in an image to be within a range"},
   {1, "imcut",        imcut,            "linear image cut between arbitrary coords"},
-  {1, "imhist",       imhist,           "histogram of an image region"},
+  {1, "imhistogram",  imhist,           "histogram of an image region"},
   {1, "imsmooth",     imsmooth,         "circular gaussian smoothing"},
+  {1, "imstats",      imstats,          "statistics on a portion of an image"},
   {1, "integrate",    integrate,        "integrate a vector"},
   {1, "interpolate",  interpolate,      "interpolate between vector pairs"},
-  {1, "jpeg",         jpeg,             "write text line on graph"},
-  {1, "png",          jpeg,             "write text line on graph"},
-  {1, "ppm",          jpeg,             "write text line on graph"},
+  {1, "jpeg",         jpeg,             "convert display image to JPEG"},
   {1, "kern",         kern,             "convolve with 3x3 kernel"},
-  {1, "keyword",      keyword,          "extract a FITS keyword from buffer header"},
+  {1, "keyword",      keyword,          "extract a FITS keyword from image header"},
   {1, "labels",       labels,           "define labels for plot"},
   {1, "limits",       limits,           "define plot limits"},
-  {1, "line",         line,             "plot line"},
-  {1, "buffers",      list_buffers,     "list the currently allocated buffers"},
-  {1, "vectors",      list_vectors,     "list vectors"},
-  {1, "load",         load,             "load an SAOimage style overlay"},
+  {1, "line",         line,             "plot a line"},
+  {1, "load",         load,             "load an SAOimage/DS9 style overlay"},
   {1, "lookup",       lookup,           "convert vector via lookup table (vector pair)"},
-  {1, "mkrgb",        mkrgb,            "convert 3 images to rgb jpeg"},
-  {1, "mcreate",      mcreate,          "create a matrix"},
+  {1, "mcreate",      mcreate,          "create an image"},
+  {1, "imcreate",     mcreate,          "create an image"},
   {1, "medacc",       medacc,           "accumulate vector values in another vector"},
-  {1, "mget",         mget,             "extract a vector from a matrix"},
+  {1, "mget",         mget,             "extract a vector from an image"},
+  {1, "imget",        mget,             "extract a vector from an image"},
   {1, "minterp",      minterp,          "interpolate image pixels"},
-  {1, "mset",         mset,             "insert a vector in a matrix"},
+  {1, "iminterp",     minterp,          "interpolate image pixels"},
+  {1, "mkrgb",        mkrgb,            "convert 3 images to rgb jpeg (use Kapa for better control)"},
+  {1, "imset",        mset,             "insert a vector in an image"},
+  {1, "parity",       parity,           "set image parity"},
   {1, "peak",         peak,             "find vector peak in range"},
   {1, "periodogram",  periodogram,      "measure periods in unevenly sampled data"},
   {1, "plot",         plot,             "plot a pair of vectors"},
-  {1, "dot",          dot,              "plot a single point"},
-  {1, "point",        point,            "load overlay with single point"},
-  {1, "ps",           ps,               "define labels for plot"},
+  {1, "png",          jpeg,             "convert display graphic to PNG"},
+  {1, "point",        point,            "load image overlay with a single point"},
+  {1, "ppm",          jpeg,             "convert display graphic to PPM"},
+  {1, "ps",           ps,               "convert display to PostScript"},
+  {1, "queuedelete",  queuedelete,      "delete a queue"},
+  {1, "queuedrop",    queuedrop,        "drop values from queue matching a key"},
+  {1, "queueinit",    queueinit,        "create an empty queue"},
+  {1, "queuelist",    queuelist,        "list defined queues"},
+  {1, "queueload",    queueload,        "load queue from command"},
   {1, "queuepop",     queuepop,         "pop value from queue to variable"},
-  {1, "queuedrop",    queuedrop,        "drop values from queue matching a key"},
   {1, "queueprint",   queueprint,       "print the contents of a queue"},
   {1, "queuepush",    queuepush,        "push value onto queue"},
-  {1, "queueinit",    queueinit,        "create an empty queue"},
-  {1, "queuedelete",  queuedelete,      "delete a queue"},
-  {1, "queuelist",    queuelist,        "list defined queues"},
-  {1, "queueload",    queueload,        "load queue from command"},
+  {1, "queuesize",    queuesize,        "show queue size"},
   {1, "queuesubstr",  queuesubstr,      "bulk replace strings in queue"},
-  {1, "queuesize",    queuesize,        "show queue size"},
   {1, "rd",           rd,               "load fits image"},
   {1, "rdseg",        rdseg,            "read a segment of an image from a file"},
   {1, "read",         read_vectors,     "read vectors from datafile"},
-  {1, "rebin",        rebin,            "rebin data by factor of N"},
+  {1, "rebin",        rebin,            "rebin image data by factor of N"},
   {1, "resize",       resize,           "set graphics/image window size"},
   {1, "roll",         roll,             "roll image to new start point"},
   {1, "rotate",       rotate,           "rotate image"},
-  {1, "save",         save,             "save an SAOimage style overlay"},
+  {1, "save",         save,             "save an SAOimage style image overlay"},
   {1, "section",      section,          "define section of graph"},
-  {1, "set",          set,              "vector math"},
+  {1, "select",       vect_select,      "selective vector assignment"},
+  {1, "set",          set,              "image and vector math"},
   {1, "shift",        shift,            "shift data in an image"},
   {1, "sort",         sort_vectors,     "sort list of vectors"},
   {1, "spline.apply", spline_apply_cmd, "apply spline fit to generate an image"},
   {1, "spline.const", spline_construct_cmd, "create spline 2nd deriv. terms"},
-  {1, "stats",        stats,            "give statistics on a portion of a buffer"},
+  {1, "stats",        imstats,          "statistics on a portion of an image"},
   {1, "style",        style,            "set the style for graph plots"},
   {1, "subraster",    subraster,        "subraster of fits image"},
-  {1, "subset",       subset,           "expand vector dimension"},
-  {1, "svd",          svd,              "singular value decomposition of a matrix"},
+  {1, "subset",       subset,           "generate a vector from a portion of another vector"},
+  {1, "svd",          svd,              "singular value decomposition of a matrix (image)"},
   {1, "swapbytes",    swapbytes,        "byte swap thing"},
   {1, "textline",     textline,         "write text line on graph"},
@@ -225,23 +238,25 @@
   {1, "tvchannel",    tvchannel,        "set the current tv channel"},
   {1, "tvcolors",     tvcolors,         "set the tv colormap"},
-  {1, "tvcontour",    tvcontour,        "send contour to overlay"},
-  {1, "tvgrid",       tvgrid,           "wait until return is typed"},
+  {1, "tvcontour",    tvcontour,        "send contour to image overlay"},
+  {1, "tvgrid",       tvgrid,           "RA/DEC grid on an image"},
+  {1, "ungridify",    ungridify,        "convert image region to vector triplet"},
   {1, "uniq",         uniq,             "create a uniq vector subset from a vector"},
   {1, "unsign",       unsign,           "toggle the UNSIGN status"},
-  {1, "vbin",         vbin,             "bin values in a vector to be within a range"},
+  {1, "vbin",         vbin,             "rebin vector data by a fector of N"},
   {1, "vclip",        vclip,            "clip values in a vector to be within a range"},
-  {1, "select",       vect_select,      "selective vector assignment"},
-  {1, "vgauss",       vgauss,           ""},
-  {1, "vmaxwell",     vmaxwell,         ""},
-  {1, "vgrid",        vgrid,            ""},
-  {1, "vload",        vload,            "load vectors on Kii"},
-  {1, "vzload",       vzload,           "load vectors on Kii"},
-  {1, "vstat",        vstat,            "get info from imreg database"},
-  {1, "vsmooth",      vsmooth,          "gaussian smooth of a vector"},
+  {1, "vectors",      list_vectors,     "list vectors"},
+  {1, "vgauss",       vgauss,           "fit a Gaussian to a vector"},
+  {1, "vgrid",        vgrid,            "generate an image from a triplet of vectors"},
+  {1, "vhistogram",   histogram,        "generate histogram from vector"},
+  {1, "vload",        vload,            "load vectors as overlay on image display"},
+  {1, "vmaxwell",     vmaxwell,         "fit a Maxwellian to a vector"},
+  {1, "vpop",         vpop,             "remove first element of a vector"},
   {1, "vroll",        vroll,            "roll vector elements"},
-  {1, "vpop",         vpop,             "remove first element"},
+  {1, "vsmooth",      vsmooth,          "Gaussian smooth of a vector"},
+  {1, "vstats",       vstats,           "statistics on a vector"},
+  {1, "vzload",       vzload,           "load vectors as overlay on image display (scaled points)"},
   {1, "wd",           wd,               "write an image to a file"},
   {1, "write",        write_vectors,    "write vectors to datafile"},
-  {1, "zap",          zap,              "delete pixels"},
+  {1, "zap",          zap,              "assign values to pixel regions"},
   {1, "zplot",        zplot,            "plot x y with size scaled by z"},
 }; 
Index: anches/cnb_branch_20090215/Ohana/src/opihi/cmd.data/stats.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/opihi/cmd.data/stats.c	(revision 21535)
+++ 	(revision )
@@ -1,125 +1,0 @@
-# include "data.h"
-
-int stats (int argc, char **argv) {
-  
-  int i, j, Nmode, Imode;
-  double Npix, N1, N2, max, min, range, median, mode, IgnoreValue;
-  float *V;
-  int sx, sy, nx, ny, *hist, Nhist, bin;
-  int Ignore, Quiet, N;
-  Buffer *buf;
-
-  IgnoreValue = 0;
-  Ignore = FALSE;
-  if ((N = get_argument (argc, argv, "-ignore"))) {
-    Ignore = TRUE;
-    remove_argument (N, &argc, argv);
-    IgnoreValue = atof(argv[N]);
-    remove_argument (N, &argc, argv);
-  }
-
-  Quiet = FALSE;
-  if ((N = get_argument (argc, argv, "-q"))) {
-    Quiet = TRUE;
-    remove_argument (N, &argc, argv);
-  }
-  if ((N = get_argument (argc, argv, "-quiet"))) {
-    Quiet = TRUE;
-    remove_argument (N, &argc, argv);
-  }
-
-  if ((argc != 2) && (argc != 6)) {
-    gprint (GP_ERR, "USAGE: stats <buffer> sx sy nx ny\n");
-    gprint (GP_ERR, "OR:    stats <buffer>\n");
-    return (FALSE);
-  }
-
-  if ((buf = SelectBuffer (argv[1], OLDBUFFER, TRUE)) == NULL) return (FALSE);
-
-  if (argc == 6) {
-    sx = strcmp (argv[2], "-") ? atof (argv[2]) : 0;
-    sy = strcmp (argv[3], "-") ? atof (argv[3]) : 0;
-    nx = strcmp (argv[4], "-") ? atof (argv[4]) : buf[0].matrix.Naxis[0];
-    ny = strcmp (argv[5], "-") ? atof (argv[5]) : buf[0].matrix.Naxis[1];
-  } else {
-    sx = 0;
-    sy = 0;
-    nx = buf[0].matrix.Naxis[0];
-    ny = buf[0].matrix.Naxis[1];
-  }
-
-  Npix = N1 = N2 = 0;
-  if ((sx < 0) || (sy < 0) || 
-      (sx+nx > buf[0].matrix.Naxis[0]) || 
-      (sy+ny > buf[0].matrix.Naxis[1])) {
-    gprint (GP_ERR, "region out of range\n");
-    return (FALSE);
-  }
-
-  max = -1e32;
-  min = +1e32;
-  for (j = sy; j < sy + ny; j++) {
-    V = (float *)(buf[0].matrix.buffer) + j*buf[0].matrix.Naxis[0] + sx; 
-    for (i = 0; i < nx; i++, V++) {
-      if (Ignore && (fabs (*V - IgnoreValue) < 1e-8)) continue;
-      if (isnan(*V)) continue;
-      if (isinf(*V)) continue;
-      N1 += *V;
-      N2 += (*V)*(*V);
-      Npix += 1.0;
-      max = MAX (max, *V);
-      min = MIN (min, *V);
-    }
-  }
-  N1 = N1 / Npix;
-
-/* calculate mode, median */
-  median = mode = 0.5*(max + min);
-  if ((max - min) != 0) {
-    range = 0xffff / (max - min);
-    ALLOCATE (hist, int, 0x10000);
-    bzero (hist, 0x10000*sizeof(int));
-    for (j = sy; j < sy + ny; j++) {
-      V = (float *)(buf[0].matrix.buffer) + j*buf[0].matrix.Naxis[0] + sx; 
-      for (i = 0; i < nx; i++, V++) {
-	if (Ignore && (fabs (*V - IgnoreValue) < 1e-8)) continue;
-	if (isnan(*V)) continue;
-	if (isinf(*V)) continue;
-	bin = MIN (MAX (0, (*V - min) * range), 0xffff);
-	hist[bin] ++;
-      }
-    }
-    Nhist = 0;
-    for (i = 0; (i < 0xffff) && (Nhist < 0.5*Npix); i++) 
-      Nhist += hist[i];
-    median = i / range + min;
-    Nmode = hist[0];
-    Imode = 0;
-    for (i = 1; i < 0x10000; i++) {
-      if (hist[i] > Nmode) {
-	Nmode = hist[i];
-	Imode = i;
-      }
-    }
-    mode = Imode / range + min;
-    free (hist);
-  }  
-  
-  if (!Quiet) {
-    gprint (GP_LOG, "  mean    stdev    min     max   median   Npix   Total\n");
-    gprint (GP_LOG, "%7.4g %7.4g %7.4g %7.4g %7.4g %7.0f %7.4g\n", N1, sqrt (N2/Npix - N1*N1), 
-	    min, max, median, Npix, Npix*N1);
-  }
-
-  set_variable ("MIN",    min);
-  set_variable ("MAX",    max);
-  set_variable ("MEDIAN", median);
-  set_variable ("MEAN",   N1);
-  set_variable ("MODE",   mode);
-  set_variable ("TOTAL",  N1*Npix);
-  set_variable ("NPIX",   Npix);
-  set_variable ("SIGMA",  sqrt (N2/Npix - N1*N1));
-
-  return (TRUE);
-}
-
Index: anches/cnb_branch_20090215/Ohana/src/opihi/cmd.data/vstat.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/opihi/cmd.data/vstat.c	(revision 21535)
+++ 	(revision )
@@ -1,139 +1,0 @@
-# include "data.h"
-
-int vstat (int argc, char **argv) {
-  
-  int i, N;
-  double max, min, sum, var, dvar, mean, stdev;
-  float IgnoreValue;
-  int Ignore, Quiet;
-
-  int *Nval, bin, Nmode, Nmed;
-  double dx, mode, median;
-  Vector *vec;
-
-  IgnoreValue = 0;
-  Ignore = FALSE;
-  if ((N = get_argument (argc, argv, "-ignore"))) {
-    Ignore = TRUE;
-    remove_argument (N, &argc, argv);
-    IgnoreValue = atof(argv[N]);
-    remove_argument (N, &argc, argv);
-  }
-
-  Quiet = FALSE;
-  if ((N = get_argument (argc, argv, "-q"))) {
-    Quiet = TRUE;
-    remove_argument (N, &argc, argv);
-  }
-  if ((N = get_argument (argc, argv, "-quiet"))) {
-    Quiet = TRUE;
-    remove_argument (N, &argc, argv);
-  }
-
-  if (argc != 2) {
-    gprint (GP_ERR, "USAGE: vstat (vector)\n");
-    return (FALSE);
-  }
-
-  if ((vec = SelectVector (argv[1], OLDVECTOR, TRUE)) == NULL) return (FALSE);
-
-  /* we need two passes, one for max, min, mean, sum, one for median, stdev, etc */
-
-  /* calculate max, min, mean, sum, npix */
-  max = -HUGE_VAL;
-  min = HUGE_VAL;
-  sum = N = 0;
-  if (vec[0].type == OPIHI_FLT) {
-    opihi_flt *X = vec[0].elements.Flt;
-    for (i = 0; i < vec[0].Nelements; i++, X++) {
-      if (!finite (*X)) continue;
-      if (Ignore && (*X == IgnoreValue)) continue;
-      max = MAX (*X, max);
-      min = MIN (*X, min);
-      sum += *X;
-      N++;
-    }      
-  } else {
-    opihi_int *X = vec[0].elements.Int;
-    for (i = 0; i < vec[0].Nelements; i++, X++) {
-      if (!finite (*X)) continue;
-      if (Ignore && (*X == IgnoreValue)) continue;
-      max = MAX (*X, max);
-      min = MIN (*X, min);
-      sum += *X;
-      N++;
-    }      
-  }
-  mean = sum / N;
-
-  /* calculate median and mode with resolution of (max - min) / 1000 */ 
-  dx = (max - min) / 1000;
-  if (dx == 0) {
-    median = mode = min;
-    stdev = 0.0;
-    goto skip;
-  }
-
-  ALLOCATE (Nval, int, 1002);
-  bzero (Nval, 1000*sizeof(int));
-  var = 0;
-  if (vec[0].type == OPIHI_FLT) {
-    opihi_flt *X = vec[0].elements.Flt;
-    for (i = 0; i < vec[0].Nelements; i++, X++) {
-      if (!finite (*X)) continue;
-      if (Ignore && (*X == IgnoreValue)) continue;
-      bin = MAX (0, MIN (1000, (*X - min) / dx));
-      Nval[bin] ++;
-      dvar = (*X - mean);
-      var += dvar*dvar;
-    }      
-  } else {
-    opihi_int *X = vec[0].elements.Int;
-    for (i = 0; i < vec[0].Nelements; i++, X++) {
-      if (!finite (*X)) continue;
-      if (Ignore && (*X == IgnoreValue)) continue;
-      bin = MAX (0, MIN (1000, (*X - min) / dx));
-      Nval[bin] ++;
-      dvar = (*X - mean);
-      var += dvar*dvar;
-    }      
-  }
-  stdev = sqrt (var / N);
-
-  Nmode = 0;
-  mode = Nval[Nmode];
-  median = 0;
-  Nmed = -1;
-  for (i = 0; i < 1001; i++) {
-    if (Nmed == -1) {
-      median += Nval[i];
-      if (median >= N / 2.0) {
-	Nmed = i;
-	median = i * dx + min;
-      }
-    }
-    if (mode < Nval[i]) {
-      Nmode = i;
-      mode = Nval[Nmode];
-    }
-  }
-  mode = Nmode * dx + min;
-  free (Nval);
-
-skip:
-  if (!Quiet) {
-    gprint (GP_ERR, "mean: %g, stdev: %g, min: %g, max: %g, median: %g, mode: %g, Npts: %d\n", 
-	     mean, stdev, min, max, median, mode, N);
-  }
-
-  set_variable ("MIN",      min);
-  set_variable ("MAX",      max);
-  set_variable ("MEDIAN",   median);
-  set_variable ("MEAN",     mean);
-  set_variable ("MODE",     mode);
-  set_variable ("TOTAL",    sum);
-  set_int_variable ("NPIX", N);
-  set_variable ("SIGMA",    stdev);
-  return (TRUE);
-}
-
Index: /branches/cnb_branch_20090215/Ohana/src/opihi/cmd.data/vstats.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/opihi/cmd.data/vstats.c	(revision 21536)
+++ /branches/cnb_branch_20090215/Ohana/src/opihi/cmd.data/vstats.c	(revision 21536)
@@ -0,0 +1,139 @@
+# include "data.h"
+
+int vstats (int argc, char **argv) {
+  
+  int i, N;
+  double max, min, sum, var, dvar, mean, stdev;
+  float IgnoreValue;
+  int Ignore, Quiet;
+
+  int *Nval, bin, Nmode, Nmed;
+  double dx, mode, median;
+  Vector *vec;
+
+  IgnoreValue = 0;
+  Ignore = FALSE;
+  if ((N = get_argument (argc, argv, "-ignore"))) {
+    Ignore = TRUE;
+    remove_argument (N, &argc, argv);
+    IgnoreValue = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  Quiet = FALSE;
+  if ((N = get_argument (argc, argv, "-q"))) {
+    Quiet = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+  if ((N = get_argument (argc, argv, "-quiet"))) {
+    Quiet = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+
+  if (argc != 2) {
+    gprint (GP_ERR, "USAGE: vstat (vector)\n");
+    return (FALSE);
+  }
+
+  if ((vec = SelectVector (argv[1], OLDVECTOR, TRUE)) == NULL) return (FALSE);
+
+  /* we need two passes, one for max, min, mean, sum, one for median, stdev, etc */
+
+  /* calculate max, min, mean, sum, npix */
+  max = -HUGE_VAL;
+  min = HUGE_VAL;
+  sum = N = 0;
+  if (vec[0].type == OPIHI_FLT) {
+    opihi_flt *X = vec[0].elements.Flt;
+    for (i = 0; i < vec[0].Nelements; i++, X++) {
+      if (!finite (*X)) continue;
+      if (Ignore && (*X == IgnoreValue)) continue;
+      max = MAX (*X, max);
+      min = MIN (*X, min);
+      sum += *X;
+      N++;
+    }      
+  } else {
+    opihi_int *X = vec[0].elements.Int;
+    for (i = 0; i < vec[0].Nelements; i++, X++) {
+      if (!finite (*X)) continue;
+      if (Ignore && (*X == IgnoreValue)) continue;
+      max = MAX (*X, max);
+      min = MIN (*X, min);
+      sum += *X;
+      N++;
+    }      
+  }
+  mean = sum / N;
+
+  /* calculate median and mode with resolution of (max - min) / 1000 */ 
+  dx = (max - min) / 1000;
+  if (dx == 0) {
+    median = mode = min;
+    stdev = 0.0;
+    goto skip;
+  }
+
+  ALLOCATE (Nval, int, 1002);
+  bzero (Nval, 1000*sizeof(int));
+  var = 0;
+  if (vec[0].type == OPIHI_FLT) {
+    opihi_flt *X = vec[0].elements.Flt;
+    for (i = 0; i < vec[0].Nelements; i++, X++) {
+      if (!finite (*X)) continue;
+      if (Ignore && (*X == IgnoreValue)) continue;
+      bin = MAX (0, MIN (1000, (*X - min) / dx));
+      Nval[bin] ++;
+      dvar = (*X - mean);
+      var += dvar*dvar;
+    }      
+  } else {
+    opihi_int *X = vec[0].elements.Int;
+    for (i = 0; i < vec[0].Nelements; i++, X++) {
+      if (!finite (*X)) continue;
+      if (Ignore && (*X == IgnoreValue)) continue;
+      bin = MAX (0, MIN (1000, (*X - min) / dx));
+      Nval[bin] ++;
+      dvar = (*X - mean);
+      var += dvar*dvar;
+    }      
+  }
+  stdev = sqrt (var / N);
+
+  Nmode = 0;
+  mode = Nval[Nmode];
+  median = 0;
+  Nmed = -1;
+  for (i = 0; i < 1001; i++) {
+    if (Nmed == -1) {
+      median += Nval[i];
+      if (median >= N / 2.0) {
+	Nmed = i;
+	median = i * dx + min;
+      }
+    }
+    if (mode < Nval[i]) {
+      Nmode = i;
+      mode = Nval[Nmode];
+    }
+  }
+  mode = Nmode * dx + min;
+  free (Nval);
+
+skip:
+  if (!Quiet) {
+    gprint (GP_ERR, "mean: %g, stdev: %g, min: %g, max: %g, median: %g, mode: %g, Npts: %d\n", 
+	     mean, stdev, min, max, median, mode, N);
+  }
+
+  set_variable ("MIN",      min);
+  set_variable ("MAX",      max);
+  set_variable ("MEDIAN",   median);
+  set_variable ("MEAN",     mean);
+  set_variable ("MODE",     mode);
+  set_variable ("TOTAL",    sum);
+  set_int_variable ("NPIX", N);
+  set_variable ("SIGMA",    stdev);
+  return (TRUE);
+}
+
Index: /branches/cnb_branch_20090215/Ohana/src/opihi/dvo/dbExtractAverages.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/opihi/dvo/dbExtractAverages.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/opihi/dvo/dbExtractAverages.c	(revision 21536)
@@ -121,5 +121,5 @@
       break;
     case AVE_FLAG:
-      value.Int = average[0].code;
+      value.Int = average[0].flags;
       break;
     case AVE_OBJID:
Index: /branches/cnb_branch_20090215/Ohana/src/opihi/dvo/dbExtractImages.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/opihi/dvo/dbExtractImages.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/opihi/dvo/dbExtractImages.c	(revision 21536)
@@ -247,5 +247,5 @@
       break;
     case IMAGE_FLAG:
-      value.Int = image[N].code;
+      value.Int = image[N].flags;
       break;
     case IMAGE_CCDNUM:
Index: /branches/cnb_branch_20090215/Ohana/src/opihi/dvo/dbExtractMeasures.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/opihi/dvo/dbExtractMeasures.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/opihi/dvo/dbExtractMeasures.c	(revision 21536)
@@ -146,5 +146,5 @@
 	case MAG_NPHOT:
 	  if (equiv == NULL) {
-	    value.Int = NAN;
+	    value.Int = 0;
 	    break;
 	  }
@@ -260,5 +260,5 @@
       break;
     case MEAS_OBJFLAGS: /* OK */
-      value.Int = average[0].code;
+      value.Int = average[0].flags;
       break;
     // note that these represent the ra displacement relative to the average, not 
@@ -312,5 +312,5 @@
       break;
     case MEAS_DOPHOT: /* OK */
-      value.Flt = measure[0].dophot;
+      value.Int = (measure[0].photFlags >> 16);
       break;
     case MEAS_DB_FLAGS: /* ? */
@@ -394,5 +394,5 @@
       break;
     case MEAS_PSF_QF: /* OK */
-      value.Flt = measure[0].qPSF;
+      value.Flt = measure[0].psfQual;
       break;
     case MEAS_PSF_CHISQ: /* OK */
@@ -404,7 +404,4 @@
     case MEAS_EXT_NSIGMA: /* OK */
       value.Flt = measure[0].extNsigma;
-      break;
-    case MEAS_STARGAL: /* OK */
-      value.Flt = measure[0].stargal;
       break;
 
Index: /branches/cnb_branch_20090215/Ohana/src/opihi/dvo/dbFields.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/opihi/dvo/dbFields.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/opihi/dvo/dbFields.c	(revision 21536)
@@ -170,5 +170,5 @@
   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, "DOPHOT"))     ESCAPE (MEAS_DOPHOT,      	  MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "DOPHOT"))     ESCAPE (MEAS_DOPHOT,      	  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);
@@ -193,5 +193,4 @@
   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, "STARGAL"))    ESCAPE (MEAS_STARGAL,     	  MAG_NONE, OPIHI_FLT);
 
   // for words that don't parse, try a photcode
Index: /branches/cnb_branch_20090215/Ohana/src/opihi/dvo/gimages.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/opihi/dvo/gimages.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/opihi/dvo/gimages.c	(revision 21536)
@@ -220,9 +220,9 @@
     if (PixelCoords) {
       gprint (GP_LOG, "%3d %s %6.1f %6.1f %20s %5d %2d %4.2f %6.3f %5.3f %5.3f %4x\n", 
-	       Nfound, image[i].name, X, Y, date, image[i].nstar, image[i].photcode, image[i].secz, image[i].Mcal, image[i].dMcal, image[i].exptime, image[i].code);
+	       Nfound, image[i].name, X, Y, date, image[i].nstar, image[i].photcode, image[i].secz, image[i].Mcal, image[i].dMcal, image[i].exptime, image[i].flags);
     } else {
       XY_to_RD (&ra, &dec, 0.5*image[i].NX, 0.5*image[i].NY, &image[i].coords);
       gprint (GP_LOG, "%3d %s %8.4f %8.4f %20s %5d %2d %4.2f %6.3f %5.3f %5.3f %4x\n", 
-	       Nfound, image[i].name, ra, dec, date, image[i].nstar, image[i].photcode, image[i].secz, image[i].Mcal, image[i].dMcal, image[i].exptime, image[i].code);
+	       Nfound, image[i].name, ra, dec, date, image[i].nstar, image[i].photcode, image[i].secz, image[i].Mcal, image[i].dMcal, image[i].exptime, image[i].flags);
     }
     sprintf (name, "IMAGEx:%d", Nfound);
Index: /branches/cnb_branch_20090215/Ohana/src/opihi/dvo/gstar.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/opihi/dvo/gstar.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/opihi/dvo/gstar.c	(revision 21536)
@@ -158,5 +158,5 @@
 	gprint (GP_LOG, "%3d   ",  catalog.average[k].Nmeasure);
 	gprint (GP_LOG, "%4.1f ",  0.01*catalog.average[k].Xp);
-	gprint (GP_LOG, "%5d",     catalog.average[k].code);
+	gprint (GP_LOG, "%5d",     catalog.average[k].flags);
 
 	if (FULL_OUTPUT) {
@@ -211,5 +211,5 @@
 	    gprint (GP_LOG, "%7.4f ",  catalog.measure[m].dR);
 	    gprint (GP_LOG, "%7.4f",   catalog.measure[m].dD);
-	    gprint (GP_LOG, "%2d ",    catalog.measure[m].dophot);
+	    gprint (GP_LOG, "%4x ",    catalog.measure[m].photFlags);
 	    gprint (GP_LOG, "%3x ",    catalog.measure[m].dbFlags);
 	    gprint (GP_LOG, "%5d ",    catalog.measure[m].photcode);
@@ -233,5 +233,5 @@
 		gprint (GP_LOG, "%d", catalog.measure[m].detID);
 		gprint (GP_LOG, "%d", catalog.measure[m].imageID);
-		gprint (GP_LOG, "%f", catalog.measure[m].qPSF);
+		gprint (GP_LOG, "%f", catalog.measure[m].psfQual);
 		gprint (GP_LOG, "%f", catalog.measure[m].psfChisq);
 		gprint (GP_LOG, "%f", catalog.measure[m].crNsigma);
@@ -240,7 +240,4 @@
 		gprint (GP_LOG, "%f", 0.01*catalog.measure[m].FWy);
 		gprint (GP_LOG, "%f", (360.0/(float)0xffff)*catalog.measure[m].theta);
-
-		gprint (GP_LOG, "%x", catalog.measure[m].photFlags);
-		gprint (GP_LOG, "%d", catalog.measure[m].stargal);
 	    }
 	    gprint (GP_LOG, "\n");
Index: /branches/cnb_branch_20090215/Ohana/src/opihi/dvo/paverage.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/opihi/dvo/paverage.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/opihi/dvo/paverage.c	(revision 21536)
@@ -122,5 +122,5 @@
     /* project stars to screen display coords */
     for (i = 0; (i < catalog.Naverage) && !interrupt; i++) {
-      if (IDclip && (average[i].code != IDchoice)) continue;
+      if (IDclip && (average[i].flags != IDchoice)) continue;
       average[i].R = ohana_normalize_angle (average[i].R);
       while (average[i].R < Rmin) average[i].R += 360.0;
Index: /branches/cnb_branch_20090215/Ohana/src/opihi/dvo/photometry.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/opihi/dvo/photometry.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/opihi/dvo/photometry.c	(revision 21536)
@@ -2,41 +2,41 @@
 
 /* match code to measure  */
-# define TESTCODE(C,M) \
-  if (C != NULL) { \
-    switch (C[0].type) { \
-    case PHOT_DEP: \
-    case PHOT_REF: \
-      if (C[0].code != M.photcode) continue; \
-      break; \
-    case PHOT_SEC: \
-      if (C[0].code != GetPhotcodeEquivCodebyCode (M.photcode)) continue; \
-      break; \
-    default: \
-      break; \
-  } }
+# define TESTCODE(C,M)							\
+  if (C != NULL) {							\
+    switch (C[0].type) {						\
+      case PHOT_DEP:							\
+      case PHOT_REF:							\
+	if (C[0].code != M.photcode) continue;				\
+	break;								\
+      case PHOT_SEC:							\
+	if (C[0].code != GetPhotcodeEquivCodebyCode (M.photcode)) continue; \
+	break;								\
+      default:								\
+	break;								\
+    } }
 
 /* exclusions based on measure.params  */
-# define TESTMEASURE(M) \
-  if (ApplySelections[SelectionParam]) { \
-    if (TimeSelect && (M.t < tzero)) continue; \
-    if (TimeSelect && (M.t > tend)) continue; \
-    if (ErrSelect  && (M.dM > ErrValue)) continue; \
+# define TESTMEASURE(M)							\
+  if (ApplySelections[SelectionParam]) {				\
+    if (TimeSelect && (M.t < tzero)) continue;				\
+    if (TimeSelect && (M.t > tend)) continue;				\
+    if (ErrSelect  && (M.dM > ErrValue)) continue;			\
+    if (iMagSelect && (PhotInst (&M) < iMagMin)) continue;		\
+    if (FlagSelect && (M.dbFlags != FlagValue)) continue;		\
     if (TypeSelect && (TypeValue != GetMeasureTypeCode (&M))) continue; \
-    if (iMagSelect && (PhotInst (&M) < iMagMin)) continue; \
-    if (FlagSelect && (M.dbFlags != FlagValue)) continue; \
-  }
-
-# define SETMAG(MOUT,MEAS,MODE) \
-  MOUT = NAN; \
-  if (MODE == MAG_INST) MOUT = PhotInst (&MEAS);  \
-  if (MODE == MAG_CAT)  MOUT = PhotCat  (&MEAS); \
-  if (MODE == MAG_SYS)  MOUT = PhotSys  (&MEAS, average, secfilt); \
-  if (MODE == MAG_REL)  MOUT = PhotRel  (&MEAS, average, secfilt); \
+  }
+
+# define SETMAG(MOUT,MEAS,MODE)						\
+  MOUT = NAN;								\
+  if (MODE == MAG_INST) MOUT = PhotInst (&MEAS);			\
+  if (MODE == MAG_CAT)  MOUT = PhotCat  (&MEAS);			\
+  if (MODE == MAG_SYS)  MOUT = PhotSys  (&MEAS, average, secfilt);	\
+  if (MODE == MAG_REL)  MOUT = PhotRel  (&MEAS, average, secfilt);	\
   if (MODE == MAG_CAL)  MOUT = PhotCal  (&MEAS, average, secfilt, measure, GetPhotcodeEquivbyCode (MEAS.photcode)); \
   if (MODE == MAG_AVE)  MOUT = PhotAve  (GetPhotcodeEquivbyCode (MEAS.photcode), average, secfilt); \
   if (MODE == MAG_REF)  MOUT = PhotRef  (GetPhotcodeEquivbyCode (MEAS.photcode), average, secfilt, measure); \
-  if (ApplySelections[SelectionParam]) { \
-    if (MagSelect && (MOUT > MagMax)) continue; \
-    if (MagSelect && (MOUT < MagMin)) continue; \
+  if (ApplySelections[SelectionParam]) {				\
+    if (MagSelect && (MOUT > MagMax)) continue;				\
+    if (MagSelect && (MOUT < MagMin)) continue;				\
   }
 
@@ -182,5 +182,4 @@
   if (!strcasecmp (parname, "dec"))  	 param = MEAS_DEC;
   if (!strcasecmp (parname, "mag")) 	 param = MEAS_MAG;
-  // if (!strcasecmp (parname, "dmag")) 	 param = MEAS_dMAG;
   if (!strcasecmp (parname, "airmass"))  param = MEAS_AIRMASS;
   if (!strcasecmp (parname, "exptime"))  param = MEAS_EXPTIME;
@@ -190,5 +189,4 @@
   if (!strcasecmp (parname, "dD")) 	 param = MEAS_DEC_OFFSET;
   if (!strcasecmp (parname, "fwhm"))   	 param = MEAS_FWHM;
-  // if (!strcasecmp (parname, "dophot")) 	 param = MEAS_DOPHOT;
   if (!strcasecmp (parname, "FLAGS"))    param = MEAS_DB_FLAGS;
   if (!strcasecmp (parname, "XCCD"))   	 param = MEAS_XCCD;
@@ -198,5 +196,5 @@
   if (!strcasecmp (parname, "help")) {
     gprint (GP_ERR, "value may be one of the following:\n");
-    gprint (GP_ERR, " ra dR dec dD mag dmag Mrel Mcal photcode time fwhm dophot xccd yccd xmosaic ymosaic flags\n");
+    gprint (GP_ERR, " ra dR dec dD mag dmag Mrel Mcal photcode time fwhm xccd yccd xmosaic ymosaic flags\n");
     gprint (GP_ERR, "value may also be a valid photcode\n");
     gprint (GP_ERR, "photcodes or 'mag' may have optional magnitude type: mag,[Minst, Mcat, Msys, Mrel, Mcal]\n");
@@ -311,6 +309,6 @@
 
   if (VarConfig ("ZERO_PT", "%lf", &ZERO_POINT) == (char *) NULL) {
-      gprint (GP_ERR, "ZERO_PT undefined in config\n");
-      return (FALSE);
+    gprint (GP_ERR, "ZERO_PT undefined in config\n");
+    return (FALSE);
   }
   SetZeroPoint (ZERO_POINT);
@@ -324,6 +322,6 @@
 
   if (VarConfig ("PHOTCODE_FILE", "%s", MasterPhotcodeFile) == (char *) NULL) {
-      gprint (GP_ERR, "PHOTCODE_FILE undefined in config\n");
-      return (FALSE);
+    gprint (GP_ERR, "PHOTCODE_FILE undefined in config\n");
+    return (FALSE);
   }
   if (!LoadPhotcodes (CatdirPhotcodeFile, MasterPhotcodeFile)) {
@@ -642,5 +640,5 @@
       break;
     case AVE_FLAG:
-      value = average[0].code;
+      value = average[0].flags;
       break;
     case AVE_MAG:
@@ -659,6 +657,6 @@
 	  value = NAN;
 	  for (i = 0; i < average[0].Nmeasure; i++) {
-	      if (code[0].code != measure[i].photcode) continue;
-	      value = measure[i].M;
+	    if (code[0].code != measure[i].photcode) continue;
+	    value = measure[i].M;
 	  }
 	  break;
@@ -675,5 +673,6 @@
       break;
     case AVE_TYPEFRAC:
-      value = DetermineTypefrac (average, measure, code);
+      // value = DetermineTypefrac (average, measure, code);
+      value = NAN;
       break;
     case AVE_NCODE:
@@ -719,5 +718,5 @@
     if ((code != NULL) && (code[0].code != GetPhotcodeEquivCodebyCode (measure[k].photcode))) continue;
     Nc ++;
-    if (measure[k].dophot != TypefracType) continue;
+    if ((measure[k].photFlags >> 16) != TypefracType) continue;
     Nt ++;
   }
@@ -744,5 +743,5 @@
 
 int GetMeasureTypeCode (Measure *measure) {
-  switch (measure[0].dophot) {
+  switch ((measure[0].photFlags >> 16)) {
     case 0:
     case 1:
@@ -770,5 +769,5 @@
   if (IsDophot) {
     
-    if (measure[0].dophot == 4) return (FALSE);
+    if ((measure[0].photFlags >> 16) == 4) return (FALSE);
     return (TRUE);
   
@@ -866,5 +865,5 @@
   if (ErrSelect) {
     dM = PhotdM (code, average, secfilt);
-    if (dM > ErrValue) return (NAN);
+    if (dM > ErrValue) return (FALSE);
   }
   
@@ -1137,12 +1136,7 @@
       value = average[0].D - measure[0].dD / 3600.0;
       break;
-# if (0)
-    case MEAS_dMAG: /* OK */
-      value = measure[0].dM;
-      break;
     case MEAS_DOPHOT: /* OK */
-      value = measure[0].dophot;
-      break;
-# endif
+      value = (measure[0].photFlags >> 16);
+      break;
     case MEAS_AIRMASS: /* OK */
       value = measure[0].airmass;
Index: /branches/cnb_branch_20090215/Ohana/src/opihi/dvo/pmeasure.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/opihi/dvo/pmeasure.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/opihi/dvo/pmeasure.c	(revision 21536)
@@ -192,5 +192,5 @@
     /* project stars to screen display coords */
     for (i = 0; (i < catalog.Naverage) && !interrupt; i++) {
-      if (IDclip && (catalog.average[i].code != IDchoice)) continue;
+      if (IDclip && (catalog.average[i].flags != IDchoice)) continue;
       catalog.average[i].R = ohana_normalize_angle (catalog.average[i].R);
       while (catalog.average[i].R < Rmin) catalog.average[i].R += 360.0;
Index: /branches/cnb_branch_20090215/Ohana/src/opihi/include/dvoshell.h
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/opihi/include/dvoshell.h	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/opihi/include/dvoshell.h	(revision 21536)
@@ -106,5 +106,4 @@
       MEAS_CR_NSIGMA, 
       MEAS_EXT_NSIGMA, 
-      MEAS_STARGAL, 
 };
 
Index: /branches/cnb_branch_20090215/Ohana/src/relastro/include/relastro.h
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/relastro/include/relastro.h	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/relastro/include/relastro.h	(revision 21536)
@@ -61,5 +61,5 @@
   short Xm;
   float secz;
-  char code;
+  char flags;
   Coords coords;
 } Mosaic; 
Index: /branches/cnb_branch_20090215/Ohana/src/relastro/src/MosaicOps.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/relastro/src/MosaicOps.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/relastro/src/MosaicOps.c	(revision 21536)
@@ -47,5 +47,5 @@
     mosaic[Nmosaic].dMcal = 0.0;
     mosaic[Nmosaic].Xm    = 0.0;
-    mosaic[Nmosaic].code  = image[i].code;
+    mosaic[Nmosaic].flags  = image[i].flags;
     mosaic[Nmosaic].secz  = image[i].secz;
     mosaic[Nmosaic].coords = image[i].coords;
Index: /branches/cnb_branch_20090215/Ohana/src/relastro/src/UpdateObjects.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/relastro/src/UpdateObjects.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/relastro/src/UpdateObjects.c	(revision 21536)
@@ -169,5 +169,5 @@
       // position, consider including the lower-quality detections
 
-      catalog[i].average[j].code &= ~ID_STAR_FEW;
+      catalog[i].average[j].flags &= ~ID_STAR_FEW;
 
       // XXX add the parallax factor range as a criterion as well
Index: /branches/cnb_branch_20090215/Ohana/src/relastro/src/bcatalog.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/relastro/src/bcatalog.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/relastro/src/bcatalog.c	(revision 21536)
@@ -36,6 +36,6 @@
       // XXX define astrometry vs photometry average.dbFlags
       // XXX put photometry flags in secfilt (ie, per average mag?)
-      subcatalog[0].average[Naverage].code &= ~ID_STAR_FEW;
-      subcatalog[0].average[Naverage].code &= ~ID_STAR_POOR;
+      subcatalog[0].average[Naverage].flags &= ~ID_STAR_FEW;
+      subcatalog[0].average[Naverage].flags &= ~ID_STAR_POOR;
     }
 
@@ -70,5 +70,6 @@
 
       /* select measurements by quality */
-      if (DophotSelect && (catalog[0].measure[offset].dophot != DophotValue)) continue;
+      // XXX FIX THIS!!
+      // if (DophotSelect && (catalog[0].measure[offset].dophot != DophotValue)) continue;
 
       /* select measurements by quality */
Index: /branches/cnb_branch_20090215/Ohana/src/relastro/src/load_catalogs.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/relastro/src/load_catalogs.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/relastro/src/load_catalogs.c	(revision 21536)
@@ -38,5 +38,5 @@
       if (RESET) {
 	for (j = 0; j < catalog[i].Naverage; j++) {
-	  catalog[i].average[j].code = 0;
+	  catalog[i].average[j].flags = 0;
 	  m = catalog[i].average[j].measureOffset;
 	  for (k = 0; k < catalog[i].average[j].Nmeasure; k++) {
Index: /branches/cnb_branch_20090215/Ohana/src/relastro/src/relastro_objects.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/relastro/src/relastro_objects.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/relastro/src/relastro_objects.c	(revision 21536)
@@ -40,5 +40,5 @@
     if (RESET) {
       for (j = 0; j < catalog.Naverage; j++) {
-	catalog.average[j].code = 0;
+	catalog.average[j].flags = 0;
 	m = catalog.average[j].measureOffset;
 	for (k = 0; k < catalog.average[j].Nmeasure; k++) {
Index: /branches/cnb_branch_20090215/Ohana/src/relastro/src/select_images.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/relastro/src/select_images.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/relastro/src/select_images.c	(revision 21536)
@@ -147,6 +147,6 @@
       image[nimage] = timage[i]; 
       /* always allow 'few' images to succeed, if possible */
-      if (image[nimage].code & ID_IMAGE_FEW) { 
-	image[nimage].code &= ~(ID_IMAGE_FEW | ID_IMAGE_POOR);
+      if (image[nimage].flags & ID_IMAGE_FEW) { 
+	image[nimage].flags &= ~(ID_IMAGE_FEW | ID_IMAGE_POOR);
       }
       if (RESET) {
@@ -154,5 +154,5 @@
 	assignMcal (&image[nimage], (double *) NULL, -1);
 	image[nimage].dMcal = NAN;
-	image[nimage].code &= ~ID_IMAGE_POOR;
+	image[nimage].flags &= ~ID_IMAGE_POOR;
       }
       line_number[nimage] = i;
Index: /branches/cnb_branch_20090215/Ohana/src/relphot/include/relphot.h
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/relphot/include/relphot.h	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/relphot/include/relphot.h	(revision 21536)
@@ -23,5 +23,5 @@
   short Xm;
   float secz;
-  char code;
+  char flags;
   Coords coords;
 } Mosaic; 
Index: /branches/cnb_branch_20090215/Ohana/src/relphot/src/GridOps.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/relphot/src/GridOps.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/relphot/src/GridOps.c	(revision 21536)
@@ -369,5 +369,5 @@
 
       // skip stars marked as BAD
-      if (catalog[c].average[n].code & STAR_BAD) {
+      if (catalog[c].average[n].flags & STAR_BAD) {
 	Nrel ++;
 	continue;
Index: /branches/cnb_branch_20090215/Ohana/src/relphot/src/ImageOps.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/relphot/src/ImageOps.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/relphot/src/ImageOps.c	(revision 21536)
@@ -244,5 +244,5 @@
   if (i == -1) return (NAN);
 
-  if (image[i].code & IMAGE_BAD) return (NAN);  
+  if (image[i].flags & IMAGE_BAD) return (NAN);  
   value = image[i].Mcal;
   return (value);
@@ -285,5 +285,5 @@
     /* on PoorImages run, skip good images */
     if (PoorImages) {
-      bad = image[i].code & (ID_IMAGE_FEW | ID_IMAGE_POOR | ID_IMAGE_SKIP);
+      bad = image[i].flags & (ID_IMAGE_FEW | ID_IMAGE_POOR | ID_IMAGE_SKIP);
       if (!bad) continue;
     }      
@@ -331,8 +331,8 @@
       mark = (N < IMAGE_TOOFEW) || (N < IMAGE_GOOD_FRACTION*Nlist[i]);
       if (mark) {
-	image[i].code |= ID_IMAGE_FEW;
+	image[i].flags |= ID_IMAGE_FEW;
 	Nfew ++;
       } else {
-	image[i].code &= ~ID_IMAGE_FEW;
+	image[i].flags &= ~ID_IMAGE_FEW;
       }      
     }
@@ -373,5 +373,5 @@
 
   for (i = N = 0; i < Nimage; i++) {
-    if (image[i].code & IMAGE_BAD) continue;
+    if (image[i].flags & IMAGE_BAD) continue;
     mlist[N] = fabs (image[i].Mcal);
     slist[N] = image[i].dMcal;
@@ -390,11 +390,11 @@
   for (i = 0; i < Nimage; i++) {
     mark = FALSE;
-    image[i].code &= ~ID_IMAGE_POOR;
+    image[i].flags &= ~ID_IMAGE_POOR;
     mark = (image[i].dMcal > MaxScatter) || (fabs(image[i].Mcal - MedOffset) > MaxOffset);
     if (mark) { 
       Nmark ++;
-      image[i].code |= ID_IMAGE_POOR;
+      image[i].flags |= ID_IMAGE_POOR;
     } else {
-      image[i].code &= ~ID_IMAGE_POOR;
+      image[i].flags &= ~ID_IMAGE_POOR;
     }
   }
@@ -470,5 +470,5 @@
   n = 0;
   for (i = 0; i < Nimage; i++) {
-    if (image[i].code & IMAGE_BAD)  continue;
+    if (image[i].flags & IMAGE_BAD)  continue;
 
     N = 0;
@@ -512,5 +512,5 @@
   for (i = 0; i < Nimage; i++) {
 
-    if (image[i].code & IMAGE_BAD)  continue;
+    if (image[i].flags & IMAGE_BAD)  continue;
 
     list[n] = pow (10.0, 0.01*image[i].Xm);
@@ -540,5 +540,5 @@
   for (i = 0; i < Nimage; i++) {
 
-    if (image[i].code & IMAGE_BAD)  continue;
+    if (image[i].flags & IMAGE_BAD)  continue;
 
     list[n] = image[i].Mcal;
@@ -568,5 +568,5 @@
   for (i = 0; i < Nimage; i++) {
 
-    if (image[i].code & IMAGE_BAD)  continue;
+    if (image[i].flags & IMAGE_BAD)  continue;
 
     list[n] = image[i].dMcal;
Index: /branches/cnb_branch_20090215/Ohana/src/relphot/src/MosaicOps.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/relphot/src/MosaicOps.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/relphot/src/MosaicOps.c	(revision 21536)
@@ -68,5 +68,5 @@
     mosaic[Nmosaic].dMcal = 0.0;
     mosaic[Nmosaic].Xm    = 0.0;
-    mosaic[Nmosaic].code  = image[i].code;
+    mosaic[Nmosaic].flags  = image[i].flags;
     mosaic[Nmosaic].secz  = image[i].secz;
 
@@ -183,6 +183,6 @@
       image[im].dMcal = mosaic[i].dMcal;
       image[im].Xm = mosaic[i].Xm;
-      image[im].code |= (mosaic[i].code & ID_IMAGE_FEW);
-      image[im].code |= (mosaic[i].code & ID_IMAGE_POOR);
+      image[im].flags |= (mosaic[i].flags & ID_IMAGE_FEW);
+      image[im].flags |= (mosaic[i].flags & ID_IMAGE_POOR);
     }
   }      
@@ -306,5 +306,5 @@
   if (i == -1) return (NAN);
 
-  if (mosaic[i].code & IMAGE_BAD) return (NAN);  
+  if (mosaic[i].flags & IMAGE_BAD) return (NAN);  
   value = mosaic[i].Mcal;
   return (value);
@@ -343,5 +343,5 @@
     /* on PoorImages run, skip good images */
     if (PoorImages) {
-      bad = mosaic[i].code & (ID_IMAGE_FEW | ID_IMAGE_POOR | ID_IMAGE_SKIP);
+      bad = mosaic[i].flags & (ID_IMAGE_FEW | ID_IMAGE_POOR | ID_IMAGE_SKIP);
       if (!bad) continue;
     }      
@@ -393,8 +393,8 @@
       if (mark) {
 	fprintf (stderr, "marked image %s (%d), (%d < %d) || (%d < %f*%d)\n", image[imlist[i][0]].name, i, N, IMAGE_TOOFEW, N, IMAGE_GOOD_FRACTION, Nlist[i]);
-	mosaic[i].code |= ID_IMAGE_FEW;
+	mosaic[i].flags |= ID_IMAGE_FEW;
 	Nfew ++;
       } else {
-	mosaic[i].code &= ~ID_IMAGE_FEW;
+	mosaic[i].flags &= ~ID_IMAGE_FEW;
       }
     }
@@ -434,5 +434,5 @@
   n = 0;
   for (i = 0; i < Nmosaic; i++) {
-    if (mosaic[i].code & IMAGE_BAD) continue;
+    if (mosaic[i].flags & IMAGE_BAD) continue;
     list[n] = mosaic[i].Mcal;
     dlist[n] = 1;
@@ -462,5 +462,5 @@
   for (i = 0; i < Nmosaic; i++) {
 
-    if (mosaic[i].code & IMAGE_BAD) continue;
+    if (mosaic[i].flags & IMAGE_BAD) continue;
     list[n] = mosaic[i].dMcal;
     dlist[n] = 1;
@@ -490,5 +490,5 @@
   n = 0;
   for (i = 0; i < Nmosaic; i++) {
-    if (mosaic[i].code & IMAGE_BAD)  continue;
+    if (mosaic[i].flags & IMAGE_BAD)  continue;
 
     N = 0;
@@ -534,5 +534,5 @@
   for (i = 0; i < Nmosaic; i++) {
 
-    if (mosaic[i].code & IMAGE_BAD) continue;
+    if (mosaic[i].flags & IMAGE_BAD) continue;
     list[n] = pow(10.0, 0.01*mosaic[i].Xm);
     dlist[n] = 1;
@@ -564,5 +564,5 @@
 
   for (i = N = 0; i < Nmosaic; i++) {
-    if (mosaic[i].code & IMAGE_BAD) continue;
+    if (mosaic[i].flags & IMAGE_BAD) continue;
     mlist[N] = mosaic[i].Mcal;
     slist[N] = mosaic[i].dMcal;
@@ -584,7 +584,7 @@
     if (mark) { 
       Nmark ++;
-      mosaic[i].code |= ID_IMAGE_POOR;
+      mosaic[i].flags |= ID_IMAGE_POOR;
     } else {
-      mosaic[i].code &= ~ID_IMAGE_POOR;
+      mosaic[i].flags &= ~ID_IMAGE_POOR;
     }
   }
Index: /branches/cnb_branch_20090215/Ohana/src/relphot/src/StarOps.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/relphot/src/StarOps.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/relphot/src/StarOps.c	(revision 21536)
@@ -26,5 +26,5 @@
 
   ave = catalog[cat].measure[meas].averef;
-  if (catalog[cat].average[ave].code & STAR_BAD) return (NAN);  
+  if (catalog[cat].average[ave].flags & STAR_BAD) return (NAN);  
  
   value = catalog[cat].secfilt[PhotNsec*ave+PhotSec].M;
@@ -44,5 +44,5 @@
 
       /* calculate the average value for a single star */
-      if (catalog[i].average[j].code & STAR_BAD) continue;  
+      if (catalog[i].average[j].flags & STAR_BAD) continue;  
       m = catalog[i].average[j].measureOffset;
 
@@ -89,8 +89,8 @@
 
       if (N <= STAR_TOOFEW) { /* too few measurements */
-	catalog[i].average[j].code |= ID_STAR_FEW;
+	catalog[i].average[j].flags |= ID_STAR_FEW;
 	Nfew ++;
       } else {
-	catalog[i].average[j].code &= ~ID_STAR_FEW;
+	catalog[i].average[j].flags &= ~ID_STAR_FEW;
       }	
 
@@ -208,5 +208,5 @@
 
 	  // XXX this is a hack for the 2MASS search; better to save an average value?
-	  if (catalog[i].measure[m].qPSF < 0.85) continue;
+	  if (catalog[i].measure[m].psfQual < 0.85) continue;
 
 	  list[N] = Msys - catalog[i].measure[m].Mcal;
@@ -280,5 +280,5 @@
   for (i = Ntot = 0; i < Ncatalog; i++) {
     for (j = 0; j < catalog[i].Naverage; j++) {
-      if (catalog[i].average[j].code & STAR_BAD) continue;
+      if (catalog[i].average[j].flags & STAR_BAD) continue;
       Xm = catalog[i].secfilt[PhotNsec*j+PhotSec].Xm;
       if (Xm == -1) continue;
@@ -306,8 +306,8 @@
       mark = (dM > MaxScatter) || (Xm == NAN_S_SHORT) || (Chisq > MaxChisq);
       if (mark) {
-	catalog[i].average[j].code |= ID_STAR_POOR;
+	catalog[i].average[j].flags |= ID_STAR_POOR;
 	Ndel ++;
       } else {
-	catalog[i].average[j].code &= ~ID_STAR_POOR;
+	catalog[i].average[j].flags &= ~ID_STAR_POOR;
       }
       Nave ++;
@@ -351,5 +351,5 @@
 
       /* skip bad stars to prevent them from becoming good (on inner sample) */
-      if (catalog[i].average[j].code & STAR_BAD) continue;  
+      if (catalog[i].average[j].flags & STAR_BAD) continue;  
 
       /* on final processing, skip stars already measured */
@@ -448,5 +448,5 @@
 
       /* calculate the average value for a single star */
-      if (catalog[i].average[j].code & STAR_BAD) continue;  
+      if (catalog[i].average[j].flags & STAR_BAD) continue;  
       m = catalog[i].average[j].measureOffset;
 
@@ -493,5 +493,5 @@
 
       /* calculate the average value for a single star */
-      if (catalog[i].average[j].code & STAR_BAD) continue;  
+      if (catalog[i].average[j].flags & STAR_BAD) continue;  
 
       Xm = catalog[i].secfilt[PhotNsec*j+PhotSec].Xm;
@@ -529,5 +529,5 @@
 
       /* calculate the average value for a single star */
-      if (catalog[i].average[j].code & STAR_BAD) continue;  
+      if (catalog[i].average[j].flags & STAR_BAD) continue;  
 
       dM = catalog[i].secfilt[PhotNsec*j+PhotSec].dM;
@@ -559,5 +559,5 @@
   for (i = 0; i < Ncatalog; i++) {
     for (j = 0; j < catalog[i].Naverage; j++) {
-      if (catalog[i].average[j].code & STAR_BAD) continue;  
+      if (catalog[i].average[j].flags & STAR_BAD) continue;  
       dMrel = catalog[i].secfilt[PhotNsec*j+PhotSec].dM;
       bin = dMrel / 0.00025;
@@ -590,5 +590,5 @@
   for (i = 0; i < Ncatalog; i++) {
     for (j = 0; j < catalog[i].Naverage; j++) {
-      if (catalog[i].average[j].code & STAR_BAD) continue;
+      if (catalog[i].average[j].flags & STAR_BAD) continue;
       xlist[N] = catalog[i].secfilt[PhotNsec*j+PhotSec].M;
       value    = catalog[i].secfilt[PhotNsec*j+PhotSec].Xm;
Index: /branches/cnb_branch_20090215/Ohana/src/relphot/src/bcatalog.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/relphot/src/bcatalog.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/relphot/src/bcatalog.c	(revision 21536)
@@ -34,6 +34,6 @@
       subcatalog[0].secfilt[PhotNsec*Naverage+PhotSec].M  = NAN;
       subcatalog[0].secfilt[PhotNsec*Naverage+PhotSec].dM = NAN;
-      subcatalog[0].average[Naverage].code &= ~ID_STAR_FEW;
-      subcatalog[0].average[Naverage].code &= ~ID_STAR_POOR;
+      subcatalog[0].average[Naverage].flags &= ~ID_STAR_FEW;
+      subcatalog[0].average[Naverage].flags &= ~ID_STAR_POOR;
     }
 
@@ -55,5 +55,6 @@
       /* select measurements by quality */
       // XXX ignore this criterion for REF measurements?
-      if (DophotSelect && (catalog[0].measure[offset].dophot != DophotValue)) continue;
+      // XXX chnage this to select by bitflags
+      if (DophotSelect && ((catalog[0].measure[offset].photFlags >> 16) != DophotValue)) continue;
 
       /* select measurements by mag limit */
Index: /branches/cnb_branch_20090215/Ohana/src/relphot/src/plot_scatter.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/relphot/src/plot_scatter.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/relphot/src/plot_scatter.c	(revision 21536)
@@ -23,5 +23,5 @@
 
       /* calculate the average value for a single star */
-      if (catalog[i].average[j].code & STAR_BAD) continue;  
+      if (catalog[i].average[j].flags & STAR_BAD) continue;  
       m = catalog[i].average[j].measureOffset;
 
Index: /branches/cnb_branch_20090215/Ohana/src/relphot/src/relphot_objects.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/relphot/src/relphot_objects.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/relphot/src/relphot_objects.c	(revision 21536)
@@ -42,12 +42,13 @@
       Nsecfilt = catalog.Nsecfilt;
       for (j = 0; j < catalog.Naverage; j++) {
-	catalog.average[j].code = 0;
+	catalog.average[j].flags = 0;
 	for (k = 0; k < Nsecfilt; k++) {
-	  catalog.secfilt[j*Nsecfilt + k].M  = NAN;
-	  catalog.secfilt[j*Nsecfilt + k].dM = NAN;
-	  catalog.secfilt[j*Nsecfilt + k].Xm = NAN_S_SHORT;
+	  catalog.secfilt[j*Nsecfilt + k].M    	= NAN;
+	  catalog.secfilt[j*Nsecfilt + k].M_20 	= NAN_S_SHORT;
+	  catalog.secfilt[j*Nsecfilt + k].M_80 	= NAN_S_SHORT;
+	  catalog.secfilt[j*Nsecfilt + k].dM   	= NAN;
+	  catalog.secfilt[j*Nsecfilt + k].Xm    = NAN_S_SHORT;
 	  catalog.secfilt[j*Nsecfilt + k].Ncode = 0;
 	  catalog.secfilt[j*Nsecfilt + k].Nused = 0;
-	  catalog.secfilt[j*Nsecfilt + k].dummy = 0;
 	}
 	m = catalog.average[j].measureOffset;
Index: /branches/cnb_branch_20090215/Ohana/src/relphot/src/select_images.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/relphot/src/select_images.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/relphot/src/select_images.c	(revision 21536)
@@ -133,11 +133,11 @@
       image[nimage] = timage[i]; 
       /* always allow 'few' images to succeed, if possible */
-      if (image[nimage].code & ID_IMAGE_FEW) { 
-	image[nimage].code &= ~(ID_IMAGE_FEW | ID_IMAGE_POOR);
+      if (image[nimage].flags & ID_IMAGE_FEW) { 
+	image[nimage].flags &= ~(ID_IMAGE_FEW | ID_IMAGE_POOR);
       }
       if (RESET) {
 	assignMcal (&image[nimage], (double *) NULL, -1);
 	image[nimage].dMcal = NAN;
-	image[nimage].code &= ~ID_IMAGE_POOR;
+	image[nimage].flags &= ~ID_IMAGE_POOR;
       }
       line_number[nimage] = i;
Index: /branches/cnb_branch_20090215/Ohana/src/relphot/src/setMrelFinal.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/relphot/src/setMrelFinal.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/relphot/src/setMrelFinal.c	(revision 21536)
@@ -54,6 +54,6 @@
   /* clear ID_STAR_POOR, ID_STAR_FEW, ID_MEAS_NOCAL values before writing ??? */
   for (i = 0; i < catalog[0].Naverage; i++) {
-    catalog[0].average[i].code &= ~ID_STAR_FEW;
-    catalog[0].average[i].code &= ~ID_STAR_POOR;
+    catalog[0].average[i].flags &= ~ID_STAR_FEW;
+    catalog[0].average[i].flags &= ~ID_STAR_POOR;
     m = catalog[0].average[i].measureOffset;
     for (j = 0; j < catalog[0].average[i].Nmeasure; j++, m++) {
@@ -102,5 +102,6 @@
 
       /* skip measurements with sat. dophot values */
-      if ((pass < 4) && (catalog[0].measure[m].dophot == 10)) goto skip;
+      // XXX we need to fix this: use the photFlags to ID saturation...
+      // if ((pass < 4) && (catalog[0].measure[m].dophot == 10)) goto skip;
 
       /* skip measurements from BAD images and mosaics */
@@ -116,6 +117,8 @@
       }
 
-      d1 = (catalog[0].measure[m].dophot == 1);
-      d2 = (catalog[0].measure[m].dophot == 2);
+      // d1 = (catalog[0].measure[m].dophot == 1);
+      // d2 = (catalog[0].measure[m].dophot == 2);
+      fprintf (stderr, "fix the dophot / type selections!");
+      abort ();
 
       /* skip measurements by measurement error */
Index: /branches/cnb_branch_20090215/Ohana/src/uniphot/src/find_image_sgroups.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/uniphot/src/find_image_sgroups.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/uniphot/src/find_image_sgroups.c	(revision 21536)
@@ -27,5 +27,5 @@
   for (i = 0; i < Nimage; i++) {
     if (imlink[i].sgroup != NULL) continue;
-    if (image[i].code & ID_IMAGE_NOCAL) continue;
+    if (image[i].flags & ID_IMAGE_NOCAL) continue;
 
     /* new sgroup, set ref coords */
@@ -52,5 +52,5 @@
 
     for (j = 0; j < Nimage; j++) {
-      if (image[j].code & ID_IMAGE_NOCAL) continue;
+      if (image[j].flags & ID_IMAGE_NOCAL) continue;
       if (imlink[j].sgroup != NULL) continue;
 
Index: /branches/cnb_branch_20090215/Ohana/src/uniphot/src/find_image_tgroups.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/uniphot/src/find_image_tgroups.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/uniphot/src/find_image_tgroups.c	(revision 21536)
@@ -63,5 +63,5 @@
       if (image[j].tzero < tmin[i]) continue;
       if (image[j].tzero > tmax[i]) continue;
-      if (image[j].code & ID_IMAGE_NOCAL) continue;
+      if (image[j].flags & ID_IMAGE_NOCAL) continue;
       
       group[i].image[Nentry] = &image[j];
Index: /branches/cnb_branch_20090215/Ohana/src/uniphot/src/fit_groups.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/uniphot/src/fit_groups.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/uniphot/src/fit_groups.c	(revision 21536)
@@ -16,5 +16,5 @@
   for (i = 0; i < Ntgroup; i++) {
     for (j = Nlist = 0; j < tgroup[i].Nimage; j++) {
-      if (tgroup[i].image[j][0].code & IMAGE_BAD) continue;
+      if (tgroup[i].image[j][0].flags & IMAGE_BAD) continue;
       sgroup = (Group *) tgroup[i].imlink[j][0].sgroup;
       Mcal = tgroup[i].image[j][0].Mcal;
@@ -54,5 +54,5 @@
   for (i = 0; i < Nsgroup; i++) {
     for (j = Nlist = 0; j < sgroup[i].Nimage; j++) {
-      if (sgroup[i].image[j][0].code & IMAGE_BAD) continue;
+      if (sgroup[i].image[j][0].flags & IMAGE_BAD) continue;
       tgroup = (Group *) sgroup[i].imlink[j][0].tgroup;
       Mcal = sgroup[i].image[j][0].Mcal;
Index: /branches/cnb_branch_20090215/Ohana/src/uniphot/src/subset_images.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/uniphot/src/subset_images.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/uniphot/src/subset_images.c	(revision 21536)
@@ -16,5 +16,5 @@
   for (i = 0; i < Nimage; i++) {
       
-    image[i].code |= ID_IMAGE_NOCAL;
+    image[i].flags |= ID_IMAGE_NOCAL;
 
     /* select images by photcode */
@@ -27,5 +27,5 @@
       if (image[i].tzero > TSTOP) continue;
     }
-    image[i].code &= ~ID_IMAGE_NOCAL;
+    image[i].flags &= ~ID_IMAGE_NOCAL;
     keep[Nkeep] = i;
     Nkeep ++;
Index: /branches/cnb_branch_20090215/Ohana/src/uniphot/src/update.c
===================================================================
--- /branches/cnb_branch_20090215/Ohana/src/uniphot/src/update.c	(revision 21535)
+++ /branches/cnb_branch_20090215/Ohana/src/uniphot/src/update.c	(revision 21536)
@@ -16,5 +16,5 @@
   /* clear the NOCAL flags */
   for (i = 0; i < Nimage; i++) {
-    image[i].code &= ~ID_IMAGE_NOCAL;
+    image[i].flags &= ~ID_IMAGE_NOCAL;
   }
 
Index: /branches/cnb_branch_20090215/doc/design/distrib.v0.txt
===================================================================
--- /branches/cnb_branch_20090215/doc/design/distrib.v0.txt	(revision 21536)
+++ /branches/cnb_branch_20090215/doc/design/distrib.v0.txt	(revision 21536)
@@ -0,0 +1,160 @@
+
+Releasing GPC1 images
+
+This note discusses the process of preparing GPC1 images for release and distributing the
+data to the PS1 Science Consortium.
+
+There are a number of somewhat unique features of the PS1 project that must be considered
+
+   1. The requirement that satellite streaks be masked in the images
+   2. The massive size of the data
+   3. The fact that the data is stored inside secure facility at MHPCC
+
+The note is rather free form. Lines marked with '*' indicate tasks that need to get
+done to complete this project.
+
+Magic Masking
+-------------
+
+All images to be released must be run through the magic destreaking process. In this process
+difference images are examined for potential satellite streaks and pixels along the line
+of the streaks and are removed from the images. For the raw images the excised pixels are
+saved so that the complete original images may be recovered if necessary.
+
+Additionally those pixels that were not included in the science and magic analyses
+must be masked because they may contain undeteced satellite streaks.
+This masking is not performed as part of the magic process so that they may be included in
+subsequent analysis inside the IPP system.  This masking is applied to images as part of the
+release process.
+
+
+De-streaking
+--------------------
+
+A pantasks task is needed that runs periodicaly to queue destreaking runs with the command
+magicdstool -definebyquery  (this mode does not exist yet and thus needs to be coded)
+
+* Create the pantasks 'destreak' task
+* Create the magicdstool -definebyquery mode
+
+A pantasks task performs the destreaking operations replacing the images in the nebulous database
+with the destreaked versions. The original images are deleted and a flag is set in the
+images' row in the corresponding database table that indicates that magic has been performed.
+
+Once the destreaking runs are complete the images are ready for release processing.
+
+Releasing images
+----------------
+
+The release processing consists of the following steps
+
+   1. identify those data that are to be prepared for release
+   2. the 'excise the masked pixel' step for science images
+   3. build DataStore file sets containing the images and any other data products (.cmf files, psf etc)
+
+This process is very similar to the processing done by the Postage Stamp server and so it makes sense
+to build upon that request processing system.
+
+* We need to be able to specify criteria for what science images are to be released.
+
+For example, do we only release raw and processed detrend images?
+Do we release chip processed or warp images from certain surveys? (The Pan planets team has
+shown an interest in analyzing the chip level images).
+
+* We need a task that applies the criteria and creates 'get_image' type postage stamp request.
+pstamptool -definebyquery ?
+(* this mode does not currently exist. Postage stamp jobs are specified
+by a request file which is externally prepared and then referenced by the db. The request file is
+parsed into a set of zero or more jobs. It probably makes sense to have the capability to skip the
+request file step and create the jobs directly.)
+
+* We need to define how we organize the data into Data Store products and file sets.
+
+We have a whole lot of data. The DataStore only has 3 levels of hierarchy
+   root
+       product
+           filesetA1
+               file
+               file
+           filesetA2
+               file
+               file
+       productB
+           filesetB2
+           etc.
+
+We probably want to have filesets correspond to exposures. To keep the products from getting too
+long, we may want to divide up the products by date.
+
+Perhaps something like:
+product    20081106_4776
+fileset       o4776g0144o_raw
+file             o4776g0144o.ota01.fits
+
+
+Since these data will quickly get large, (we don't have storage space budgeted for a complete second
+copy of the data):
+
+* We need to be able to purge release file sets based on some criteria.
+
+* For images that are being released in order to create a backup copy, it would make sense to get
+notification from MPG that the images have been successfully transferred. Need a mechanism for that.
+
+* The data store needs to be able to recognize and report to users when requested file sets
+are no longer available because they have been purged.
+
+
+Presentation and data delivery
+------------------------------
+The primary interface to the data is through the Data Store. The data store is implementated
+as cgi scripts exectuted by an apache web server.
+
+Since we do not have space in Manoa to store the images here we need to leave them at MHPCC.
+Since the network there is restricted we will need to provide a reverse proxy server in
+Manoa which will forward the requests to the apache server(s) on Maui.
+
+* We need to restrict access to the data store by user. Perhaps by product?
+
+* We need to log bandwith used by these users had have the ability to control throttle usage to
+insure that the primary users are serviced.
+
+XXXX The following isn't very thought out. There are two issues I'm trying to solve at once.
+   1. Maximizing bandwidth for data transfer.
+   2. Simplifying the client interface.
+
+The standard data store use pattern is for users to query the product list for new file sets
+and then copy the files with HTTP GET requests. This method is used by the IPP for the summit
+copy process. This method has the drawback that the client must handle any exceptional situations
+and manage errors and retries when necessary.
+
+* It might be more efficient to supply an rsync server interface to the data repository. This program
+already implements error correction features, detection of differnces between the source and
+destination, etc.
+
+We would need to provide a reverse proxy server in manoa to handle forward the rsync
+procotol requests to maui.
+
+On the other hand for efficiency we probably want to distribute the data store's files among
+a set of nodes.  (This would make the rsync solution problematic.)
+This way we could use a set of apache servers and redirect the requests to the various nodes.
+Perhaps we would need a set of reverse proxy servers in manoa as well.
+
+
+"Mirror of data at MPG"
+-----------------------
+
+The destreaked raw images will be copied to the MPG cluster in Garching to serve as a backup and
+a source for analysis there.
+
+It will be very confusing to have different database ids for the images located there.
+We need a way to copy the database tables for the images so that they can be preserved.
+
+It has been suggested that what might be done is to copy the database and
+set all of the processed image entries to 'cleaned'. Then they could be regenerated using 'update'.
+
+* We would need to provide the metadata config dump of the configuration that was used to process
+the images.
+
+* Will it be a problem that the reprocessing is done with the streak and masked pixels removed?
+
+* Perhaps we could provide the database dump and the config files as part of the raw image transfer
Index: /branches/cnb_branch_20090215/doc/design/remote.copy.txt
===================================================================
--- /branches/cnb_branch_20090215/doc/design/remote.copy.txt	(revision 21536)
+++ /branches/cnb_branch_20090215/doc/design/remote.copy.txt	(revision 21536)
@@ -0,0 +1,123 @@
+
++ The data will be copied in batches which represent a single entry in
+  a single stage.  This means, eg, a single chipRun, a single rawExp, or
+  a single warpRun, etc.
+
++ We need hand-shaking between the source and target sites.
+
++ Data Store:
+
+  product: distribution (restricted access)
+    fileset: chipRun chip_id
+      files....
+
++ remote copy system includes these stages:
+
+  1) rc_getstages
+
+     query the source datastore for stages to fetch
+     + this may use the last-seen entry to query for only the new
+       entries
+
+     insert the new stages into rcDownloadStage
+
+  2) rc_copystage
+
+     for a single rcDownloadStage entry, download the complete fileset 
+
+     * we can do this with the wget command to ensure the full set is
+       downloaded, and allow for retries
+
+     * the result files should be placed in a local temporary
+       location.
+
+     insert the downloaded data into the local database:
+
+     * check the database version in the manifest
+       - if it is not equal to the current version, raise an error
+
+     * create nebulous entries for each of the files
+       - for each file in the manifest, create the single nebulous
+         entry and copy the file to the corresponding instance.
+       - allow the remote site to replicate entries at this time
+     
+     * execute the SQL db update code 
+
+     * update the rcDownloadStage entry
+
+     * post an entry on our datastore to acknowledge success or
+       failure
+
+     * on success insert the stage info into our upload tables.
+
+----------  
+
+rc_manifest:
+
+STAGE:
+ID:
+DB_VERSION : version number of source database 
+DB_DATA : filename.sql
+NUMBER OF FILES : NNN
+# neb name                              ==>  bundle name
+neb://path/name/o4541g0012o.ota11.fits  ==>  o4541g0012o.ota11.fits
+neb://path/name/o4541g0012o.ota12.fits  ==>  o4541g0012o.ota12.fits
+neb://path/name/o4541g0012o.ota13.fits  ==>  o4541g0012o.ota13.fits
+
+-----------
+
+database tables:
+
+rcDownloadStage:
+  id
+  ds_entry
+  stage (needed here?)
+  fileset uri
+  state
+  fault
+
+rcDistributeStage
+  id
+  stage
+  fileset uri
+  destination
+  state
+  
+------------
+
+once the rcDistributeStage is built, we need a task to monitor for
+successful download by the destination system.  Here are the tasks
+needed:
+
+1) build a book of remote destinations (static book loaded from
+   config?)
+
+2) for each remote destination, examine the remote datastore
+   (PRODUCT name needed for download results)
+
+   * we need to track the last seen entry 
+   ** we need this information for several systems: summit copy,
+      remote copy, distribute
+
+   for each new entry, update rcDistributeStage with new state
+   (success / failure)
+
+------------
+
+build the rcDistributeStage table entries:
+
+new entries to be distributed should be added after the data is (a)
+identified to be distributed, and (b) a distribution bundle is
+generated.
+
+* Does this replicate PStamp server tables / interfaces?
+
+Steps to do (run for each of the distributed stages)
+
+1) identify the entries in the stage to be distributed:
+   * entry meets the needed condition (exists, is 'full', is magicked
+   -- this last may be optional depending on the data source).  
+
+   * entry is not in the rcDistributeStage
+
+2) do work 
Index: /branches/cnb_branch_20090215/ippTools/share/Makefile.am
===================================================================
--- /branches/cnb_branch_20090215/ippTools/share/Makefile.am	(revision 21535)
+++ /branches/cnb_branch_20090215/ippTools/share/Makefile.am	(revision 21536)
@@ -21,4 +21,6 @@
      chiptool_revertprocessedimfile.sql \
      chiptool_run.sql \
+     chiptool_export_run.sql \
+     chiptool_export_imfiles.sql \
      chiptool_unmasked.sql \
      detselect_search.sql \
Index: /branches/cnb_branch_20090215/ippTools/share/chiptool_export_imfiles.sql
===================================================================
--- /branches/cnb_branch_20090215/ippTools/share/chiptool_export_imfiles.sql	(revision 21536)
+++ /branches/cnb_branch_20090215/ippTools/share/chiptool_export_imfiles.sql	(revision 21536)
@@ -0,0 +1,3 @@
+SELECT
+    chipProcessedImfile.*
+FROM chipProcessedImfile
Index: /branches/cnb_branch_20090215/ippTools/share/chiptool_export_run.sql
===================================================================
--- /branches/cnb_branch_20090215/ippTools/share/chiptool_export_run.sql	(revision 21536)
+++ /branches/cnb_branch_20090215/ippTools/share/chiptool_export_run.sql	(revision 21536)
@@ -0,0 +1,3 @@
+SELECT
+    chipRun.*
+FROM chipRun
Index: /branches/cnb_branch_20090215/ippTools/src/chiptool.c
===================================================================
--- /branches/cnb_branch_20090215/ippTools/src/chiptool.c	(revision 21535)
+++ /branches/cnb_branch_20090215/ippTools/src/chiptool.c	(revision 21536)
@@ -54,4 +54,6 @@
 static bool tofullimfileMode(pxConfig *config);
 static bool topurgedimfileMode(pxConfig *config);
+static bool exportrunMode(pxConfig *config);
+static bool importrunMode(pxConfig *config);
 
 # define MODECASE(caseName, func) \
@@ -91,4 +93,6 @@
         MODECASE(CHIPTOOL_MODE_TOFULLIMFILE,            tofullimfileMode);
         MODECASE(CHIPTOOL_MODE_TOPURGEDIMFILE,          topurgedimfileMode);
+        MODECASE(CHIPTOOL_MODE_EXPORTRUN,               exportrunMode);
+        MODECASE(CHIPTOOL_MODE_IMPORTRUN,               importrunMode);
         default:
             psAbort("invalid option (this should not happen)");
@@ -880,5 +884,4 @@
 }
 
-
 static bool pendingcleanupimfileMode(pxConfig *config)
 {
@@ -1005,5 +1008,4 @@
     return true;
 }
-
 
 static bool runMode(pxConfig *config)
@@ -1251,2 +1253,165 @@
     return change_imfile_data_state(config, "purged", "goto_purged");
 }
+
+bool exportrunMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, NULL);
+
+    PXOPT_LOOKUP_S64(chip_id, config->args, "-chip_id", true,  false);
+    PXOPT_LOOKUP_STR(outfile, config->args, "-outfile", true,  false);
+    PXOPT_LOOKUP_U64(limit,   config->args, "-limit",   false, false);
+
+    FILE *f = fopen (outfile, "w");
+    if (f == NULL) {
+        psError(PS_ERR_UNKNOWN, false, "failed to open output file");
+        return false;
+    }
+
+    psMetadata *where = psMetadataAlloc();
+    PXOPT_COPY_S64(config->args, where, "-chip_id", "chip_id", "==");
+
+    // *** extract the chipRun in this section ***
+    psString query = pxDataGet("chiptool_export_run.sql");
+    if (!query) {
+        psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
+        return false;
+    }
+
+    if (where && psListLength(where->list)) {
+        psString whereClause = psDBGenerateWhereSQL(where, NULL);
+        psStringAppend(&query, " %s", whereClause);
+        psFree(whereClause);
+    }
+
+    // treat limit == 0 as "no limit"
+    if (limit) {
+        psString limitString = psDBGenerateLimitSQL(limit);
+        psStringAppend(&query, " %s", limitString);
+        psFree(limitString);
+    }
+
+    if (!p_psDBRunQuery(config->dbh, query)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        psFree(query);
+        return false;
+    }
+    psFree(query);
+
+    psArray *output = p_psDBFetchResult(config->dbh);
+    if (!output) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        return false;
+    }
+    if (!psArrayLength(output)) {
+        psTrace("chiptool", PS_LOG_INFO, "no rows found");
+        psFree(output);
+        return true;
+    }
+
+    // we must write the export table in non-simple (true) format
+    if (!ippdbPrintMetadatas(f, output, "chipRun", true)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to print array");
+        psFree(output);
+        return false;
+    }
+    psFree(output);
+
+    // *** extract the chipProcessedImfile entries in this section ***
+    query = pxDataGet("chiptool_export_imfiles.sql");
+    if (!query) {
+        psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
+        return false;
+    }
+
+    if (where && psListLength(where->list)) {
+        psString whereClause = psDBGenerateWhereSQL(where, NULL);
+        psStringAppend(&query, " %s", whereClause);
+        psFree(whereClause);
+    }
+    psFree(where);
+
+    // treat limit == 0 as "no limit"
+    if (limit) {
+        psString limitString = psDBGenerateLimitSQL(limit);
+        psStringAppend(&query, " %s", limitString);
+        psFree(limitString);
+    }
+
+    if (!p_psDBRunQuery(config->dbh, query)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        psFree(query);
+        return false;
+    }
+    psFree(query);
+
+    output = p_psDBFetchResult(config->dbh);
+    if (!output) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        return false;
+    }
+    if (!psArrayLength(output)) {
+        psTrace("chiptool", PS_LOG_INFO, "no rows found");
+        psFree(output);
+        return true;
+    }
+
+    // we must write the export table in non-simple (true) format
+    if (!ippdbPrintMetadatas(f, output, "chipProcessedImfiles", true)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to print array");
+        psFree(output);
+        return false;
+    }
+    psFree(output);
+
+    fclose (f);
+
+    return true;
+}
+
+
+bool importrunMode(pxConfig *config)
+{
+  unsigned int nFail;
+
+  PS_ASSERT_PTR_NON_NULL(config, NULL);
+  
+  PXOPT_LOOKUP_STR(infile, config->args, "-infile", true,  false);
+
+  psMetadata *input = psMetadataConfigRead (NULL, &nFail, infile, false);
+
+  fprintf (stdout, "---- input ----\n");
+  psMetadataPrint (stderr, input, 1);
+
+  psMetadataItem *chipRunItem = psMetadataLookup (input, "chipRun");
+  psAssert (chipRunItem, "entry not in input?");
+  psAssert (chipRunItem->type == PS_DATA_METADATA_MULTI, "entry not multi?");
+  
+  psMetadataItem *chipRunEntry = psListGet (chipRunItem->data.list, 0);
+  assert (chipRunEntry);
+  assert (chipRunEntry->type == PS_DATA_METADATA);
+  chipRunRow *chipRun = chipRunObjectFromMetadata (chipRunEntry->data.md);
+  chipRunInsertObject (config->dbh, chipRun);
+
+  // fprintf (stdout, "---- chip run ----\n");
+  // psMetadataPrint (stderr, chipRunEntry->data.md, 1);
+
+  psMetadataItem *item = psMetadataLookup (input, "chipProcessedImfiles");
+  psAssert (item, "entry not in input?");
+  psAssert (item->type == PS_DATA_METADATA_MULTI, "entry not multi?");
+
+  // XXX would be better to use the iterator?
+  for (int i = 0; i < item->data.list->n; i++) {
+    psMetadataItem *entry = psListGet (item->data.list, i);
+    assert (entry);
+    assert (entry->type == PS_DATA_METADATA);
+    chipProcessedImfileRow *chipProcessedImfile = chipProcessedImfileObjectFromMetadata (entry->data.md);
+    chipProcessedImfileInsertObject (config->dbh, chipProcessedImfile);
+
+    // fprintf (stdout, "---- row %d ----\n", i);
+    // psMetadataPrint (stderr, entry->data.md, 1);
+  }
+
+  return true;
+}
+
+
Index: /branches/cnb_branch_20090215/ippTools/src/chiptool.h
===================================================================
--- /branches/cnb_branch_20090215/ippTools/src/chiptool.h	(revision 21535)
+++ /branches/cnb_branch_20090215/ippTools/src/chiptool.h	(revision 21536)
@@ -44,5 +44,7 @@
     CHIPTOOL_MODE_TOCLEANEDIMFILE,
     CHIPTOOL_MODE_TOFULLIMFILE,
-    CHIPTOOL_MODE_TOPURGEDIMFILE
+    CHIPTOOL_MODE_TOPURGEDIMFILE,
+    CHIPTOOL_MODE_EXPORTRUN,
+    CHIPTOOL_MODE_IMPORTRUN
 } chiptoolMode;
 
Index: /branches/cnb_branch_20090215/ippTools/src/chiptoolConfig.c
===================================================================
--- /branches/cnb_branch_20090215/ippTools/src/chiptoolConfig.c	(revision 21535)
+++ /branches/cnb_branch_20090215/ippTools/src/chiptoolConfig.c	(revision 21536)
@@ -244,4 +244,15 @@
     psMetadataAddStr(topurgedimfileArgs, PS_LIST_TAIL, "-class_id",  0,        "class ID to update", NULL);
 
+    // -exportrun
+    psMetadata *exportrunArgs = psMetadataAlloc();
+    // pxchipSetSearchArgs (exportrunArgs); XXX include search terms?
+    psMetadataAddS64(exportrunArgs, PS_LIST_TAIL, "-chip_id", 0,          "export this chip ID (required)", 0);
+    psMetadataAddStr(exportrunArgs, PS_LIST_TAIL, "-outfile", 0,          "export to this file (required)", NULL);
+    psMetadataAddU64(exportrunArgs, PS_LIST_TAIL, "-limit",   0,          "limit result set to N items", 0);
+
+    // -importrun
+    psMetadata *importrunArgs = psMetadataAlloc();
+    psMetadataAddStr(importrunArgs, PS_LIST_TAIL, "-infile",  0,          "import from this file (required)", NULL);
+
     psMetadata *argSets = psMetadataAlloc();
     psMetadata *modes = psMetadataAlloc();
@@ -264,6 +275,9 @@
     PXOPT_ADD_MODE("-run",                  "show runs",                            CHIPTOOL_MODE_RUN,                  runArgs);
     PXOPT_ADD_MODE("-tocleanedimfile",      "set imfile state to cleaned",          CHIPTOOL_MODE_TOCLEANEDIMFILE,      tocleanedimfileArgs);
-    PXOPT_ADD_MODE("-tofullimfile",        "set imfile state to full",              CHIPTOOL_MODE_TOFULLIMFILE,         tofullimfileArgs);
-    PXOPT_ADD_MODE("-topurgedimfile",      "set imfile state to purged",            CHIPTOOL_MODE_TOPURGEDIMFILE,       topurgedimfileArgs);
+    PXOPT_ADD_MODE("-tofullimfile",         "set imfile state to full",              CHIPTOOL_MODE_TOFULLIMFILE,         tofullimfileArgs);
+    PXOPT_ADD_MODE("-topurgedimfile",       "set imfile state to purged",            CHIPTOOL_MODE_TOPURGEDIMFILE,       topurgedimfileArgs);
+
+    PXOPT_ADD_MODE("-exportrun",            "export run for import on other database", CHIPTOOL_MODE_EXPORTRUN, exportrunArgs);
+    PXOPT_ADD_MODE("-importrun",            "import run from metadata file",           CHIPTOOL_MODE_IMPORTRUN, importrunArgs);
 
     if (!pxGetOptions(stderr, argc, argv, config, modes, argSets)) {
Index: /branches/cnb_branch_20090215/ippconfig/gpc1/Makefile.am
===================================================================
--- /branches/cnb_branch_20090215/ippconfig/gpc1/Makefile.am	(revision 21535)
+++ /branches/cnb_branch_20090215/ippconfig/gpc1/Makefile.am	(revision 21536)
@@ -10,4 +10,5 @@
 	format_20080929.config \
 	format_20081011.config \
+	format_20090120.config \
 	format_mef.config \
 	format_relphot.config \
Index: /branches/cnb_branch_20090215/ippconfig/gpc1/psphot.config
===================================================================
--- /branches/cnb_branch_20090215/ippconfig/gpc1/psphot.config	(revision 21535)
+++ /branches/cnb_branch_20090215/ippconfig/gpc1/psphot.config	(revision 21536)
@@ -3,10 +3,6 @@
 SAVE.OUTPUT	BOOL 	TRUE
 SAVE.BACKMDL	BOOL 	TRUE
-#SAVE.RESID	BOOL 	TRUE
-#SAVE.BACKGND	BOOL 	TRUE
-#SAVE.BACKSUB	BOOL 	TRUE
-#SAVE.PSF	BOOL 	TRUE
-#LOAD.PSF	BOOL 	FALSE
-#SAVE.PLOTS     	BOOL    TRUE
+SAVE.PSF	BOOL 	TRUE
+SAVE.PLOTS     	BOOL    TRUE
 
 BACKGROUND.XBIN	    S32  256            # size of background superpixels
@@ -42,10 +38,10 @@
 PSF.TREND.NY                        S32   1
 
-MOMENTS_SN_MIN      F32   30.0
+MOMENTS_SN_MIN      F32   10.0
 EXT_MIN_SN           F32  50.0           # fit galaxies above this S/N limit
 FULL_FIT_SN_LIM      F32  50.0
 AP_MIN_SN            F32  50.0
 
-OUTPUT.FORMAT       STR PS1_DEV_1
+OUTPUT.FORMAT        STR  PS1_V1
 
 PSF_SHAPE_NSIGMA     F32  3.0		 # max significance for shape variation
Index: /branches/cnb_branch_20090215/ippconfig/recipes/fitstypes.mdc
===================================================================
--- /branches/cnb_branch_20090215/ippconfig/recipes/fitstypes.mdc	(revision 21535)
+++ /branches/cnb_branch_20090215/ippconfig/recipes/fitstypes.mdc	(revision 21536)
@@ -24,5 +24,5 @@
 END
 DET_MASK	METADATA
-	BITPIX		S32	8
+	BITPIX		S32	16
 END
 DET_WEIGHT	METADATA
@@ -34,5 +34,5 @@
 END
 SKY_MASK	METADATA
-	BITPIX		S32	8
+	BITPIX		S32	16
 END
 SKY_WEIGHT	METADATA
@@ -54,5 +54,5 @@
 # Compressed mask
 COMP_MASK	METADATA
-	BITPIX		S32	8
+	BITPIX		S32	16
 	COMPRESSION	STR	PLIO
 	TILE.X		S32	0
Index: /branches/cnb_branch_20090215/ippconfig/recipes/psphot.config
===================================================================
--- /branches/cnb_branch_20090215/ippconfig/recipes/psphot.config	(revision 21535)
+++ /branches/cnb_branch_20090215/ippconfig/recipes/psphot.config	(revision 21536)
@@ -49,5 +49,5 @@
 # parameters to control the selection of the peak in the Sx,Sy plane
 MOMENTS_SCALE                       F32   0.25       
-MOMENTS_SN_MIN                      F32   100.0           # min S/N to measure moments
+MOMENTS_SN_MIN                      F32   10.0           # min S/N to measure moments
 MOMENTS_SX_MAX                      F32   50.0
 MOMENTS_SY_MAX                      F32   50.0
Index: /branches/cnb_branch_20090215/ippconfig/vysos5/camera.config
===================================================================
--- /branches/cnb_branch_20090215/ippconfig/vysos5/camera.config	(revision 21535)
+++ /branches/cnb_branch_20090215/ippconfig/vysos5/camera.config	(revision 21536)
@@ -3,6 +3,6 @@
 # File formats that we know about
 FORMATS         METADATA
+        FLIPPED STR     vysos5/format_flipped.config
         SIMPLE  STR     vysos5/format.config
-        FLIPPED STR     vysos5/format_flipped.config
 END
  
Index: /branches/cnb_branch_20090215/ippconfig/vysos5/format_flipped.config
===================================================================
--- /branches/cnb_branch_20090215/ippconfig/vysos5/format_flipped.config	(revision 21535)
+++ /branches/cnb_branch_20090215/ippconfig/vysos5/format_flipped.config	(revision 21536)
@@ -5,4 +5,5 @@
 	TELESCOP	STR	VYSOS-5
 	INSTRUME	STR	Apogee USB/Net
+	FLIPSTAT	STR	Flip/Mirror
 END
 
@@ -60,6 +61,6 @@
 	CELL.READDIR	S32	2
 	CELL.TIMESYS	STR	UTC
-	CELL.XPARITY	S32	1
-	CELL.YPARITY	S32	1
+	CELL.XPARITY	S32	-1
+	CELL.YPARITY	S32	-1
 	CHIP.XPARITY	S32	1
 	CHIP.YPARITY	S32	1
Index: /branches/cnb_branch_20090215/ippconfig/vysos5/psastro.config
===================================================================
--- /branches/cnb_branch_20090215/ippconfig/vysos5/psastro.config	(revision 21535)
+++ /branches/cnb_branch_20090215/ippconfig/vysos5/psastro.config	(revision 21536)
@@ -9,9 +9,9 @@
 # use plate-scale to make this in pixels?
 PSASTRO.GRID.OFFSET    F32     200.
-PSASTRO.GRID.SCALE     F32      50
+PSASTRO.GRID.SCALE     F32      10
 PSASTRO.GRID.NSTAR.MAX S32     800 # max stars accepted for fitting
 
-PSASTRO.MAX.NRAW      S32      1000   # max stars accepted for fitting (0 for all)
-PSASTRO.MAX.NREF      S32      5000   # max stars accepted for fitting (0 for all)
+PSASTRO.MAX.NRAW      S32       500   # max stars accepted for fitting (0 for all)
+PSASTRO.MAX.NREF      S32      2000   # max stars accepted for fitting (0 for all)
 
 # extra field for ref stars:
Index: /branches/cnb_branch_20090215/ppImage/src/ppImageArguments.c
===================================================================
--- /branches/cnb_branch_20090215/ppImage/src/ppImageArguments.c	(revision 21535)
+++ /branches/cnb_branch_20090215/ppImage/src/ppImageArguments.c	(revision 21536)
@@ -80,5 +80,5 @@
     if ((argnum = psArgumentGet(argc, argv, "-visual"))) {
         psArgumentRemove(argnum, &argc, argv);
-	psphotSetVisual (true);
+        pmVisualSetVisual(true);
     }
 
@@ -86,11 +86,11 @@
     if ((argnum = psArgumentGet(argc, argv, "-threads"))) {
         psArgumentRemove(argnum, &argc, argv);
-	int nThreads = atoi(argv[argnum]);
+        int nThreads = atoi(argv[argnum]);
         psMetadataAddS32(config->arguments, PS_LIST_TAIL, "NTHREADS", 0, "number of warp threads", nThreads);
         psArgumentRemove(argnum, &argc, argv);
 
-	// create the thread pool with number of desired threads, supplying our thread launcher function
-	// XXX need to determine the number of threads from the config data
-	psThreadPoolInit (nThreads);
+        // create the thread pool with number of desired threads, supplying our thread launcher function
+        // XXX need to determine the number of threads from the config data
+        psThreadPoolInit (nThreads);
     }
 
Index: /branches/cnb_branch_20090215/ppStack/src/ppStack.c
===================================================================
--- /branches/cnb_branch_20090215/ppStack/src/ppStack.c	(revision 21535)
+++ /branches/cnb_branch_20090215/ppStack/src/ppStack.c	(revision 21536)
@@ -74,5 +74,5 @@
     pmConfigDone();
     psLibFinalize();
-
+    pmVisualClose();
     exit(exitValue);
 }
Index: /branches/cnb_branch_20090215/ppStack/src/ppStackArguments.c
===================================================================
--- /branches/cnb_branch_20090215/ppStack/src/ppStackArguments.c	(revision 21535)
+++ /branches/cnb_branch_20090215/ppStack/src/ppStackArguments.c	(revision 21536)
@@ -176,11 +176,4 @@
     psMetadataAddF32(arguments, PS_LIST_TAIL, "-zp-star-limit", 0, "Limit on star rejection fraction for successful iteration", NAN);
     psMetadataAddF32(arguments, PS_LIST_TAIL, "-zp-star-sys", 0, "Estimated systematic error", NAN);
-    psMetadataAddBool(arguments, PS_LIST_TAIL, "-renorm", 0, "Renormalise variance maps?", false);
-    psMetadataAddStr(arguments, PS_LIST_TAIL, "-renorm-mean", 0,
-                     "Statistic for mean in renormalisation", NULL);
-    psMetadataAddStr(arguments, PS_LIST_TAIL, "-renorm-stdev", 0,
-                     "Statistic for stdev in renormalisation", NULL);
-    psMetadataAddF32(arguments, PS_LIST_TAIL, "-renorm-width", 0, "Gaussian width for renormalisation", NAN);
-    psMetadataAddS32(arguments, PS_LIST_TAIL, "-renorm-num", 0, "Number of samples for renormalisation", 0);
     psMetadataAddStr(arguments, PS_LIST_TAIL, "-temp-image", 0, "Suffix for temporary images", NULL);
     psMetadataAddStr(arguments, PS_LIST_TAIL, "-temp-mask", 0, "Suffix for temporary masks", NULL);
@@ -189,5 +182,5 @@
                       "Delete temporary files on completion?", false);
     psMetadataAddS32(arguments, PS_LIST_TAIL, "-threads", 0, "Number of threads to use", 0);
-    psMetadataAddBool(arguments, PS_LIST_TAIL, "-psphot-visual", 0, "psphot visualisation", 0);
+    psMetadataAddBool(arguments, PS_LIST_TAIL, "-visual", 0, "visualisation", 0);
 
     if (argc == 1 || !psArgumentParse(arguments, &argc, argv) || argc != 3) {
@@ -280,13 +273,4 @@
     }
 
-    if (psMetadataLookupBool(NULL, arguments, "-renorm") ||
-        psMetadataLookupBool(NULL, recipe, "RENORM")) {
-        psMetadataAddBool(arguments, PS_LIST_TAIL, "RENORM", 0, "Renormalise variance maps?", true);
-    }
-    VALUE_ARG_RECIPE_INT("-renorm-num", "RENORM.NUM", S32, 0);
-    VALUE_ARG_RECIPE_FLOAT("-renorm-width", "RENORM.WIDTH", F32);
-    valueArgRecipeStr(arguments, recipe, "-renorm-mean",  "RENORM.MEAN", recipe);
-    valueArgRecipeStr(arguments, recipe, "-renorm-stdev", "RENORM.STDEV", recipe);
-
     valueArgRecipeStr(arguments, recipe, "-temp-image",    "TEMP.IMAGE",  recipe);
     valueArgRecipeStr(arguments, recipe, "-temp-mask",     "TEMP.MASK",   recipe);
Index: /branches/cnb_branch_20090215/ppStack/src/ppStackLoop.c
===================================================================
--- /branches/cnb_branch_20090215/ppStack/src/ppStackLoop.c	(revision 21535)
+++ /branches/cnb_branch_20090215/ppStack/src/ppStackLoop.c	(revision 21536)
@@ -480,4 +480,8 @@
             psMetadataAddF32(stats, PS_LIST_TAIL, "STAMP.NUM", PS_META_DUPLICATE_OK,
                              "Number of stamps", kernels->numStamps);
+            float deconv = psMetadataLookupF32(NULL, readout->analysis,
+                                               PM_SUBTRACTION_ANALYSIS_DECONV_MAX); // Deconvolution fraction
+            psMetadataAddF32(stats, PS_LIST_TAIL, "KERNEL.DECONV", PS_META_DUPLICATE_OK,
+                             "Deconvolution fraction for kernel", deconv);
             psMetadataAddF32(stats, PS_LIST_TAIL, "PPSTACK.WEIGHTING", PS_META_DUPLICATE_OK,
                              "Weighting for image", weightings->data.F32[i]);
@@ -503,4 +507,5 @@
             psStringAppend(&name, "covariance_%d.fits", i);
             writeImage(name, hdu->header, readout->covariance->image, config);
+            pmStackVisualPlotTestImage(readout->covariance->image, name);
             psFree(name);
         }
@@ -801,4 +806,5 @@
 #ifdef TESTING
     writeImage("combined_initial.fits", NULL, outRO->image, config);
+    pmStackVisualPlotTestImage(outRO->image, "combined_initial.fits");
 #endif
 
@@ -884,4 +890,5 @@
                 psString name = NULL;           // Name of image
                 psStringAppend(&name, "inspect_%03d.fits", i);
+                pmStackVisualPlotTestImage(mask, name);
                 psFits *fits = psFitsOpen(name, "w");
                 psFree(name);
@@ -901,4 +908,5 @@
                 psString name = NULL;           // Name of image
                 psStringAppend(&name, "reject_%03d.fits", i);
+                pmStackVisualPlotTestImage(mask, name);
                 psFits *fits = psFitsOpen(name, "w");
                 psFree(name);
@@ -1034,4 +1042,5 @@
 
 #ifdef TESTING
+    pmStackVisualPlotTestImage(outRO->image, "combined_initial.fits");
     writeImage("combined_final.fits", NULL, outRO->image, config);
 #endif
@@ -1151,23 +1160,4 @@
     psLogMsg("ppStack", PS_LOG_INFO, "Stage 7 : WCS & JPEGS : %f sec", psTimerClear("PPSTACK_STEPS"));
 
-    if (psMetadataLookupBool(&mdok, recipe, "RENORM")) {
-        // Statistics for renormalisation
-        psStatsOptions renormMean = psStatsOptionFromString(psMetadataLookupStr(&mdok, recipe,
-                                                                                "RENORM.MEAN"));
-        psStatsOptions renormStdev = psStatsOptionFromString(psMetadataLookupStr(&mdok, recipe,
-                                                                                 "RENORM.STDEV"));
-        int renormNum = psMetadataLookupS32(&mdok, recipe, "RENORM.NUM"); // Number of samples
-        float renormWidth = psMetadataLookupS32(&mdok, recipe, "RENORM.WIDTH"); // Width of Gaussian phot
-        psImageMaskType maskValue = pmConfigMaskGet("BLANK", config); // Bits to mask
-        if (!pmReadoutVarianceRenormPhot(outRO, maskValue, renormNum, renormWidth,
-                                         renormMean, renormStdev, NULL)) {
-            psError(PS_ERR_UNKNOWN, false, "Unable to renormalise variances.");
-            psFree(outRO);
-            return false;
-        }
-    }
-
-    psLogMsg("ppStack", PS_LOG_INFO, "Stage 8 : Photometry Renormalization : %f sec", psTimerClear("PPSTACK_STEPS"));
-
     if (psMetadataLookupBool(&mdok, recipe, "PHOTOMETRY")) {
         psTrace("ppStack", 1, "Photometering stacked image....\n");
@@ -1199,5 +1189,5 @@
     }
 
-    psLogMsg("ppStack", PS_LOG_INFO, "Stage 9 : Photometry Analysis : %f sec", psTimerClear("PPSTACK_STEPS"));
+    psLogMsg("ppStack", PS_LOG_INFO, "Stage 8 : Photometry Analysis : %f sec", psTimerClear("PPSTACK_STEPS"));
 
     psThreadPoolFinalize();
@@ -1254,5 +1244,5 @@
     }
 
-    psLogMsg("ppStack", PS_LOG_INFO, "Stage 10 : Final Output : %f sec", psTimerClear("PPSTACK_STEPS"));
+    psLogMsg("ppStack", PS_LOG_INFO, "Stage 9 : Final Output : %f sec", psTimerClear("PPSTACK_STEPS"));
 
     memDump("finish");
Index: /branches/cnb_branch_20090215/ppStack/src/ppStackMatch.c
===================================================================
--- /branches/cnb_branch_20090215/ppStack/src/ppStackMatch.c	(revision 21535)
+++ /branches/cnb_branch_20090215/ppStack/src/ppStackMatch.c	(revision 21536)
@@ -189,5 +189,4 @@
 
     bool mdok;                          // Status of MD lookup
-    bool renorm = psMetadataLookupBool(&mdok, recipe, "RENORM"); // Renormalise variances?
     float penalty = psMetadataLookupF32(NULL, ppsub, "PENALTY"); // Penalty for wideness
     int threads = psMetadataLookupS32(NULL, config->arguments, "-threads"); // Number of threads
@@ -359,4 +358,5 @@
                 psString name = NULL;
                 psStringAppend(&name, "fake_%03d.fits", numInput);
+                pmStackVisualPlotTestImage(fake->image, name);
                 psFits *fits = psFitsOpen(name, "w");
                 psFree(name);
@@ -368,4 +368,5 @@
                 psString name = NULL;
                 psStringAppend(&name, "real_%03d.fits", numInput);
+                pmStackVisualPlotTestImage(readout->image, name);
                 psFits *fits = psFitsOpen(name, "w");
                 psFree(name);
@@ -374,19 +375,4 @@
             }
 #endif
-
-            // Renormalise the variances if desired
-            if (renorm) {
-                // Statistics for renormalisation
-                psStatsOptions renormMean = psStatsOptionFromString(psMetadataLookupStr(&mdok, recipe,
-                                                                                        "RENORM.MEAN"));
-                psStatsOptions renormStdev = psStatsOptionFromString(psMetadataLookupStr(&mdok, recipe,
-                                                                                         "RENORM.STDEV"));
-
-                if (!pmReadoutVarianceRenormPixels(readout, maskBad, renormMean, renormStdev, rng)) {
-                    psError(PS_ERR_UNKNOWN, false, "Unable to renormalise variances.");
-                    psFree(output);
-                    return false;
-                }
-            }
 
             if (threads > 0) {
@@ -413,4 +399,5 @@
                 psString name = NULL;
                 psStringAppend(&name, "conv_%03d.fits", numInput);
+                pmStackVisualPlotTestImage(output->image, name);
                 psFits *fits = psFitsOpen(name, "w");
                 psFree(name);
@@ -422,4 +409,5 @@
                 psString name = NULL;
                 psStringAppend(&name, "diff_%03d.fits", numInput);
+                pmStackVisualPlotTestImage(fake->image, name);
                 psFits *fits = psFitsOpen(name, "w");
                 psFree(name);
@@ -562,19 +550,4 @@
     }
 
-    // Renormalise the variances if desired
-    if (renorm) {
-        // Statistics for renormalisation
-        psStatsOptions renormMean = psStatsOptionFromString(psMetadataLookupStr(&mdok, recipe,
-                                                                                "RENORM.MEAN"));
-        psStatsOptions renormStdev = psStatsOptionFromString(psMetadataLookupStr(&mdok, recipe,
-                                                                                 "RENORM.STDEV"));
-
-        if (!pmReadoutVarianceRenormPixels(readout, maskBad, renormMean, renormStdev, rng)) {
-            psError(PS_ERR_UNKNOWN, false, "Unable to renormalise variances.");
-            psFree(output);
-            return false;
-        }
-    }
-
     // Ensure the background value is zero
     psStats *bg = psStatsAlloc(PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV); // Statistics for background
@@ -664,4 +637,5 @@
         psString name = NULL;
         psStringAppend(&name, "convolved_%03d.fits", numInput);
+        pmStackVisualPlotTestImage(output->image, name);
         psFits *fits = psFitsOpen(name, "w");
         psFree(name);
Index: /branches/cnb_branch_20090215/ppStack/src/ppStackPhotometry.c
===================================================================
--- /branches/cnb_branch_20090215/ppStack/src/ppStackPhotometry.c	(revision 21535)
+++ /branches/cnb_branch_20090215/ppStack/src/ppStackPhotometry.c	(revision 21536)
@@ -118,6 +118,6 @@
     pmFPACopy(photFile->fpa, readout->parent->parent->parent);
 
-    if (psMetadataLookupBool(NULL, config->arguments, "-psphot-visual")) {
-        psphotSetVisual(true);
+    if (psMetadataLookupBool(NULL, config->arguments, "-visual")) {
+        pmVisualSetVisual(true);
     }
 
Index: /branches/cnb_branch_20090215/ppStack/src/ppStackSources.c
===================================================================
--- /branches/cnb_branch_20090215/ppStack/src/ppStackSources.c	(revision 21535)
+++ /branches/cnb_branch_20090215/ppStack/src/ppStackSources.c	(revision 21536)
@@ -69,4 +69,5 @@
         psString name = NULL;
         psStringAppend(&name, "start_%03d.fits", i);
+        pmStackVisualPlotTestImage(fake->image, name);
         psFits *fits = psFitsOpen(name, "w");
         psFree(name);
@@ -154,15 +155,15 @@
     int minMatches = PS_MAX (2, 0.5*num);
     for (int i = 0; i < matches->n; i++) {
-	pmSourceMatch *match = matches->data[i]; // Match of interest
-	if (match->num < minMatches) continue;
-
-	// We need to grab a single instance of this source: just take the first available
-	int nImage = match->image->data.S32[0];
-	int nIndex = match->index->data.S32[0];
-	psArray *sources = sourceLists->data[nImage];
-	pmSource *source = sources->data[nIndex];
-	
-	// stick this sample source on sourcesBest
-	psArrayAdd (sourcesBest, 100, source);
+        pmSourceMatch *match = matches->data[i]; // Match of interest
+        if (match->num < minMatches) continue;
+
+        // We need to grab a single instance of this source: just take the first available
+        int nImage = match->image->data.S32[0];
+        int nIndex = match->index->data.S32[0];
+        psArray *sources = sourceLists->data[nImage];
+        pmSource *source = sources->data[nIndex];
+
+        // stick this sample source on sourcesBest
+        psArrayAdd (sourcesBest, 100, source);
     }
     psMetadataAdd (sourcesCell->analysis, PS_LIST_TAIL, "PSPHOT.SOURCES", PS_DATA_ARRAY | PS_META_REPLACE, "psphot sources", sourcesBest);
Index: /branches/cnb_branch_20090215/ppSub/src/ppSub.c
===================================================================
--- /branches/cnb_branch_20090215/ppSub/src/ppSub.c	(revision 21535)
+++ /branches/cnb_branch_20090215/ppSub/src/ppSub.c	(revision 21536)
@@ -6,8 +6,17 @@
  *
  *  @author IfA
- *  @version $Revision: 1.11 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2009-02-09 21:26:05 $
+ *  @version $Revision: 1.11.2.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-19 17:59:49 $
  *  Copyright 2009 Institute for Astronomy, University of Hawaii
  */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <pslib.h>
+#include <psmodules.h>
+#include <psphot.h>
 
 #include "ppSub.h"
@@ -66,5 +75,5 @@
     psTimerStop();
 
-    pmSubtractionVisualClose(); //close plot windows, if -visual is set
+    pmVisualClose(); //close plot windows, if -visual is set
     psFree(config);
     pmModelClassCleanup();
Index: /branches/cnb_branch_20090215/ppSub/src/ppSub.h
===================================================================
--- /branches/cnb_branch_20090215/ppSub/src/ppSub.h	(revision 21535)
+++ /branches/cnb_branch_20090215/ppSub/src/ppSub.h	(revision 21536)
@@ -6,6 +6,6 @@
  *
  *  @author IfA
- *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2009-02-06 01:37:17 $
+ *  @version $Revision: 1.6.2.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-19 17:59:49 $
  *  Copyright 2009 Institute for Astronomy, University of Hawaii
  */
@@ -14,14 +14,6 @@
 #define PP_SUB_H
 
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <string.h>
 #include <pslib.h>
 #include <psmodules.h>
-#include <psphot.h>
-#include <ppStats.h>
 
 /// @addtogroup ppSub
@@ -32,5 +24,5 @@
 /// Setup the arguments parsing
 bool ppSubArgumentsSetup(int argc, char *argv[], ///< Command-line arguments
-			 pmConfig *config    ///< Configuration
+                         pmConfig *config    ///< Configuration
     );
 
@@ -53,47 +45,41 @@
     );
 
-/// generate (if needed) and set or update the masks for input and reference images
-bool ppSubSetMasks (pmConfig *config,	  ///< Configuration
-		    const pmFPAview *view ///< View of active readout
+/// Generate (if needed) and set or update the masks for input and reference images
+bool ppSubSetMasks(pmConfig *config,     ///< Configuration
+                   const pmFPAview *view ///< View of active readout
     );
 
-/// Generate the PSF-matching kernel and convolve the images as needed.  Most of this function
-/// involves looking up the parameters in the recipe and supplying them to the function
-/// pmSubtractionMatch()
-bool ppSubMatchPSFs (pmConfig *config,	  ///< Configuration
-		     const pmFPAview *view ///< View of active readout
+/// Generate the PSF-matching kernel and convolve the images as needed.  Most of this function involves
+/// looking up the parameters in the recipe and supplying them to the function pmSubtractionMatch()
+bool ppSubMatchPSFs(pmConfig *config,    ///< Configuration
+                    const pmFPAview *view ///< View of active readout
     );
 
-/// generate the output readout and pass the kernel info to the header 
-bool ppSubDefineOutput(pmConfig *config,	  ///< Configuration
-		       const pmFPAview *view ///< View of active readout
+/// Generate the output readout and pass the kernel info to the header
+bool ppSubDefineOutput(pmConfig *config, ///< Configuration
+                       const pmFPAview *view ///< View of active readout
     );
 
-/// Calculate the variance factor for the output image based on the input images
-bool ppSubVarianceFactors(pmConfig *config,	  ///< Configuration
-			  psMetadata *stats,    ///< Statistics, for output
-			  const pmFPAview *view ///< View of active readout
-    );
-
-/// Photometry stage 1: measure the PSF from the minuend image 
-bool ppSubMakePSF(pmConfig *config,	  ///< Configuration
-		  const pmFPAview *view ///< View of active readout
+/// Photometry stage 1: measure the PSF from the minuend image
+bool ppSubMakePSF(pmConfig *config,       ///< Configuration
+                  const pmFPAview *view ///< View of active readout
     );
 
 /// Perform the actual image subtraction, update output concepts
-bool ppSubReadoutSubtract(pmConfig *config,	  ///< Configuration
-			  const pmFPAview *view ///< View of active readout
+bool ppSubReadoutSubtract(pmConfig *config,       ///< Configuration
+                          const pmFPAview *view ///< View of active readout
     );
 
 
 /// Photometry stage 2: find and measure sources on the subtracted image
-bool ppSubReadoutPhotometry(pmConfig *config,	  ///< Configuration
-			    psMetadata *stats,    ///< Statistics, for output
-			    const pmFPAview *view ///< View of active readout
+bool ppSubReadoutPhotometry(pmConfig *config,     ///< Configuration
+                            psMetadata *stats,    ///< Statistics, for output
+                            const pmFPAview *view ///< View of active readout
     );
 
 /// Renormalize, update headers and generate JPEGs
-bool ppSubReadoutUpdate(pmConfig *config,	  ///< Configuration
-			const pmFPAview *view ///< View of active readout
+bool ppSubReadoutUpdate(pmConfig *config, ///< Configuration
+                        psMetadata *stats, ///< Statistics for output, or NULL
+                        const pmFPAview *view ///< View of active readout
     );
 
@@ -107,23 +93,4 @@
     );
 
-/// Generate and Set the masks if needed
-bool ppSubSetMasks (
-    pmConfig *config,			///< Configuration
-    const pmFPAview *view 		///< view to readout
-    );
-
-/// Renormalize readout for peak pixels
-bool ppSubReadoutRenormPixels (
-    pmConfig *config, 			///< Configuration
-    psMetadata *recipe, 			///< Recipe
-    pmReadout *readout			///< Readout
-    );
-
-/// Renormalize readout for photometry analysis
-bool ppSubReadoutRenormPhot (
-    pmConfig *config, 			///< Configuration
-    psMetadata *recipe, 			///< Recipe
-    pmReadout *readout			///< Readout
-    );
 
 // Copy every instance of a single keyword from one metadata to another
Index: /branches/cnb_branch_20090215/ppSub/src/ppSubArguments.c
===================================================================
--- /branches/cnb_branch_20090215/ppSub/src/ppSubArguments.c	(revision 21535)
+++ /branches/cnb_branch_20090215/ppSub/src/ppSubArguments.c	(revision 21536)
@@ -6,8 +6,17 @@
  *
  *  @author IfA
- *  @version $Revision: 1.58 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2009-02-09 21:26:05 $
+ *  @version $Revision: 1.58.2.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-19 17:59:49 $
  *  Copyright 2009 Institute for Astronomy, University of Hawaii
  */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <pslib.h>
+#include <psmodules.h>
+#include <psphot.h>
 
 #include "ppSub.h"
@@ -191,8 +200,4 @@
     }
 
-    if ((argnum = psArgumentGet(argc, argv, "-psphot-visual"))) {
-        psArgumentRemove(argnum, &argc, argv);
-        psphotSetVisual(true);
-    }
 
     pmConfigFileSetsMD(config->arguments, &argc, argv, "PPSUB.SOURCES", "-sources", NULL);
@@ -240,11 +245,4 @@
     psMetadataAddS32(arguments, PS_LIST_TAIL, "-opt-order", 0, "Maximum order for optimum kernel search", -1);
     psMetadataAddBool(arguments, PS_LIST_TAIL, "-dual", 0, "Dual convolution", false);
-    psMetadataAddBool(arguments, PS_LIST_TAIL, "-renorm", 0, "Renormalise variance maps?", false);
-    psMetadataAddStr(arguments, PS_LIST_TAIL, "-renorm-mean", 0,
-                     "Statistic for mean in renormalisation", NULL);
-    psMetadataAddStr(arguments, PS_LIST_TAIL, "-renorm-stdev", 0,
-                     "Statistic for stdev in renormalisation", NULL);
-    psMetadataAddF32(arguments, PS_LIST_TAIL, "-renorm-width", 0, "Gaussian width for renormalisation", NAN);
-    psMetadataAddS32(arguments, PS_LIST_TAIL, "-renorm-num", 0, "Number of samples for renormalisation", 0);
     psMetadataAddBool(arguments, PS_LIST_TAIL, "-photometry", 0, "Perform photometry?", false);
     psMetadataAddS32(arguments, PS_LIST_TAIL, "-threads", 0, "Number of threads", 0);
@@ -352,13 +350,4 @@
                       psMetadataLookupBool(NULL, arguments, "-dual"));
 
-    if (psMetadataLookupBool(NULL, arguments, "-renorm") ||
-        psMetadataLookupBool(NULL, recipe, "RENORM")) {
-        psMetadataAddBool(arguments, PS_LIST_TAIL, "RENORM", 0, "Renormalise variance maps?", true);
-    }
-    VALUE_ARG_RECIPE_INT("-renorm-num", "RENORM.NUM", S32, 0);
-    VALUE_ARG_RECIPE_FLOAT("-renorm-width", "RENORM.WIDTH", F32);
-    valueArgRecipeStr(arguments, recipe, "-renorm-mean", "RENORM.MEAN", recipe);
-    valueArgRecipeStr(arguments, recipe, "-renorm-stdev", "RENORM.STDEV", recipe);
-
     // Need to update this because it could have been overwritten by the camera's own recipe
     if (psMetadataLookupBool(NULL, arguments, "-photometry")) {
@@ -367,5 +356,5 @@
 
     if (psMetadataLookupBool(NULL, arguments, "-visual")) {
-        pmSubtractionSetVisual(true);
+        pmVisualSetVisual(true);
     }
 
Index: /branches/cnb_branch_20090215/ppSub/src/ppSubBackground.c
===================================================================
--- /branches/cnb_branch_20090215/ppSub/src/ppSubBackground.c	(revision 21535)
+++ /branches/cnb_branch_20090215/ppSub/src/ppSubBackground.c	(revision 21536)
@@ -6,36 +6,38 @@
  *
  *  @author IfA
- *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2009-02-06 01:37:17 $
+ *  @version $Revision: 1.6.2.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-19 17:59:49 $
  *  Copyright 2009 Institute for Astronomy, University of Hawaii
  */
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <pslib.h>
+#include <psmodules.h>
+#include <psphot.h>
+
 #include "ppSub.h"
 
-/**
- * Based on ppImageSubtractBackground()
- */
 bool ppSubBackground(pmConfig *config, const pmFPAview *view)
 {
-    psAssert(config, "Need configuration");
-    psAssert(view, "Need view to chip");
+    psAssert(config, "Require configuration");
+    psAssert(view, "Require view");
 
-    bool status; // Status of metadata lookups
+    bool mdok; // Status of metadata lookups
 
-    psMetadata *ppSubRecipe = psMetadataLookupPtr(NULL, config->recipes, PPSUB_RECIPE);
+    psMetadata *ppSubRecipe = psMetadataLookupPtr(NULL, config->recipes, PPSUB_RECIPE); // Recipe for ppSub
     psAssert(ppSubRecipe, "Need PPSUB recipe");
-
-    psMetadata *psphotRecipe = psMetadataLookupPtr(NULL, config->recipes, PSPHOT_RECIPE);
+    psMetadata *psphotRecipe = psMetadataLookupPtr(NULL, config->recipes, PSPHOT_RECIPE); // Recipe for psphot
     psAssert(psphotRecipe, "Need PSPHOT recipe for binning");
 
-    psImageMaskType maskBad = pmConfigMaskGet("BLANK", config); 
+    psImageMaskType maskBad = pmConfigMaskGet("BLANK", config); // Bits to mask
 
-    // select the output readout
-    pmReadout *outRO = pmFPAfileThisReadout(config->files, view, "PPSUB.OUTPUT");
+    pmReadout *outRO = pmFPAfileThisReadout(config->files, view, "PPSUB.OUTPUT"); // Output image
+    pmReadout *modelRO = pmFPAfileThisReadout(config->files, view, "PSPHOT.BACKMDL"); // Background model
 
-    // select the model readout, if it exist already; if not, generate it
-    pmReadout *modelRO = pmFPAfileThisReadout(config->files, view, "PSPHOT.BACKMDL");
-
-    // if necessary, generate the background model
+    // Generate the background model, if required
     if (!modelRO) {
         // Create the background model
@@ -44,6 +46,6 @@
             return false;
         }
-	// select the model readout (should now exist)
-	modelRO = pmFPAfileThisReadout(config->files, view, "PSPHOT.BACKMDL");
+        // select the model readout (should now exist)
+        modelRO = pmFPAfileThisReadout(config->files, view, "PSPHOT.BACKMDL");
         if (!modelRO) {
             psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find background model");
@@ -51,8 +53,7 @@
         }
     }
-    psImageBinning *binning = psMetadataLookupPtr(&status, psphotRecipe,
+    psImageBinning *binning = psMetadataLookupPtr(&mdok, psphotRecipe,
                                                   "PSPHOT.BACKGROUND.BINNING"); // Binning for model
     psImage *modelImage = modelRO->image; // Background model
-
     psImage *image = outRO->image; // Image of interest
     psImage *mask = outRO->mask; // Mask of interest
Index: /branches/cnb_branch_20090215/ppSub/src/ppSubCamera.c
===================================================================
--- /branches/cnb_branch_20090215/ppSub/src/ppSubCamera.c	(revision 21535)
+++ /branches/cnb_branch_20090215/ppSub/src/ppSubCamera.c	(revision 21536)
@@ -6,8 +6,17 @@
  *
  *  @author IfA
- *  @version $Revision: 1.33 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2009-02-06 03:20:02 $
+ *  @version $Revision: 1.33.2.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-19 17:59:49 $
  *  Copyright 2009 Institute for Astronomy, University of Hawaii
  */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <pslib.h>
+#include <psmodules.h>
+#include <psphot.h>
 
 #include "ppSub.h"
@@ -257,8 +266,7 @@
     // psPhot input
     if (psMetadataLookupBool(NULL, recipe, "PHOTOMETRY")) {
-        psphotModelClassInit ();        // load implementation-specific models
-
-
-        // Internal-ish file for getting the PSF from the matched addition
+        psphotModelClassInit();        // load implementation-specific models
+
+        // Internal-ish file for getting the PSF from the minuend
         pmFPAfile *psf = pmFPAfileDefineOutputFromFile(config, output, "PSPHOT.PSF.LOAD");
         if (!psf) {
@@ -272,15 +280,4 @@
         pmFPAfileActivate(config->files, false, "PSPHOT.PSF.LOAD");
 
-        pmFPAfile *psphotResid = pmFPAfileDefineOutputForFormat (config, NULL, "PSPHOT.RESID", output->cameraName, output->formatName);
-        if (!psphotResid) {
-            psError(PSPHOT_ERR_CONFIG, false, "Cannot find a rule for PSPHOT.RESID");
-            return false;
-        }
-        // make this optional: psphotResid->save = true;
-    }
-
-    // Always do this, since we're using psphot for the background model.
-    // XXX Not certain that I need to generate a separate pmFPAfile for PSPHOT.INPUT
-    if (0) {
         pmFPAfile *psphot = pmFPAfileDefineFromFPA(config, output->fpa, 1, 1, "PSPHOT.INPUT");
         if (!psphot) {
@@ -297,5 +294,4 @@
             return false;
         }
-
     }
 
Index: /branches/cnb_branch_20090215/ppSub/src/ppSubDefineOutput.c
===================================================================
--- /branches/cnb_branch_20090215/ppSub/src/ppSubDefineOutput.c	(revision 21535)
+++ /branches/cnb_branch_20090215/ppSub/src/ppSubDefineOutput.c	(revision 21536)
@@ -6,16 +6,25 @@
  *
  *  @author IfA
- *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2009-02-06 01:37:17 $
+ *  @version $Revision: 1.2.4.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-19 17:59:49 $
  *  Copyright 2009 Institute for Astronomy, University of Hawaii
  */
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <pslib.h>
+#include <psmodules.h>
+
 #include "ppSub.h"
 
-bool ppSubDefineOutput (pmConfig *config, const pmFPAview *view) {
+bool ppSubDefineOutput(pmConfig *config, const pmFPAview *view)
+{
+    psAssert(config, "Require configuration");
+    psAssert(view, "Require view");
 
-    bool mdok;
-
-    // generate an output readout 
+    // generate an output readout
     pmCell *outCell = pmFPAfileThisCell(config->files, view, "PPSUB.OUTPUT"); // Output cell
     pmReadout *outRO = pmReadoutAlloc(outCell); // Output readout: subtraction
@@ -30,11 +39,13 @@
     pmReadout *refConv = pmFPAfileThisReadout(config->files, view, "PPSUB.REF.CONV"); // Reference readout
 
-    // Add kernel descrption to header.  We don't know which readout gets the kernels because
-    // it depends on which is larger (the choice is set in ppSubMatchPSFs)
-    bool inputHasKernel = true;
-    pmSubtractionKernels *kernels = psMetadataLookupPtr(&mdok, inConv->analysis, PM_SUBTRACTION_ANALYSIS_KERNEL); // Subtraction kernel
+    // Add kernel descrption to header.
+    // We don't know which readout has the kernels because it depends on which PSF is larger
+    bool mdok;                          // Status of MD lookup
+    psMetadata *analysis = inConv->analysis; // Analysis metadata with kernel information
+    pmSubtractionKernels *kernels = psMetadataLookupPtr(&mdok, analysis,
+                                                        PM_SUBTRACTION_ANALYSIS_KERNEL); // Subtraction kernel
     if (!kernels) {
-        kernels = psMetadataLookupPtr(&mdok, refConv->analysis, PM_SUBTRACTION_ANALYSIS_KERNEL);
-	inputHasKernel = false;
+        analysis = refConv->analysis;
+        kernels = psMetadataLookupPtr(&mdok, analysis, PM_SUBTRACTION_ANALYSIS_KERNEL);
     }
     if (!kernels) {
@@ -45,24 +56,17 @@
         return false;
     }
-    psMetadataAddStr(outHDU->header, PS_LIST_TAIL, "PPSUB.KERNEL", 0, "Subtraction kernel", kernels->description);
+    psMetadataAddStr(outHDU->header, PS_LIST_TAIL, "PPSUB.KERNEL", 0, "Subtraction kernel",
+                     kernels->description);
 
-    if (inputHasKernel) {
-	outRO->analysis = psMetadataCopy(outRO->analysis, inConv->analysis);
-    } else {
-	outRO->analysis = psMetadataCopy(outRO->analysis, refConv->analysis);
-    } 
+    outRO->analysis = psMetadataCopy(outRO->analysis, analysis);
 
 #ifdef TESTING
-    psImage *kernelImage = NULL;
-
-    if (inputHasKernel) {
-	kernelImage = psMetadataLookupPtr(&mdok, inConv->analysis, "SUBTRACTION.KERNEL.IMAGE"); // Image of the kernels
-    } else {
-        kernelImage = psMetadataLookupPtr(&mdok, refConv->analysis, "SUBTRACTION.KERNEL.IMAGE");
+    {
+        psImage *kernelImage = psMetadataLookupPtr(&mdok, analysis,
+                                                   "SUBTRACTION.KERNEL.IMAGE"); // Image of kernel
+        psFits *fits = psFitsOpen("kernel.fits", "w");
+        psFitsWriteImage(fits, NULL, kernelImage, 0, NULL);
+        psFitsClose(fits);
     }
-
-    psFits *fits = psFitsOpen("kernel.fits", "w");
-    psFitsWriteImage(fits, NULL, kernelImage, 0, NULL);
-    psFitsClose(fits);
 #endif
 
Index: /branches/cnb_branch_20090215/ppSub/src/ppSubLoop.c
===================================================================
--- /branches/cnb_branch_20090215/ppSub/src/ppSubLoop.c	(revision 21535)
+++ /branches/cnb_branch_20090215/ppSub/src/ppSubLoop.c	(revision 21536)
@@ -6,8 +6,16 @@
  *
  *  @author IfA
- *  @version $Revision: 1.23 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2009-02-06 01:37:17 $
+ *  @version $Revision: 1.23.2.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-19 17:59:49 $
  *  Copyright 2009 Institute for Astronomy, University of Hawaii
  */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <pslib.h>
+#include <psmodules.h>
+#include <ppStats.h>
 
 #include "ppSub.h"
@@ -138,5 +146,5 @@
                     return false;
                 }
-		psImageMaskType maskValue = pmConfigMaskGet("MASK.VALUE", config);
+                psImageMaskType maskValue = pmConfigMaskGet("MASK.VALUE", config);
                 ppStatsFPA(stats, output->fpa, view, maskValue, config);
             }
Index: /branches/cnb_branch_20090215/ppSub/src/ppSubMakePSF.c
===================================================================
--- /branches/cnb_branch_20090215/ppSub/src/ppSubMakePSF.c	(revision 21535)
+++ /branches/cnb_branch_20090215/ppSub/src/ppSubMakePSF.c	(revision 21536)
@@ -6,61 +6,84 @@
  *
  *  @author IfA
- *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2009-02-06 01:37:17 $
+ *  @version $Revision: 1.2.4.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-19 17:59:49 $
  *  Copyright 2009 Institute for Astronomy, University of Hawaii
  */
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <pslib.h>
+#include <psmodules.h>
+#include <psphot.h>
+
 #include "ppSub.h"
 
-/**
- * Photometry stage 1: measure the PSF from the minuend image 
- */
-bool ppSubMakePSF (pmConfig *config, const pmFPAview *view) {
+bool ppSubMakePSF(pmConfig *config, const pmFPAview *view)
+{
+    psAssert(config, "Require configuration");
+    psAssert(view, "Require view");
 
-    bool mdok = false;
-
-    // Photometry is to be performed in two stages:
-    // 1. Measure the PSF using the PSF-matched images
-    // 2. Find and measure sources on the subtracted image
     psTimerStart("PPSUB_PHOT");
 
-    // Look up recipe values
     psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSUB_RECIPE); // Recipe for ppSub
     psAssert(recipe, "We checked this earlier, so it should be here.");
 
-    psMetadata *psphotRecipe = psMetadataLookupMetadata(NULL, config->recipes, PSPHOT_RECIPE); // Recipe for psphot
+    if (!psMetadataLookupBool(NULL, recipe, "PHOTOMETRY")) {
+        return true;
+    }
+
+    psMetadata *psphotRecipe = psMetadataLookupMetadata(NULL, config->recipes, PSPHOT_RECIPE);// psphot recipe
     psAssert(recipe, "We checked this earlier, so it should be here.");
-
-    if (!psMetadataLookupBool(NULL, recipe, "PHOTOMETRY")) return true;
 
     bool reverse = psMetadataLookupBool(NULL, config->arguments, "REVERSE"); // Reverse sense of subtraction?
 
-    pmReadout *minuend = NULL;
-    pmFPAfile *minuendFile = NULL;
+    bool mdok = false;                  // Status of MD lookup
+    pmReadout *minuend = NULL;          // Image that will be positive following subtraction
+    pmFPAfile *minuendFile = NULL;      // File for minuend image
     if (reverse) {
-	minuend = pmFPAfileThisReadout(config->files, view, "PPSUB.REF.CONV");
-	minuendFile = psMetadataLookupPtr(&mdok, config->files, "PPSUB.REF.CONV");
+        minuend = pmFPAfileThisReadout(config->files, view, "PPSUB.REF.CONV");
+        minuendFile = psMetadataLookupPtr(&mdok, config->files, "PPSUB.REF.CONV");
     } else {
-	minuend = pmFPAfileThisReadout(config->files, view, "PPSUB.INPUT.CONV");
-	minuendFile = psMetadataLookupPtr(&mdok, config->files, "PPSUB.INPUT.CONV");
+        minuend = pmFPAfileThisReadout(config->files, view, "PPSUB.INPUT.CONV");
+        minuendFile = psMetadataLookupPtr(&mdok, config->files, "PPSUB.INPUT.CONV");
     }
 
-    // supply the minuend pmFPAfile to psphot as PSPHOT.INPUT:
-    psMetadataAddPtr (config->files, PS_LIST_TAIL, "PSPHOT.INPUT", PS_DATA_UNKNOWN | PS_META_REPLACE, "psphot input : view on another pmFPAfile", minuendFile);
+#if 1
+    pmReadout *template = minuend;
+    pmFPAfile *photFile = psMetadataLookupPtr(&mdok, config->files, "PSPHOT.INPUT"); // Photometry file
+    pmReadout *photRO = pmFPAviewThisReadout(view, photFile->fpa); // Readout to photometer
+    if (!photRO) {
+        pmCell *cell = pmFPAviewThisCell(view, photFile->fpa); // Cell to photometer
+        photRO = pmReadoutAlloc(cell); // Output readout: subtraction
+    }
+    photRO->image = psImageCopy(photRO->image, template->image, PS_TYPE_F32);
+    if (template->variance) {
+        photRO->variance = psImageCopy(photRO->variance, template->variance, PS_TYPE_F32);
+    } else {
+        psFree(photRO->variance);
+        photRO->variance = NULL;
+    }
+    if (template->mask) {
+        photRO->mask = psImageCopy(photRO->mask, template->mask, PS_TYPE_IMAGE_MASK);
+    } else {
+        psFree(photRO->mask);
+        photRO->mask = NULL;
+    }
+#else
+    // Supply the minuend pmFPAfile to psphot as PSPHOT.INPUT:
+    psMetadataAddPtr(config->files, PS_LIST_TAIL, "PSPHOT.INPUT", PS_DATA_UNKNOWN | PS_META_REPLACE,
+                     "psphot input: view on another pmFPAfile", minuendFile);
+#endif
 
-    // old-style variance renormalization
-    if (!ppSubReadoutRenormPhot (config, recipe, minuend)) {
-	psError(PS_ERR_UNKNOWN, false, "failure in renormalization");
-	return false;
-    }
-
-    // extract the loaded sources from the associated readout
+    // Extract the loaded sources from the associated readout, and generate PSF
+    // Here, we assume the image is background-subtracted
     pmReadout *sourcesRO = pmFPAfileThisReadout(config->files, view, "PPSUB.SOURCES");
     psArray *sources = psMetadataLookupPtr(&mdok, sourcesRO->analysis, "PSPHOT.SOURCES");
-
-    // generate PSF from the supplied sources (assumes image is background-subtracted)
     if (!psphotReadoutFindPSF(config, view, sources)) {
-	psError(PS_ERR_UNKNOWN, false, "Unable to perform photometry on subtracted image.");
-	return false;
+        psError(PS_ERR_UNKNOWN, false, "Unable to perform photometry on subtracted image.");
+        return false;
     }
 
@@ -70,4 +93,7 @@
     psMetadataItemSupplement(hdu->header, psphotRecipe, "FWHM_MAJ");
     psMetadataItemSupplement(hdu->header, psphotRecipe, "FWHM_MIN");
+
+    // Get rid of the generated header; it will be regenerated by the real photometry run
+    psMetadataRemoveKey(photRO->analysis, "PSPHOT.HEADER");
 
     return true;
@@ -87,5 +113,5 @@
 
 // Blow away the sources psphot found --- they're irrelevant for the subtraction
-// XXX is this still needed?  These are now probably not being set 
+// XXX is this still needed?  These are now probably not being set
 // pmReadout *photRO = pmFPAviewThisReadout(view, photFile->fpa); // Readout with sources
 // psMetadataRemoveKey(photRO->analysis, "PSPHOT.SOURCES");
Index: /branches/cnb_branch_20090215/ppSub/src/ppSubMatchPSFs.c
===================================================================
--- /branches/cnb_branch_20090215/ppSub/src/ppSubMatchPSFs.c	(revision 21535)
+++ /branches/cnb_branch_20090215/ppSub/src/ppSubMatchPSFs.c	(revision 21536)
@@ -6,19 +6,24 @@
  *
  *  @author IfA
- *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2009-02-06 01:37:17 $
+ *  @version $Revision: 1.2.4.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-19 17:59:49 $
  *  Copyright 2009 Institute for Astronomy, University of Hawaii
  */
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <pslib.h>
+#include <psmodules.h>
+#include <psphot.h>
+
 #include "ppSub.h"
 
-/** Generate the PSF-matching kernel and convolve the images as needed.  Most of this function
- * involves looking up the parameters in the recipe and supplying them to the function
- * pmSubtractionMatch();
- */
-
-bool ppSubMatchPSFs (pmConfig *config, const pmFPAview *view) {
-
-    bool mdok;                          // Status of MD lookup
+bool ppSubMatchPSFs(pmConfig *config, const pmFPAview *view)
+{
+    psAssert(config, "Require configuration");
+    psAssert(view, "Require view");
 
     // Look up recipe values
@@ -26,35 +31,25 @@
     psAssert(recipe, "We checked this earlier, so it should be here.");
 
-    // input images
+    // Input images
     pmReadout *inRO = pmFPAfileThisReadout(config->files, view, "PPSUB.INPUT"); // Input readout
     pmReadout *refRO = pmFPAfileThisReadout(config->files, view, "PPSUB.REF"); // Reference readout
 
-    // get or generate output image holders
-    pmReadout *inConv = pmFPAfileThisReadout(config->files, view, "PPSUB.INPUT.CONV"); // Input convolved readout
+    // Output image holders
+    pmReadout *inConv = pmFPAfileThisReadout(config->files, view, "PPSUB.INPUT.CONV"); // Input convolved
     if (!inConv) {
-	pmCell *cell = pmFPAfileThisCell(config->files, view, "PPSUB.INPUT.CONV"); // Input convolved readout
-	inConv = pmReadoutAlloc(cell); // Convolved version of input
+        pmCell *cell = pmFPAfileThisCell(config->files, view, "PPSUB.INPUT.CONV"); // Cell for convolved input
+        inConv = pmReadoutAlloc(cell);
     }
-    pmReadout *refConv = pmFPAfileThisReadout(config->files, view, "PPSUB.REF.CONV"); // Reference convolved readout
+    pmReadout *refConv = pmFPAfileThisReadout(config->files, view, "PPSUB.REF.CONV"); // Reference convolved
     if (!refConv) {
-	pmCell *cell = pmFPAfileThisCell(config->files, view, "PPSUB.REF.CONV"); // Input convolved readout
-	refConv = pmReadoutAlloc(cell); // Convolved version of input
+        pmCell *cell = pmFPAfileThisCell(config->files, view, "PPSUB.REF.CONV"); // Cell for convolved ref.
+        refConv = pmReadoutAlloc(cell);
     }
 
-    // options which control the generation of optimal parameters
-    bool optimum = psMetadataLookupBool(&mdok, recipe, "OPTIMUM"); // Derive optimum parameters?
-    float optMin = psMetadataLookupF32(&mdok, recipe, "OPTIMUM.MIN"); // Minimum width for search
-    float optMax = psMetadataLookupF32(&mdok, recipe, "OPTIMUM.MAX"); // Maximum width for search
-    float optStep = psMetadataLookupF32(&mdok, recipe, "OPTIMUM.STEP"); // Step for search
+    bool mdok;                          // Status of MD lookup
 
-    // Vector with FWHMs for optimum search
-    psVector *optWidths = NULL;
-    if (optimum) {
-        optWidths = psVectorCreate(optWidths, optMin, optMax, optStep, PS_TYPE_F32);
-    }
-
-    // Sources in image : these must be loaded from previous analysis stages
-    pmReadout *sourcesRO = pmFPAfileThisReadout(config->files, view, "PPSUB.SOURCES"); // Readout with sources 
-    psArray *sources = NULL;            
+    // Sources in image, used for stamps: these must be loaded from previous analysis stages
+    pmReadout *sourcesRO = pmFPAfileThisReadout(config->files, view, "PPSUB.SOURCES"); // Readout with sources
+    psArray *sources = NULL;            // Sources in image; used for stamps
     if (sourcesRO) {
         sources = psMetadataLookupPtr(&mdok, sourcesRO->analysis, "PSPHOT.SOURCES");
@@ -66,10 +61,8 @@
     float spacing = psMetadataLookupF32(NULL, recipe, "STAMP.SPACING"); // Typical stamp spacing
     float threshold = psMetadataLookupF32(NULL, recipe, "STAMP.THRESHOLD"); // Threshold for stmps
-
     const char *stampsName = psMetadataLookupStr(&mdok, config->arguments, "STAMPS"); // Filename for stamps
 
     const char *typeStr = psMetadataLookupStr(NULL, recipe, "KERNEL.TYPE"); // Kernel type
     psAssert(typeStr, "We put it here in ppSubArguments.c");
-
     pmSubtractionKernelsType type = pmSubtractionKernelsTypeFromString(typeStr); // Type of kernel
     if (type == PM_SUBTRACTION_KERNEL_NONE) {
@@ -87,8 +80,4 @@
     int binning = psMetadataLookupS32(NULL, recipe, "SPAM.BINNING"); // Binning for SPAM kernel
     float penalty = psMetadataLookupF32(NULL, recipe, "PENALTY"); // Penalty for wideness
-
-    int optOrder = psMetadataLookupS32(&mdok, recipe, "OPTIMUM.ORDER"); // Order for search
-    float optThresh = psMetadataLookupF32(&mdok, recipe, "OPTIMUM.TOL"); // Tolerance for search
-
     int iter = psMetadataLookupS32(NULL, recipe, "ITER"); // Rejection iterations
     float rej = psMetadataLookupF32(NULL, recipe, "REJ"); // Rejection threshold
@@ -98,6 +87,18 @@
     float poorFrac = psMetadataLookupF32(&mdok, recipe, "POOR.FRACTION"); // Fraction for "poor"
 
-    // XXX EAM : do we need to / want to define different values for BAD and POOR subtraction vs BAD and POOR warp?
-    psImageMaskType maskVal = pmConfigMaskGet("MASK.VALUE", config); // Bits to mask going in to pmSubtractionMatch
+    // Options which control the generation of optimal parameters
+    bool optimum = psMetadataLookupBool(&mdok, recipe, "OPTIMUM"); // Derive optimum parameters?
+    float optMin = psMetadataLookupF32(&mdok, recipe, "OPTIMUM.MIN"); // Minimum width for search
+    float optMax = psMetadataLookupF32(&mdok, recipe, "OPTIMUM.MAX"); // Maximum width for search
+    float optStep = psMetadataLookupF32(&mdok, recipe, "OPTIMUM.STEP"); // Step for search
+    psVector *optWidths = NULL;         // Vector with FWHMs for optimum search
+    if (optimum) {
+        optWidths = psVectorCreate(optWidths, optMin, optMax, optStep, PS_TYPE_F32);
+    }
+    int optOrder = psMetadataLookupS32(&mdok, recipe, "OPTIMUM.ORDER"); // Order for search
+    float optThresh = psMetadataLookupF32(&mdok, recipe, "OPTIMUM.TOL"); // Tolerance for search
+
+    // XXX Do we need/want to define different values for BAD and POOR subtraction vs BAD and POOR warp?
+    psImageMaskType maskVal = pmConfigMaskGet("MASK.VALUE", config); // Bits to mask in inputs
     psImageMaskType maskPoor = pmConfigMaskGet("POOR.WARP", config); // Bits to mask for poor pixels
     psImageMaskType maskBad = pmConfigMaskGet("BLANK", config); // Bits to mask for bad pixels
@@ -124,4 +125,7 @@
     pmSubtractionThreadsFinalize(inRO, refRO);
 
+    psImageCovarianceTransfer(inConv->variance, inConv->covariance);
+    psImageCovarianceTransfer(refConv->variance, refConv->covariance);
+
     // XXX drop the pixels associated with inRO and refRO (now that we have inConv and refConf)
 
Index: /branches/cnb_branch_20090215/ppSub/src/ppSubReadout.c
===================================================================
--- /branches/cnb_branch_20090215/ppSub/src/ppSubReadout.c	(revision 21535)
+++ /branches/cnb_branch_20090215/ppSub/src/ppSubReadout.c	(revision 21536)
@@ -6,8 +6,16 @@
  *
  *  @author IfA
- *  @version $Revision: 1.112 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2009-02-09 21:26:05 $
+ *  @version $Revision: 1.112.2.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-19 17:59:49 $
  *  Copyright 2009 Institute for Astronomy, University of Hawaii
  */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <pslib.h>
+#include <psmodules.h>
 
 #include "ppSub.h"
@@ -17,31 +25,26 @@
     psTimerStart("PPSUB_MATCH");
 
-    if (!ppSubSetMasks (config, view)) {
-        psError(PS_ERR_UNKNOWN, false, "Unable to subtract background.");
+    if (!ppSubSetMasks(config, view)) {
+        psError(PS_ERR_UNKNOWN, false, "Unable to set masks.");
         return false;
     }
 
-    if (!ppSubMatchPSFs (config, view)) {
-        psError(PS_ERR_UNKNOWN, false, "Unable to subtract background.");
+    if (!ppSubMatchPSFs(config, view)) {
+        psError(PS_ERR_UNKNOWN, false, "Unable to match PSFs.");
         return false;
     }
 
-    if (!ppSubDefineOutput (config, view)) {
-        psError(PS_ERR_UNKNOWN, false, "Unable to subtract background.");
-        return false;
-    }
-
-    if (!ppSubVarianceFactors (config, stats, view)) {
-        psError(PS_ERR_UNKNOWN, false, "Unable to subtract background.");
+    if (!ppSubDefineOutput(config, view)) {
+        psError(PS_ERR_UNKNOWN, false, "Unable to define output.");
         return false;
     }
 
     if (!ppSubMakePSF(config, view)) {
-        psError(PS_ERR_UNKNOWN, false, "Unable to subtract background.");
+        psError(PS_ERR_UNKNOWN, false, "Unable to generate PSF.");
         return false;
     }
 
-    if (!ppSubReadoutSubtract (config, view)) {
-        psError(PS_ERR_UNKNOWN, false, "Unable to subtract background.");
+    if (!ppSubReadoutSubtract(config, view)) {
+        psError(PS_ERR_UNKNOWN, false, "Unable to subtract images.");
         return false;
     }
@@ -53,11 +56,11 @@
     }
 
-    if (!ppSubReadoutPhotometry (config, stats, view)) {
-        psError(PS_ERR_UNKNOWN, false, "Unable to subtract background.");
+    if (!ppSubReadoutPhotometry(config, stats, view)) {
+        psError(PS_ERR_UNKNOWN, false, "Unable to perform photometry.");
         return false;
     }
 
-    if (!ppSubReadoutUpdate (config, view)) {
-        psError(PS_ERR_UNKNOWN, false, "Unable to subtract background.");
+    if (!ppSubReadoutUpdate(config, stats, view)) {
+        psError(PS_ERR_UNKNOWN, false, "Unable to update.");
         return false;
     }
Index: /branches/cnb_branch_20090215/ppSub/src/ppSubReadoutPhotometry.c
===================================================================
--- /branches/cnb_branch_20090215/ppSub/src/ppSubReadoutPhotometry.c	(revision 21535)
+++ /branches/cnb_branch_20090215/ppSub/src/ppSubReadoutPhotometry.c	(revision 21536)
@@ -6,17 +6,24 @@
  *
  *  @author IfA
- *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2009-02-06 03:20:02 $
+ *  @version $Revision: 1.3.4.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-19 17:59:49 $
  *  Copyright 2009 Institute for Astronomy, University of Hawaii
  */
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <pslib.h>
+#include <psmodules.h>
+#include <psphot.h>
+
 #include "ppSub.h"
 
-/**
- * Photometry stage 2: find and measure sources on the subtracted image
- */
-bool ppSubReadoutPhotometry (pmConfig *config, psMetadata *stats, const pmFPAview *view) {
-
-    bool mdok = false;
+bool ppSubReadoutPhotometry (pmConfig *config, psMetadata *stats, const pmFPAview *view)
+{
+    psAssert(config, "Require configuration");
+    psAssert(view, "Require view");
 
     // Look up recipe values
@@ -32,28 +39,29 @@
     // The PSF (measured in ppSubMakePSF) is stored on the chip->analysis of PSPHOT.INPUT
     // In order to use an incoming PSF, it must be stored on the chip->analysis of PSPHOT.PSF.LOAD
-    pmChip *psfInputChip = pmFPAfileThisChip(config->files, view, "PSPHOT.INPUT");
+    pmChip *psfInputChip = pmFPAfileThisChip(config->files, view, "PSPHOT.INPUT"); // Chip with PSF
     psAssert (psfInputChip, "should have been generated for ppSubMakePSF");
-
-    pmChip *psfLoadChip = pmFPAfileThisChip(config->files, view, "PSPHOT.PSF.LOAD");
+    pmChip *psfLoadChip = pmFPAfileThisChip(config->files, view, "PSPHOT.PSF.LOAD"); // Chip to have PSF
     psAssert (psfLoadChip, "PSPHOT.PSF.LOAD should have been defined in ppSubCamera");
-
-    pmPSF *psf = psMetadataLookupPtr(NULL, psfInputChip->analysis, "PSPHOT.PSF");
+    pmPSF *psf = psMetadataLookupPtr(NULL, psfInputChip->analysis, "PSPHOT.PSF"); // PSF for photometry
     if (!psf) {
         psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find PSF from psphot");
         return false;
     }
-    psMetadataAddPtr(psfLoadChip->analysis, PS_LIST_TAIL, "PSPHOT.PSF", PS_DATA_UNKNOWN | PS_META_REPLACE, "PSF from matched addition", psf);
+    psMetadataAddPtr(psfLoadChip->analysis, PS_LIST_TAIL, "PSPHOT.PSF", PS_DATA_UNKNOWN | PS_META_REPLACE,
+                     "PSF from ppSubMakePSF", psf);
+
+    bool mdok = false;
 
     // psphotReadoutMinimal performs the photometry analysis on PSPHOT.INPUT; we need to move
     // around the pointers so PSPHOT.INPUT corresponds to the output image; previously, it was
     // equivalent to the minuend image.
-    pmFPAfile *outputFile = psMetadataLookupPtr(&mdok, config->files, "PPSUB.OUTPUT");
+    pmFPAfile *outputFile = psMetadataLookupPtr(&mdok, config->files, "PPSUB.OUTPUT"); // Output file
     pmReadout *outRO = pmFPAviewThisReadout(view, outputFile->fpa); // Readout with the sources
 
     // XXX possibly rename this to PPSUB.RESID?
-    pmFPAfile *photFile = psMetadataLookupPtr(&mdok, config->files, "PSPHOT.RESID");
-    pmReadout *photRO = pmFPAviewThisReadout(view, photFile->fpa); // Readout with the sources
+    pmFPAfile *photFile = psMetadataLookupPtr(&mdok, config->files, "PSPHOT.INPUT"); // Photometry file
+    pmReadout *photRO = pmFPAviewThisReadout(view, photFile->fpa); // Readout to photometer
     if (!photRO) {
-        pmCell *cell = pmFPAfileThisCell(config->files, view, "PSPHOT.RESID"); // Output cell
+        pmCell *cell = pmFPAviewThisCell(view, photFile->fpa); // Cell to photometer
         photRO = pmReadoutAlloc(cell); // Output readout: subtraction
     }
@@ -62,5 +70,5 @@
         photRO->variance = psImageCopy(photRO->variance, outRO->variance, PS_TYPE_F32);
     } else {
-        psFree (photRO->variance);
+        psFree(photRO->variance);
         photRO->variance = NULL;
     }
@@ -68,16 +76,12 @@
         photRO->mask = psImageCopy(photRO->mask, outRO->mask, PS_TYPE_IMAGE_MASK);
     } else {
-        psFree (photRO->mask);
+        psFree(photRO->mask);
         photRO->mask = NULL;
     }
 
-    // pmFPAfile *photFile = outputFile;
-    psMetadataAddPtr (config->files, PS_LIST_TAIL, "PSPHOT.INPUT", PS_DATA_UNKNOWN | PS_META_REPLACE, "psphot input : view on another pmFPAfile", photFile);
-
-    // old-style variance renormalization
-    if (!ppSubReadoutRenormPhot (config, recipe, photRO)) {
-        psError(PS_ERR_UNKNOWN, false, "failure in renormalization");
-        return false;
-    }
+#if 0
+    psMetadataAddPtr(config->files, PS_LIST_TAIL, "PSPHOT.INPUT", PS_DATA_UNKNOWN | PS_META_REPLACE,
+                     "psphot input: view on another pmFPAfile", photFile);
+#endif
 
     if (!psphotReadoutMinimal(config, view)) {
@@ -86,4 +90,9 @@
         psErrorClear();
     }
+#if 1
+    photRO->data_exists = true;
+    photRO->parent->data_exists = true;
+    photRO->parent->parent->data_exists = true;
+#endif
 
     if (stats) {
@@ -101,14 +110,6 @@
 }
 
-    // XXX not sure that this is still needed (only if psphotReadoutMinimal measures the background)
-    // if (!pmFPAfileDropInternal(config->files, "PSPHOT.BACKMDL") ||
-    //  !pmFPAfileDropInternal (config->files, "PSPHOT.BACKMDL.STDEV") ||
-    //  !pmFPAfileDropInternal (config->files, "PSPHOT.BACKGND")) {
-    //  psError(PS_ERR_UNKNOWN, false, "Unable to drop PSPHOT internal files.");
-    //  return false;
-    // }
 
-    // pmFPAfileActivate(config->files, false, "PSPHOT.INPUT");
-    // pmFPAfileActivate(config->files, false, "PSPHOT.LOAD.PSF");
+
 
 
Index: /branches/cnb_branch_20090215/ppSub/src/ppSubReadoutSubtract.c
===================================================================
--- /branches/cnb_branch_20090215/ppSub/src/ppSubReadoutSubtract.c	(revision 21535)
+++ /branches/cnb_branch_20090215/ppSub/src/ppSubReadoutSubtract.c	(revision 21536)
@@ -6,18 +6,30 @@
  *
  *  @author IfA
- *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2009-02-09 21:26:05 $
+ *  @version $Revision: 1.4.4.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-19 17:59:49 $
  *  Copyright 2009 Institute for Astronomy, University of Hawaii
  */
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <pslib.h>
+#include <psmodules.h>
+
 #include "ppSub.h"
+
 #define WCS_TOLERANCE 0.001             // Tolerance for WCS
 
-bool ppSubReadoutSubtract (pmConfig *config, const pmFPAview *view) {
+bool ppSubReadoutSubtract(pmConfig *config, const pmFPAview *view)
+{
+    psAssert(config, "Require configuration");
+    psAssert(view, "Require view");
 
-    bool mdok = false;
 
     // Look up recipe values
-    psMetadata *recipe = psMetadataLookupMetadata(&mdok, config->recipes, PPSUB_RECIPE); // Recipe for ppSim
+    bool mdok = false;                  // Status of MD lookup
+    psMetadata *recipe = psMetadataLookupMetadata(&mdok, config->recipes, PPSUB_RECIPE); // Recipe for ppSub
     psAssert(recipe, "We checked this earlier, so it should be here.");
 
@@ -25,6 +37,6 @@
 
     // Subtraction is: minuend - subtrahend
-    pmReadout *minuend = NULL;
-    pmReadout *subtrahend = NULL;
+    pmReadout *minuend = NULL;          // Positive image
+    pmReadout *subtrahend = NULL;       // Negative image
     if (reverse) {
         minuend = pmFPAfileThisReadout(config->files, view, "PPSUB.REF.CONV");
@@ -59,4 +71,10 @@
     outRO->mask = (psImage*)psBinaryOp(outRO->mask, minuend->mask, "|", subtrahend->mask);
 
+    psArray *covars = psArrayAlloc(2);  // Covariance pseudo-matrices
+    covars->data[0] = psMemIncrRefCounter(minuend->covariance);
+    covars->data[1] = psMemIncrRefCounter(subtrahend->covariance);
+    outRO->covariance = psImageCovarianceSum(covars);
+    psFree(covars);
+
     outRO->data_exists = true;
     outRO->parent->data_exists = true;
@@ -65,11 +83,9 @@
     pmSubtractionVisualShowSubtraction(minuend->image, subtrahend->image, outRO->image);
 
-    // copy concepts from the input to the output (XXX should this always use minuend?)
-    pmFPAfile *inFile = psMetadataLookupPtr (&mdok, config->files, "PPSUB.INPUT");
-    pmFPA *inFPA = inFile->fpa;
-
-    pmFPAfile *outFile = psMetadataLookupPtr (&mdok, config->files, "PPSUB.OUTPUT");
-    pmFPA *outFPA = outFile->fpa;
-
+    // Copy concepts from the input to the output
+    pmFPAfile *inFile = psMetadataLookupPtr(&mdok, config->files, "PPSUB.INPUT"); // Input file
+    pmFPA *inFPA = inFile->fpa;         // Input FPA
+    pmFPAfile *outFile = psMetadataLookupPtr(&mdok, config->files, "PPSUB.OUTPUT"); // Output file
+    pmFPA *outFPA = outFile->fpa;       // Output FPA
     if (!pmFPACopyConcepts(outFPA, inFPA)) {
         psError(PS_ERR_UNKNOWN, false, "Unable to copy concepts from input to output.");
@@ -78,21 +94,17 @@
     }
 
-    // get the HDUs and output Chip to copy the astrometry
-    pmHDU *inHDU = inFPA->hdu;        // input HDU
-    pmHDU *outHDU = outFPA->hdu;
-    pmChip *outChip = pmFPAfileThisChip(config->files, view, "PPSUB.OUTPUT");
-
+    // Copy astrometry over
+    // It should find its way into the output images and photometry
+    pmHDU *inHDU = inFPA->hdu;          // Input HDU
+    pmHDU *outHDU = outFPA->hdu;        // Output HDU
+    pmChip *outChip = pmFPAfileThisChip(config->files, view, "PPSUB.OUTPUT"); // Output chip
     if (!outHDU || !inHDU) {
         psError(PS_ERR_UNKNOWN, false, "Unable to find HDU at FPA level to copy astrometry.");
         return false;
     }
-
-    // Copy astrometry over
-    // It should get into the output images and photometry
     if (!pmAstromReadWCS(outFPA, outChip, inHDU->header, 1.0)) {
         psError(PS_ERR_UNKNOWN, false, "Unable to read WCS astrometry from input FPA.");
         return false;
     }
-
     if (!pmAstromWriteWCS(outHDU->header, outFPA, outChip, WCS_TOLERANCE)) {
         psError(PS_ERR_UNKNOWN, false, "Unable to write WCS astrometry to output FPA.");
@@ -102,17 +114,2 @@
     return true;
 }
-
-// XXX this test code was in place to check for and squash unexpected NANs
-
-#if 0
-    pmReadoutMaskApply(outRO, maskBad);
-
-    for (int y = 0; y < outRO->image->numRows; y++) {
-        for (int x = 0; x < outRO->image->numCols; x++) {
-            if (isnan(outRO->image->data.F32[y][x]) && !(outRO->mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] & maskVal)) {
-                printf("Unmasked NAN at %d %d --> %d\n", x, y, outRO->mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x]);
-            }
-        }
-    }
-#endif
-
Index: /branches/cnb_branch_20090215/ppSub/src/ppSubReadoutUpdate.c
===================================================================
--- /branches/cnb_branch_20090215/ppSub/src/ppSubReadoutUpdate.c	(revision 21535)
+++ /branches/cnb_branch_20090215/ppSub/src/ppSubReadoutUpdate.c	(revision 21536)
@@ -6,17 +6,25 @@
  *
  *  @author IfA
- *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2009-02-07 00:15:00 $
+ *  @version $Revision: 1.3.4.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-19 17:59:50 $
  *  Copyright 2009 Institute for Astronomy, University of Hawaii
  */
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <pslib.h>
+#include <psmodules.h>
+
 #include "ppSub.h"
 
-/**
- * Renormalize, update headers and generate JPEGs
- */
-bool ppSubReadoutUpdate (pmConfig *config, const pmFPAview *view) {
+bool ppSubReadoutUpdate(pmConfig *config, psMetadata *stats, const pmFPAview *view)
+{
+    psAssert(config, "Require configuration");
+    psAssert(view, "Require view");
 
-    bool mdok = false;
+    bool mdok = false;                  // Status of MD lookup
 
     // Look up recipe values
@@ -24,17 +32,8 @@
     psAssert(recipe, "We checked this earlier, so it should be here.");
 
-    // select the output readout
-    pmReadout *outRO = pmFPAfileThisReadout(config->files, view, "PPSUB.OUTPUT");
-
-    // Renormalising for pixels, because that's what magic desires
-    if (!ppSubReadoutRenormPixels (config, recipe, outRO)) {
-        psError(PS_ERR_BAD_PARAMETER_VALUE, false, "failure in renormalization");
-        return false;
-    }
-
-    // select the output FPA and HDU to get the output header
-    pmFPAfile *outFile = psMetadataLookupPtr (&mdok, config->files, "PPSUB.OUTPUT");
-    pmFPA *outFPA = outFile->fpa;
-    pmHDU *outHDU = outFPA->hdu;
+    pmFPAfile *outFile = psMetadataLookupPtr(&mdok, config->files, "PPSUB.OUTPUT"); // Output file
+    pmReadout *outRO = pmFPAfileThisReadout(config->files, view, "PPSUB.OUTPUT"); // Output image
+    pmFPA *outFPA = outFile->fpa;       // Output FPA
+    pmHDU *outHDU = outFPA->hdu;        // Output HDU
 
     // Add additional data to the header
@@ -46,4 +45,22 @@
                      "Subtraction input", inFile->filename);
 
+    // Statistics on the matching
+    if (stats) {
+        psMetadataCopySingle(stats, outRO->analysis, PM_SUBTRACTION_ANALYSIS_MODE);
+        psMetadataCopySingle(stats, outRO->analysis, PM_SUBTRACTION_ANALYSIS_STAMPS);
+        psMetadataCopySingle(stats, outRO->analysis, PM_SUBTRACTION_ANALYSIS_DEV_MEAN);
+        psMetadataCopySingle(stats, outRO->analysis, PM_SUBTRACTION_ANALYSIS_DEV_RMS);
+        psMetadataCopySingle(stats, outRO->analysis, PM_SUBTRACTION_ANALYSIS_NORM);
+        psMetadataCopySingle(stats, outRO->analysis, PM_SUBTRACTION_ANALYSIS_BGDIFF);
+        psMetadataCopySingle(stats, outRO->analysis, PM_SUBTRACTION_ANALYSIS_MX);
+        psMetadataCopySingle(stats, outRO->analysis, PM_SUBTRACTION_ANALYSIS_MY);
+        psMetadataCopySingle(stats, outRO->analysis, PM_SUBTRACTION_ANALYSIS_MXX);
+        psMetadataCopySingle(stats, outRO->analysis, PM_SUBTRACTION_ANALYSIS_MXY);
+        psMetadataCopySingle(stats, outRO->analysis, PM_SUBTRACTION_ANALYSIS_MYY);
+
+        psMetadataAddF32(stats, PS_LIST_TAIL, "TIME_MATCH", 0, "Time to match PSFs",
+                         psTimerClear("PPSUB_MATCH"));
+    }
+
     // Generate binned JPEGs
     {
@@ -54,9 +71,8 @@
 
         // Target cells
-        pmCell *cell1 = pmFPAfileThisCell(config->files, view, "PPSUB.OUTPUT.JPEG1");
-        pmCell *cell2 = pmFPAfileThisCell(config->files, view, "PPSUB.OUTPUT.JPEG2");
+        pmCell *cell1 = pmFPAfileThisCell(config->files, view, "PPSUB.OUTPUT.JPEG1"); // Rebinned cell once
+        pmCell *cell2 = pmFPAfileThisCell(config->files, view, "PPSUB.OUTPUT.JPEG2"); // Rebinned cell twice
 
-        pmReadout *ro1 = pmReadoutAlloc(cell1);
-        pmReadout *ro2 = pmReadoutAlloc(cell2); // Binned readouts
+        pmReadout *ro1 = pmReadoutAlloc(cell1), *ro2 = pmReadoutAlloc(cell2); // Binned readouts
         if (!pmReadoutRebin(ro1, outRO, maskBad, bin1, bin1)) {
             psError(PS_ERR_UNKNOWN, false, "Unable to bin output (1st binning)");
Index: /branches/cnb_branch_20090215/ppSub/src/ppSubSetMasks.c
===================================================================
--- /branches/cnb_branch_20090215/ppSub/src/ppSubSetMasks.c	(revision 21535)
+++ /branches/cnb_branch_20090215/ppSub/src/ppSubSetMasks.c	(revision 21536)
@@ -6,22 +6,26 @@
  *
  *  @author IfA
- *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2009-02-06 01:37:17 $
+ *  @version $Revision: 1.2.4.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-19 17:59:50 $
  *  Copyright 2009 Institute for Astronomy, University of Hawaii
  */
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <pslib.h>
+#include <psmodules.h>
+#include <psphot.h>
+
 #include "ppSub.h"
 
-/** this function generates (if needed) and sets or updates the masks for both the input and
- * reference images.  this function also has the code for interpolation over bad pixels, but it
- * is currently if-def-ed out
- */
+bool ppSubSetMasks(pmConfig *config, const pmFPAview *view)
+{
+    psAssert(config, "Require configuration");
+    psAssert(view, "Require view");
 
-bool ppSubSetMasks (pmConfig *config, const pmFPAview *view) {
-
-    psImageMaskType maskValue;
-    psImageMaskType markValue;
-    bool mdok = false;
-
+    psImageMaskType maskValue, markValue; // Mask values
     if (!pmConfigMaskSetBits(&maskValue, &markValue, config)) {
         psError(PS_ERR_UNKNOWN, false, "Unable to determine mask value.");
@@ -29,16 +33,16 @@
     }
 
-    // set the mask bits needed by psphot (in psphot recipe) 
+    // Set the mask bits needed by psphot (in psphot recipe)
     psphotSetMaskRecipe (config, maskValue, markValue);
 
     // Look up recipe values
-    psMetadata *recipe = psMetadataLookupMetadata(&mdok, config->recipes, PPSUB_RECIPE); // Recipe for ppSim
+    psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSUB_RECIPE); // Recipe for ppSim
     psAssert(recipe, "We checked this earlier, so it should be here.");
 
     psImageMaskType satValue = pmConfigMaskGet("SAT", config);
-    psAssert (satValue, "SAT must be non-zero");
+    psAssert(satValue, "SAT must be non-zero");
 
     psImageMaskType badValue = pmConfigMaskGet("BAD", config);
-    psAssert (badValue, "BAD must be non-zero");
+    psAssert(badValue, "BAD must be non-zero");
 
     // input images
@@ -49,8 +53,5 @@
     psImage *reference = refRO->image;  // Reference image
     PS_ASSERT_IMAGES_SIZE_EQUAL(input, reference, false);
-
-    // XXX use psImageCopy below to avoid caring about image dimensions
-    int numCols = input->numCols;
-    int numRows = input->numRows;
+    int numCols = input->numCols, numRows = input->numRows; // Size of image
 
     // Generate masks if they don't exist
@@ -78,15 +79,12 @@
     }
     if (!pmReadoutMaskNonfinite(refRO, satValue)) {
-	psError(PS_ERR_UNKNOWN, false, "Unable to mask non-finite pixels in reference.");
-	return false;
+        psError(PS_ERR_UNKNOWN, false, "Unable to mask non-finite pixels in reference.");
+        return false;
     }
 
-#if (0)
-    // Look up recipe values
-    psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSUB_RECIPE); // Recipe for ppSim
-    psAssert(recipe, "We checked this earlier, so it should be here.");
 
+#if 0
+    // Interpolation over bad pixels: this takes a while!
     bool mdok = false;
-
     psString interpModeStr = psMetadataLookupStr(&mdok, recipe, "INTERPOLATION"); // Interpolation mode
     psImageInterpolateMode interpMode = psImageInterpolateModeFromString(interpModeStr); // Interp
@@ -102,10 +100,10 @@
     // Interpolate over bad pixels, so the bad pixels don't explode
     if (!pmReadoutInterpolateBadPixels(inRO, maskVal, interpMode, poorFrac, maskPoor, maskBad)) {
-	psError(PS_ERR_UNKNOWN, false, "Unable to interpolate bad pixels for input image.");
-	return false;
+        psError(PS_ERR_UNKNOWN, false, "Unable to interpolate bad pixels for input image.");
+        return false;
     }
     if (!pmReadoutInterpolateBadPixels(refRO, maskVal, interpMode, poorFrac, maskPoor, maskBad)) {
-	psError(PS_ERR_UNKNOWN, false, "Unable to interpolate bad pixels for reference image.");
-	return false;
+        psError(PS_ERR_UNKNOWN, false, "Unable to interpolate bad pixels for reference image.");
+        return false;
     }
     maskVal |= maskBad;
Index: /branches/cnb_branch_20090215/ppSub/src/ppSubVarianceFactors.c
===================================================================
--- /branches/cnb_branch_20090215/ppSub/src/ppSubVarianceFactors.c	(revision 21535)
+++ /branches/cnb_branch_20090215/ppSub/src/ppSubVarianceFactors.c	(revision 21536)
@@ -6,6 +6,6 @@
  *
  *  @author IfA
- *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2009-02-06 03:20:02 $
+ *  @version $Revision: 1.3.4.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-19 17:59:50 $
  *  Copyright 2009 Institute for Astronomy, University of Hawaii
  */
@@ -96,22 +96,4 @@
     vfItem->data.F32 = vf;
 
-    // Statistics on the matching
-    if (stats) {
-        psMetadataCopySingle(stats, outRO->analysis, PM_SUBTRACTION_ANALYSIS_MODE);
-        psMetadataCopySingle(stats, outRO->analysis, PM_SUBTRACTION_ANALYSIS_STAMPS);
-        psMetadataCopySingle(stats, outRO->analysis, PM_SUBTRACTION_ANALYSIS_DEV_MEAN);
-        psMetadataCopySingle(stats, outRO->analysis, PM_SUBTRACTION_ANALYSIS_DEV_RMS);
-        psMetadataCopySingle(stats, outRO->analysis, PM_SUBTRACTION_ANALYSIS_NORM);
-        psMetadataCopySingle(stats, outRO->analysis, PM_SUBTRACTION_ANALYSIS_BGDIFF);
-        psMetadataCopySingle(stats, outRO->analysis, PM_SUBTRACTION_ANALYSIS_MX);
-        psMetadataCopySingle(stats, outRO->analysis, PM_SUBTRACTION_ANALYSIS_MY);
-        psMetadataCopySingle(stats, outRO->analysis, PM_SUBTRACTION_ANALYSIS_MXX);
-        psMetadataCopySingle(stats, outRO->analysis, PM_SUBTRACTION_ANALYSIS_MXY);
-        psMetadataCopySingle(stats, outRO->analysis, PM_SUBTRACTION_ANALYSIS_MYY);
-
-        psMetadataAddF32(stats, PS_LIST_TAIL, "TIME_MATCH", 0, "Time to match PSFs",
-                         psTimerClear("PPSUB_MATCH"));
-    }
-
     return true;
 }
Index: /branches/cnb_branch_20090215/ppSub/src/ppSubVersion.c
===================================================================
--- /branches/cnb_branch_20090215/ppSub/src/ppSubVersion.c	(revision 21535)
+++ /branches/cnb_branch_20090215/ppSub/src/ppSubVersion.c	(revision 21536)
@@ -6,8 +6,17 @@
  *
  *  @author IfA
- *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2009-02-06 01:37:17 $
+ *  @version $Revision: 1.3.2.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-19 17:59:50 $
  *  Copyright 2009 Institute for Astronomy, University of Hawaii
  */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <pslib.h>
+#include <psmodules.h>
+#include <ppStats.h>
 
 #include "ppSub.h"
Index: /branches/cnb_branch_20090215/psLib/m4/.cvsignore
===================================================================
--- /branches/cnb_branch_20090215/psLib/m4/.cvsignore	(revision 21535)
+++ /branches/cnb_branch_20090215/psLib/m4/.cvsignore	(revision 21536)
@@ -1,2 +1,7 @@
+libtool.m4
+ltoptions.m4
+ltsugar.m4
+ltversion.m4
+lt~obsolete.m4
 Makefile
 Makefile.in
Index: /branches/cnb_branch_20090215/psLib/src/math/psPolynomialUtils.c
===================================================================
--- /branches/cnb_branch_20090215/psLib/src/math/psPolynomialUtils.c	(revision 21535)
+++ /branches/cnb_branch_20090215/psLib/src/math/psPolynomialUtils.c	(revision 21536)
@@ -139,4 +139,5 @@
 // XXX determine the errors, and propagate to the output of psImageBicubeMin
 // XXX x,y are the image pixel index, but the fit is implied for the image pixel coordinates (0.5,0.5 center)
+// this solution is determined assuming constant weight per pixel
 psPolynomial2D *psImageBicubeFit(const psImage *image, int x, int y)
 {
@@ -179,5 +180,5 @@
 psPlane psImageBicubeMin(const psPolynomial2D *poly)
 {
-    psPlane min = { NAN, NAN, 0, 0 };   // Minimum value to return
+    psPlane min = { NAN, NAN, NAN, NAN };   // Minimum value to return
 
     PS_ASSERT_PTR_NON_NULL(poly, min);
@@ -186,6 +187,19 @@
 
     double det = 4*poly->coeff[2][0]*poly->coeff[0][2] - PS_SQR(poly->coeff[1][1]); // Determinant
-    min.x = (poly->coeff[1][1]*poly->coeff[0][1] - 2*poly->coeff[0][2]*poly->coeff[1][0]) / det;
-    min.y = (poly->coeff[1][1]*poly->coeff[1][0] - 2*poly->coeff[2][0]*poly->coeff[0][1]) / det;
+    double xn = (poly->coeff[1][1]*poly->coeff[0][1] - 2*poly->coeff[0][2]*poly->coeff[1][0]);
+    double yn = (poly->coeff[1][1]*poly->coeff[1][0] - 2*poly->coeff[2][0]*poly->coeff[0][1]);
+
+    min.x = xn / det;
+    min.y = yn / det;
+
+    // sigma_xn^2 / xn^2 = sigma_11^2 / C11
+
+    // without a supplied error, we calculate the normalized error
+    double fdetErr2 = 0.5/PS_SQR(poly->coeff[0][2]) + 0.5/PS_SQR(poly->coeff[2][0]) + 4.0/(6.0*PS_SQR(poly->coeff[1][1]));
+    double fxnErr2 = 1.0/(6.0*PS_SQR(poly->coeff[0][1])) + 1.0/(6.0*PS_SQR(poly->coeff[1][0])) + 1.0/(6.0*PS_SQR(poly->coeff[1][1])) + 0.5/PS_SQR(poly->coeff[0][2]);
+    double fynErr2 = 1.0/(6.0*PS_SQR(poly->coeff[0][1])) + 1.0/(6.0*PS_SQR(poly->coeff[1][0])) + 1.0/(6.0*PS_SQR(poly->coeff[1][1])) + 0.5/PS_SQR(poly->coeff[2][0]);
+
+    min.xErr = fabs(min.x) * sqrt(fxnErr2 + fdetErr2);
+    min.yErr = fabs(min.y) * sqrt(fynErr2 + fdetErr2);
 
     return min;
Index: /branches/cnb_branch_20090215/psModules/src/astrom/pmAstrometryVisual.c
===================================================================
--- /branches/cnb_branch_20090215/psModules/src/astrom/pmAstrometryVisual.c	(revision 21535)
+++ /branches/cnb_branch_20090215/psModules/src/astrom/pmAstrometryVisual.c	(revision 21536)
@@ -23,5 +23,4 @@
 
 //variables to determine when things are plotted
-static bool isVisual             = false;
 static bool plotGridMatch        = true;
 static bool plotTweak            = true;
@@ -48,10 +47,4 @@
 /* Initialization Routines  */
 
-bool pmAstromSetVisual (bool mode) {
-    isVisual = mode;
-    return true;
-}
-
-
 bool pmAstromVisualClose()
 {
@@ -68,9 +61,8 @@
 {
     // make sure we want to plot this
-    if (!plotRawStars || !isVisual) return true;
+    if (!plotRawStars || !pmVisualIsVisual()) return true;
 
     //set up plot region
     if (!pmVisualInitWindow (&kapa, "psastro:plots")){
-        isVisual = false;
         return false;
     }
@@ -222,5 +214,5 @@
 
     // pause and wait for user input:
-    pmVisualAskUser(&plotRawStars, &isVisual);
+    pmVisualAskUser(&plotRawStars);
 
     psFree (xVec);
@@ -234,9 +226,8 @@
 {
     //make sure we want to plot this
-    if (!isVisual || !plotRefStars) return true;
+    if (!pmVisualIsVisual() || !plotRefStars) return true;
 
     //set up plotting variables
     if (!pmVisualInitWindow (&kapa, "psastro:plots")) {
-        isVisual = false;
         return false;
     }
@@ -284,5 +275,5 @@
 
     // pause and wait for user input:
-    pmVisualAskUser(&plotRefStars, &isVisual);
+    pmVisualAskUser(&plotRefStars);
 
     psFree (xVec);
@@ -301,9 +292,8 @@
 
     // make sure we want to plot this
-    if ( !isVisual || !plotLumFunc ) return true;
+    if ( !pmVisualIsVisual() || !plotLumFunc ) return true;
 
     //set up plotting variables
     if ( !pmVisualInitWindow (&kapa, "psastro:plots")){
-        isVisual = false;
         return false;
     }
@@ -377,5 +367,5 @@
 
         // pause and wait for user input:
-        pmVisualAskUser (&plotLumFunc, &isVisual);
+        pmVisualAskUser (&plotLumFunc);
     }
     return true;
@@ -391,9 +381,8 @@
 
     //make sure we want to plot this
-    if (!isVisual || !plotRemoveClumps) return true;
+    if (!pmVisualIsVisual() || !plotRemoveClumps) return true;
 
     //set up plot variables
     if ( !pmVisualInitWindow (&kapa, "psastro:plots")) {
-        isVisual = false;
         return false;
     }
@@ -480,5 +469,5 @@
 
     //ask for user input and finish
-    pmVisualAskUser (&plotRemoveClumps, &isVisual);
+    pmVisualAskUser (&plotRemoveClumps);
     psFree (xVec);
     psFree (yVec);
@@ -496,9 +485,8 @@
 
     //make sure we want to plot this
-    if (!isVisual || !plotOneChipFit)
+    if (!pmVisualIsVisual() || !plotOneChipFit)
         return true;
 
     if(!pmVisualInitWindow(&kapa, "psastro:plots") || !pmVisualInitWindow(&kapa2, "psastro:plots")) {
-        isVisual = false;
         return false;
     }
@@ -511,5 +499,5 @@
 
     //ask for user input and finish
-    pmVisualAskUser(&plotOneChipFit, &isVisual);
+    pmVisualAskUser(&plotOneChipFit);
     return true;
 }
@@ -522,8 +510,7 @@
 {
     //make sure we want to plot this
-    if(!isVisual || !plotFixChips) return true;
+    if(!pmVisualIsVisual() || !plotFixChips) return true;
 
     if(!pmVisualInitWindow(&kapa, "psastro:plots")) {
-        isVisual = false;
         return false;
     }
@@ -588,5 +575,5 @@
     KapaPlotVector (kapa, xNew->n, yNew->data.F32, "y");
 
-    pmVisualAskUser(&plotFixChips, &isVisual);
+    pmVisualAskUser(&plotFixChips);
     psFree(xNew);
     psFree(yNew);
@@ -606,9 +593,8 @@
 
     //make sure we want to plot this
-    if (!isVisual || !plotAstromGuessCheck) return true;
+    if (!pmVisualIsVisual() || !plotAstromGuessCheck) return true;
 
     //set up graph window
     if ( !pmVisualInitWindow (&kapa, "psastro:plots")) {
-        isVisual = false;
         return false;
     }
@@ -686,5 +672,5 @@
     psFree(xResid);
     psFree(yResid);
-    pmVisualAskUser (&plotAstromGuessCheck, &isVisual);
+    pmVisualAskUser (&plotAstromGuessCheck);
     return true;
 }
@@ -696,8 +682,7 @@
 {
     //make sure we want to plot this
-    if (!isVisual || !plotCommonScale) return true;
+    if (!pmVisualIsVisual() || !plotCommonScale) return true;
 
     if (!pmVisualInitWindow(&kapa, "psastro:plots")){
-        isVisual = false;
         return false;
     }
@@ -736,5 +721,5 @@
     KapaSendLabel (kapa, "Old Pixel Scale of FPA Chips (Not to Scale)", KAPA_LABEL_XP);
 
-    pmVisualAskUser (&plotCommonScale, &isVisual);
+    pmVisualAskUser (&plotCommonScale);
 
     psFree(xVec);
@@ -750,8 +735,7 @@
 
     //make sure we want to plot this
-    if (!isVisual || !plotMosaicOneChip) return true;
+    if (!pmVisualIsVisual() || !plotMosaicOneChip) return true;
 
     if(!pmVisualInitWindow(&kapa, "psastro:plots") || !pmVisualInitWindow(&kapa2, "psastro:plots")) {
-        isVisual = false;
         return false;
     }
@@ -759,10 +743,10 @@
     //plot the residuals
     if (!residPlot(rawstars, refstars, match, recipe, "Single Chip Fit Residuals - Mosaic Mode")) {
-        isVisual = false;
+        pmVisualSetVisual(false);
         return false;
     }
 
     //ask for user input and finish
-    pmVisualAskUser(&plotMosaicOneChip, &isVisual);
+    pmVisualAskUser(&plotMosaicOneChip);
 
     return true;
@@ -775,5 +759,5 @@
 {
     //make sure we want to plot this
-    if (!isVisual || !plotMosaicMatches) return true;
+    if (!pmVisualIsVisual() || !plotMosaicMatches) return true;
 
     char title[60];
@@ -782,15 +766,14 @@
 
     if(!pmVisualInitWindow(&kapa, "psastro:plots") || !pmVisualInitWindow(&kapa2, "psastro:plots")) {
-        isVisual = false;
         return false;
     }
 
     if (!residPlot(rawstars, refstars, match, recipe, title)){
-        isVisual = false;
+        pmVisualSetVisual(false);
         return false;
     }
 
     //ask for user input
-    pmVisualAskUser (&plotMosaicMatches, &isVisual);
+    pmVisualAskUser (&plotMosaicMatches);
     return true;
 }
@@ -807,7 +790,6 @@
 {
     //make sure we want to plot this
-    if (!isVisual || !plotGridMatch) return true;
+    if (!pmVisualIsVisual() || !plotGridMatch) return true;
     if (!pmVisualInitWindow(&kapa, "psastro:plots")){
-        isVisual = false;
         return false;
     }
@@ -952,5 +934,5 @@
     KapaPlotVector (kapa, 2, yslice, "y");
 
-    pmVisualAskUser(&plotGridMatch, &isVisual);
+    pmVisualAskUser(&plotGridMatch);
     psFree(dXplot);
     psFree(dYplot);
@@ -966,7 +948,6 @@
 {
     //make sure we want to plot this
-    if (!isVisual || !plotTweak) return true;
+    if (!pmVisualIsVisual() || !plotTweak) return true;
     if (!pmVisualInitWindow(&kapa, "psastro:plots")) {
-        isVisual = false;
         return false;
     }
@@ -1051,5 +1032,5 @@
                    KAPA_LABEL_XP);
 
-    pmVisualAskUser(&plotTweak, &isVisual);
+    pmVisualAskUser(&plotTweak);
 
     psFree(xIndices);
@@ -1341,5 +1322,4 @@
 # else
 
-bool pmAstromSetVisual(bool mode) { return true; }
 bool pmAstromVisualClose() { return true; }
 bool pmAstromVisualPlotGridMatch (const psArray *raw, const psArray *ref, psImage *gridNP, double offsetX, double offsetY, double maxOffpix, double Scale, double Offset) { return true; }
Index: /branches/cnb_branch_20090215/psModules/src/astrom/pmAstrometryVisual.h
===================================================================
--- /branches/cnb_branch_20090215/psModules/src/astrom/pmAstrometryVisual.h	(revision 21535)
+++ /branches/cnb_branch_20090215/psModules/src/astrom/pmAstrometryVisual.h	(revision 21536)
@@ -22,10 +22,4 @@
     int sPeak;                          ///< sum of stars to peak bin
 } pmLumFunc;
-
-
-/** Enable or disable visual plotting for psastro routines
- * @param mode true/false to enable/disable plotting
- * @return true for success */
-bool pmAstromSetVisual(bool mode);
 
 
Index: /branches/cnb_branch_20090215/psModules/src/camera/pmFPACopy.c
===================================================================
--- /branches/cnb_branch_20090215/psModules/src/camera/pmFPACopy.c	(revision 21535)
+++ /branches/cnb_branch_20090215/psModules/src/camera/pmFPACopy.c	(revision 21536)
@@ -457,4 +457,31 @@
     psMetadataCopy(target->parent->concepts, source->parent->concepts);
 
+    // Update the astrometric parameters
+    target->toFPA = psMemIncrRefCounter (source->toFPA);
+    target->fromFPA = psMemIncrRefCounter (source->fromFPA);
+
+    // Update the parent fpa astrometry parameters, or check that they match
+    pmFPA *targetFPA = target->parent;
+    pmFPA *sourceFPA = source->parent;
+    // XXX should we require that both of these exist?
+
+    if (targetFPA && sourceFPA) {
+	if (targetFPA->toSky) {
+	    psAssert (targetFPA->toSky == sourceFPA->toSky, "chips within FPA have inconsistent astrometry references");
+	} else {
+	    targetFPA->toSky = psMemIncrRefCounter (sourceFPA->toSky);
+	}
+	if (targetFPA->toTPA) {
+	    psAssert (targetFPA->toTPA == sourceFPA->toTPA, "chips within FPA have inconsistent astrometry references");
+	} else {
+	    targetFPA->toTPA = psMemIncrRefCounter (sourceFPA->toTPA);
+	}
+	if (targetFPA->fromTPA) {
+	    psAssert (targetFPA->fromTPA == sourceFPA->fromTPA, "chips within FPA have inconsistent astrometry references");
+	} else {
+	    targetFPA->fromTPA = psMemIncrRefCounter (sourceFPA->fromTPA);
+	}
+    }
+
     target->data_exists = true;
     return status;
Index: /branches/cnb_branch_20090215/psModules/src/detrend/pmShutterCorrection.h
===================================================================
--- /branches/cnb_branch_20090215/psModules/src/detrend/pmShutterCorrection.h	(revision 21535)
+++ /branches/cnb_branch_20090215/psModules/src/detrend/pmShutterCorrection.h	(revision 21536)
@@ -5,6 +5,6 @@
  * @author Paul Price, IfA
  *
- * @version $Revision: 1.23 $ $Name: not supported by cvs2svn $
- * @date $Date: 2009-02-12 19:33:30 $
+ * @version $Revision: 1.23.2.1 $ $Name: not supported by cvs2svn $
+ * @date $Date: 2009-02-19 17:59:50 $
  * Copyright 2006 Institute for Astronomy, University of Hawaii
  */
Index: /branches/cnb_branch_20090215/psModules/src/extras/pmVisual.c
===================================================================
--- /branches/cnb_branch_20090215/psModules/src/extras/pmVisual.c	(revision 21535)
+++ /branches/cnb_branch_20090215/psModules/src/extras/pmVisual.c	(revision 21536)
@@ -28,4 +28,23 @@
 # define KAPAY 700
 
+static bool isVisual = false;
+
+
+bool pmVisualSetVisual(bool value) {
+    isVisual = value;
+    return true;
+}
+
+
+bool pmVisualIsVisual(void) {return isVisual;}
+
+bool pmVisualClose(void) {
+    pmAstrometryVisualClose();
+    pmSubtractionVisualClose();
+    pmStackVisualClose();
+    //XXX handle psphot
+    //    psphotVisualClose();
+    return true;
+}
 
 bool pmVisualInitWindow (int *kapid, char *name) {
@@ -34,4 +53,5 @@
         if (*kapid == -1) {
             fprintf (stderr, "Failure to open kapa.\n");
+            isVisual = false;
             return false;
         }
@@ -52,5 +72,5 @@
 
 
-bool pmVisualAskUser(bool *plotFlag, bool *packageFlag)
+bool pmVisualAskUser(bool *plotFlag)
 {
     char key[10];
@@ -63,5 +83,5 @@
     }
     if (key[0] == 'a') {
-        *packageFlag = false;
+        isVisual = false;
     }
     return true;
@@ -304,9 +324,11 @@
 
 #else
-
+bool pmVisualSetVisual(bool value) {return true;}
+bool pmVisualIsVisual(void) {return false;}
+bool pmVisualClose(void) {return true;}
 bool pmVisualInitWindow(int *kapid, char *name){return true;}
 bool pmVisualInitGraph (int kapa, void *section, void *graphdata){return true;}
 
-bool pmVisualAskUser(bool *plotFlag, bool *packageFlag){return true;}
+bool pmVisualAskUser(bool *plotFlag){return true;}
 bool pmVisualImStats(psImage *image, double *mean,
                      double *stdev, double *min, double *max){return true;}
Index: /branches/cnb_branch_20090215/psModules/src/extras/pmVisual.h
===================================================================
--- /branches/cnb_branch_20090215/psModules/src/extras/pmVisual.h	(revision 21535)
+++ /branches/cnb_branch_20090215/psModules/src/extras/pmVisual.h	(revision 21536)
@@ -10,4 +10,22 @@
 
 #if (HAVE_KAPA)
+
+
+/** Globally enable or disable plotting
+ * @param value - true to enable plotting
+ * @return true
+ */
+bool pmVisualSetVisual(bool value);
+
+
+/** Check whether plotting is enabled
+ * @retrun true if plots should be generated
+ */
+bool pmVisualIsVisual(void);
+
+
+/** Destroy plotting windows at the end of a run
+ * @return true for success */
+bool pmVisualClose(void);
 
 
@@ -32,8 +50,6 @@
  * At the user's request, this will disable diagnostic plotting.
  * @param plotFlag, set to false if this plot should be disabled in the future
- * @param packageFlag, set to false if all plots from this package (e.g. psastro, pmSubtraction)
- *                      should be disabled.
  */
-bool pmVisualAskUser(bool *plotFlag, bool *packageFlag);
+bool pmVisualAskUser(bool *plotFlag);
 
 
@@ -115,7 +131,10 @@
 
 // kapa-specific data types are changed to void
+bool pmVisualSetVisual(bool value);
+bool pmVisualIsVisual(void);
+bool pmVisualClose(void);
 bool pmVisualInitWindow (int *kapid, char *name);
 bool pmVisualInitGraph (int kapa, void *section, void *graphdata);
-bool pmVisualAskUser(bool *plotFlag, bool *packageFlag);
+bool pmVisualAskUser(bool *plotFlag);
 bool pmVisualScaleImage(int kapaFD, psImage *inImage,
                         const char *name, int channel, bool clip);
Index: /branches/cnb_branch_20090215/psModules/src/imcombine/Makefile.am
===================================================================
--- /branches/cnb_branch_20090215/psModules/src/imcombine/Makefile.am	(revision 21535)
+++ /branches/cnb_branch_20090215/psModules/src/imcombine/Makefile.am	(revision 21536)
@@ -19,5 +19,6 @@
 	pmSubtractionThreads.c	\
 	pmPSFEnvelope.c         \
-	pmSubtractionVisual.c
+	pmSubtractionVisual.c   \
+	pmStackVisual.c
 
 pkginclude_HEADERS = \
@@ -37,5 +38,6 @@
 	pmSubtractionThreads.h	\
 	pmPSFEnvelope.h         \
-	pmSubtractionVisual.h
+	pmSubtractionVisual.h   \
+	pmStackVisual.h
 
 CLEANFILES = *~
Index: /branches/cnb_branch_20090215/psModules/src/imcombine/pmPSFEnvelope.c
===================================================================
--- /branches/cnb_branch_20090215/psModules/src/imcombine/pmPSFEnvelope.c	(revision 21535)
+++ /branches/cnb_branch_20090215/psModules/src/imcombine/pmPSFEnvelope.c	(revision 21536)
@@ -30,8 +30,8 @@
 
 #include "pmPSFEnvelope.h"
-
-
-
-//#define TESTING                         // Enable test output
+#include "pmStackVisual.h"
+
+
+#define TESTING                         // Enable test output
 #define PEAK_FLUX 1.0e4                 // Peak flux for each source
 #define SKY_VALUE 0.0e0                 // Sky value for fake image
@@ -162,4 +162,5 @@
             psStringAppend(&name, "psf_field_%03d.fits", i);
             psFits *fits = psFitsOpen(name, "w");
+            pmStackVisualPlotTestImage(fakeRO->image, name);
             psFitsWriteImage(fits, NULL, fakeRO->image, 0, NULL);
             psFitsClose(fits);
@@ -179,4 +180,5 @@
         // Write out the envelope
         psFits *fits = psFitsOpen("psf_field_envelope.fits", "w");
+        pmStackVisualPlotTestImage(envelope, "psf_field_envelope.fits");
         psFitsWriteImage(fits, NULL, envelope, 0, NULL);
         psFitsClose(fits);
@@ -231,4 +233,5 @@
         // Write out the envelope
         psFits *fits = psFitsOpen("psf_field_full.fits", "w");
+        pmStackVisualPlotTestImage(readout->image, "psf_field_full.fits");
         psFitsWriteImage(fits, NULL, readout->image, 0, NULL);
         psFitsClose(fits);
@@ -312,4 +315,5 @@
         {
             psFits *fits = psFitsOpen("psf_field_model.fits", "w");
+            pmStackVisualPlotTestImage(generated->image, "psf_field_model.fits");
             psFitsWriteImage(fits, NULL, generated->image, 0, NULL);
             psFitsClose(fits);
@@ -318,4 +322,5 @@
         {
             psFits *fits = psFitsOpen("psf_field_resid.fits", "w");
+            pmStackVisualPlotTestImage(generated->image, "psf_field_resid.fits");
             psFitsWriteImage(fits, NULL, generated->image, 0, NULL);
             psFitsClose(fits);
Index: /branches/cnb_branch_20090215/psModules/src/imcombine/pmStack.c
===================================================================
--- /branches/cnb_branch_20090215/psModules/src/imcombine/pmStack.c	(revision 21535)
+++ /branches/cnb_branch_20090215/psModules/src/imcombine/pmStack.c	(revision 21536)
@@ -8,6 +8,6 @@
  *  @author GLG, MHPCC
  *
- *  @version $Revision: 1.48 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2009-02-13 23:52:14 $
+ *  @version $Revision: 1.48.2.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-19 17:59:50 $
  *  Copyright 2004-2007 Institute for Astronomy, University of Hawaii
  *
@@ -33,7 +33,8 @@
 #define NUM_DIRECT_STDEV 5              // For less than this number of values, measure stdev directly
 
-//#define TESTING                         // Enable test output
-//#define TEST_X 2318                     // x coordinate to examine
-//#define TEST_Y 2306                     // y coordinate to examine
+//CNB change all of these to false
+#define TESTING                         // Enable test output
+#define TEST_X 2318                     // x coordinate to examine
+#define TEST_Y 2306                     // y coordinate to examine
 
 
Index: /branches/cnb_branch_20090215/psModules/src/imcombine/pmSubtractionIO.c
===================================================================
--- /branches/cnb_branch_20090215/psModules/src/imcombine/pmSubtractionIO.c	(revision 21535)
+++ /branches/cnb_branch_20090215/psModules/src/imcombine/pmSubtractionIO.c	(revision 21536)
@@ -16,4 +16,5 @@
 
 #include "pmSubtractionIO.h"
+#include "pmStackVisual.h"
 
 #define ARRAY_BUFFER 16                 // Number to add to array at a time
@@ -144,6 +145,6 @@
     // CVS tags, used to identify the version of this file (in case incompatibilities are introduced)
     psString cvsFile = psStringCopy("$RCSfile: pmSubtractionIO.c,v $");
-    psString cvsRev  = psStringCopy("$Revision: 1.9 $");
-    psString cvsDate = psStringCopy("$Date: 2008-10-24 21:21:06 $");
+    psString cvsRev  = psStringCopy("$Revision: 1.9.18.1 $");
+    psString cvsDate = psStringCopy("$Date: 2009-02-19 17:59:50 $");
     psStringSubstitute(&cvsFile, NULL, "RCSfile: ");
     psStringSubstitute(&cvsRev,  NULL, "Revision: ");
@@ -167,4 +168,6 @@
 
     psImage *image = psMetadataLookupPtr(NULL, ro->analysis, PM_SUBTRACTION_ANALYSIS_KERNEL_IMAGE); // Image
+    pmStackVisualPlotTestImage(image, "Subtraction_kernels.fits");
+
     if (image && !psFitsWriteImage(fits, header, image, 0, EXTNAME_IMAGE)) {
         psError(PS_ERR_IO, false, "Unable to write subtraction kernel image.");
Index: /branches/cnb_branch_20090215/psModules/src/imcombine/pmSubtractionVisual.c
===================================================================
--- /branches/cnb_branch_20090215/psModules/src/imcombine/pmSubtractionVisual.c	(revision 21535)
+++ /branches/cnb_branch_20090215/psModules/src/imcombine/pmSubtractionVisual.c	(revision 21536)
@@ -28,5 +28,4 @@
 
 //variables to determine when things are plotted
-static bool isVisual             = false;
 static bool plotConvKernels      = true;
 static bool plotStamps           = true;
@@ -42,9 +41,4 @@
 // Initialization Routines
 
-/** start or stop plotting */
-bool pmSubtractionSetVisual (bool mode) {
-    isVisual = mode;
-    return true;
-}
 
 
@@ -65,11 +59,10 @@
  *    @return true for success */
 bool pmSubtractionVisualPlotConvKernels(psImage *convKernels) {
-    if (!isVisual || !plotConvKernels) return true;
+    if (!pmVisualIsVisual() || !plotConvKernels) return true;
     if (!pmVisualInitWindow(&kapa, "ppSub:Images")) {
-        isVisual = false;
         return false;
     }
     pmVisualScaleImage(kapa, convKernels, "Convolution_Kernels", 0, true);
-    pmVisualAskUser(&plotConvKernels, &isVisual);
+    pmVisualAskUser(&plotConvKernels);
     return true;
 }
@@ -80,11 +73,9 @@
     @return true for success */
 bool pmSubtractionVisualPlotStamps(pmSubtractionStampList *stamps, pmReadout *ro) {
-    if (!isVisual || !plotStamps) return true;
+    if (!pmVisualIsVisual() || !plotStamps) return true;
     if (!pmVisualInitWindow (&kapa, "ppSub:Images")) {
-        isVisual = false;
         return false;
     }
     if (!pmVisualInitWindow (&kapa2, "ppSub:StampMasterImage")) {
-        isVisual = false;
         return false;
     }
@@ -145,5 +136,5 @@
     pmVisualScaleImage(kapa, canvas, "Subtraction_Stamps", 0, true);
 
-    pmVisualAskUser(&plotStamps, &isVisual);
+    pmVisualAskUser(&plotStamps);
     return true;
 }
@@ -152,7 +143,6 @@
 bool pmSubtractionVisualPlotLeastSquares (pmSubtractionStampList *stamps, bool dual) {
 
-    if (!isVisual || !plotLeastSquares) return true;
+    if (!pmVisualIsVisual() || !plotLeastSquares) return true;
     if (!pmVisualInitWindow (&kapa, "PPSub:Images")) {
-        isVisual = false;
         return false;
     }
@@ -209,5 +199,5 @@
     pmVisualScaleImage(kapa, canvas32, "Least_Squares", 0, true);
 
-    pmVisualAskUser(&plotLeastSquares, &isVisual);
+    pmVisualAskUser(&plotLeastSquares);
     psFree(canvas);
     psFree(canvas32);
@@ -216,7 +206,6 @@
 
 bool pmSubtractionVisualShowSubtraction(psImage *image, psImage *ref, psImage *sub) {
-    if (!isVisual || !plotImage) return true;
+    if (!pmVisualIsVisual() || !plotImage) return true;
     if (!pmVisualInitWindow (&kapa, "PPSub:Images")) {
-        isVisual = false;
         return false;
     }
@@ -225,5 +214,5 @@
     pmVisualScaleImage(kapa, ref, "Reference", 1, true);
     pmVisualScaleImage(kapa, sub, "Subtraction", 2, true);
-    pmVisualAskUser(&plotImage, &isVisual);
+    pmVisualAskUser(&plotImage);
     return true;
 }
@@ -267,5 +256,4 @@
 
 #else
-bool pmSubtractionSetVisual (bool mode) {return true;}
 bool pmSubtractionVisualClose() {return true;}
 bool pmSubtractionVisualPlotConvKernels(psImage *convKernels) {return true;}
Index: /branches/cnb_branch_20090215/psModules/src/imcombine/pmSubtractionVisual.h
===================================================================
--- /branches/cnb_branch_20090215/psModules/src/imcombine/pmSubtractionVisual.h	(revision 21535)
+++ /branches/cnb_branch_20090215/psModules/src/imcombine/pmSubtractionVisual.h	(revision 21536)
@@ -2,5 +2,4 @@
 #define PM_SUBTRACTION_VISUAL_H
 
-bool pmSubtractionSetVisual (bool mode);
 bool pmSubtractionVisualClose();
 bool pmSubtractionVisualPlotConvKernels(psImage *convKernels);
Index: /branches/cnb_branch_20090215/psModules/src/objects/Makefile.am
===================================================================
--- /branches/cnb_branch_20090215/psModules/src/objects/Makefile.am	(revision 21535)
+++ /branches/cnb_branch_20090215/psModules/src/objects/Makefile.am	(revision 21536)
@@ -36,4 +36,5 @@
 	pmSourceIO_PS1_DEV_1.c \
 	pmSourceIO_PS1_CAL_0.c \
+	pmSourceIO_CMF_PS1_V1.c \
 	pmSourcePlots.c \
 	pmSourcePlotPSFModel.c \
Index: /branches/cnb_branch_20090215/psModules/src/objects/pmModel.c
===================================================================
--- /branches/cnb_branch_20090215/psModules/src/objects/pmModel.c	(revision 21535)
+++ /branches/cnb_branch_20090215/psModules/src/objects/pmModel.c	(revision 21536)
@@ -6,6 +6,6 @@
  *  @author EAM, IfA
  *
- *  @version $Revision: 1.27 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2009-02-06 20:54:14 $
+ *  @version $Revision: 1.27.4.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-19 17:59:50 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -59,4 +59,5 @@
     tmp->chisqNorm = 0.0;
     tmp->nDOF  = 0;
+    tmp->nPix  = 0;
     tmp->nIter = 0;
     tmp->radiusFit = 0;
@@ -234,14 +235,14 @@
 
     if (model->residuals) {
-	DX = xBin*(image->col0 - xCenter - dx) + model->residuals->xCenter + 0.5;
-	DY = yBin*(image->row0 - yCenter - dy) + model->residuals->yCenter + 0.5;
-	Ro = (model->residuals->Ro)   ? model->residuals->Ro->data.F32 : NULL;
-	Rx = (model->residuals->Rx)   ? model->residuals->Rx->data.F32 : NULL;
-	Ry = (model->residuals->Ry)   ? model->residuals->Ry->data.F32 : NULL;
-	Rm = (model->residuals->mask) ? model->residuals->mask->data.PS_TYPE_IMAGE_MASK_DATA : NULL;
-	if (Ro) {
-	    NX = model->residuals->Ro->numCols;
-	    NY = model->residuals->Ro->numRows;
-	}	    
+        DX = xBin*(image->col0 - xCenter - dx) + model->residuals->xCenter + 0.5;
+        DY = yBin*(image->row0 - yCenter - dy) + model->residuals->yCenter + 0.5;
+        Ro = (model->residuals->Ro)   ? model->residuals->Ro->data.F32 : NULL;
+        Rx = (model->residuals->Rx)   ? model->residuals->Rx->data.F32 : NULL;
+        Ry = (model->residuals->Ry)   ? model->residuals->Ry->data.F32 : NULL;
+        Rm = (model->residuals->mask) ? model->residuals->mask->data.PS_TYPE_IMAGE_MASK_DATA : NULL;
+        if (Ro) {
+            NX = model->residuals->Ro->numCols;
+            NY = model->residuals->Ro->numRows;
+        }
     }
 
@@ -255,5 +256,5 @@
 
             // XXX should we use using 0.5 pixel offset?
-	    // Convert to coordinate in parent image, with offset (dx,dy)
+            // Convert to coordinate in parent image, with offset (dx,dy)
             imageCol = ix + image->col0 - dx;
             imageRow = iy + image->row0 - dy;
@@ -275,56 +276,56 @@
                 float rx = xBin*ix + DX;
 
-		int rx0 = rx - 0.5;
-		int rx1 = rx + 0.5;
-		int ry0 = ry - 0.5;
-		int ry1 = ry + 0.5;
-
-		if (rx0 < 0) goto skip;
-		if (ry0 < 0) goto skip;
-		if (rx1 >= NX) goto skip;
-		if (ry1 >= NY) goto skip;
-
-		// these go from 0.0 to 1.0 between the centers of the pixels 
-		float fx = rx - 0.5 - rx0;
-		float Fx = 1.0 - fx;
-		float fy = ry - 0.5 - ry0;
-		float Fy = 1.0 - fy;
-
-		// check the residual image mask (if set). give up if any of the 4 pixels are masked.
-		if (Rm) {
-		    if (Rm[ry0][rx0]) goto skip;
-		    if (Rm[ry0][rx1]) goto skip;
-		    if (Rm[ry1][rx0]) goto skip;
-		    if (Rm[ry1][rx1]) goto skip;
-		}
-
-		// a possible further optimization if we re-use these values
-		// XXX allow for masked pixels, and add pixel weights
-		float V0 = (Ro[ry0][rx0]*Fx + Ro[ry0][rx1]*fx);
-		float V1 = (Ro[ry1][rx0]*Fx + Ro[ry1][rx1]*fx);
-		float Vo = V0*Fy + V1*fy;
-		if (!isfinite(Vo)) goto skip;
-
-		float Vx = 0.0;
-		float Vy = 0.0;
-
-		// skip Rx,Ry if Ro is masked
-		if (Rx && Ry && (mode & PM_MODEL_OP_RES1)) {
-		    V0 = (Rx[ry0][rx0]*Fx + Rx[ry0][rx1]*fx);
-		    V1 = (Rx[ry1][rx0]*Fx + Rx[ry1][rx1]*fx);
-		    Vx = V0*Fy + V1*fy;
-
-		    V0 = (Ry[ry0][rx0]*Fx + Ry[ry0][rx1]*fx);
-		    V1 = (Ry[ry1][rx0]*Fx + Ry[ry1][rx1]*fx);
-		    Vy = V0*Fy + V1*fy;
-		}
-		if (!isfinite(Vx)) goto skip;
-		if (!isfinite(Vy)) goto skip;
-
-		// 2D residual variations are set for the true source position
-		pixelValue += Io*(Vo + XoSave*Vx + XoSave*Vy);
+                int rx0 = rx - 0.5;
+                int rx1 = rx + 0.5;
+                int ry0 = ry - 0.5;
+                int ry1 = ry + 0.5;
+
+                if (rx0 < 0) goto skip;
+                if (ry0 < 0) goto skip;
+                if (rx1 >= NX) goto skip;
+                if (ry1 >= NY) goto skip;
+
+                // these go from 0.0 to 1.0 between the centers of the pixels
+                float fx = rx - 0.5 - rx0;
+                float Fx = 1.0 - fx;
+                float fy = ry - 0.5 - ry0;
+                float Fy = 1.0 - fy;
+
+                // check the residual image mask (if set). give up if any of the 4 pixels are masked.
+                if (Rm) {
+                    if (Rm[ry0][rx0]) goto skip;
+                    if (Rm[ry0][rx1]) goto skip;
+                    if (Rm[ry1][rx0]) goto skip;
+                    if (Rm[ry1][rx1]) goto skip;
+                }
+
+                // a possible further optimization if we re-use these values
+                // XXX allow for masked pixels, and add pixel weights
+                float V0 = (Ro[ry0][rx0]*Fx + Ro[ry0][rx1]*fx);
+                float V1 = (Ro[ry1][rx0]*Fx + Ro[ry1][rx1]*fx);
+                float Vo = V0*Fy + V1*fy;
+                if (!isfinite(Vo)) goto skip;
+
+                float Vx = 0.0;
+                float Vy = 0.0;
+
+                // skip Rx,Ry if Ro is masked
+                if (Rx && Ry && (mode & PM_MODEL_OP_RES1)) {
+                    V0 = (Rx[ry0][rx0]*Fx + Rx[ry0][rx1]*fx);
+                    V1 = (Rx[ry1][rx0]*Fx + Rx[ry1][rx1]*fx);
+                    Vx = V0*Fy + V1*fy;
+
+                    V0 = (Ry[ry0][rx0]*Fx + Ry[ry0][rx1]*fx);
+                    V1 = (Ry[ry1][rx0]*Fx + Ry[ry1][rx1]*fx);
+                    Vy = V0*Fy + V1*fy;
+                }
+                if (!isfinite(Vx)) goto skip;
+                if (!isfinite(Vy)) goto skip;
+
+                // 2D residual variations are set for the true source position
+                pixelValue += Io*(Vo + XoSave*Vx + XoSave*Vy);
             }
 
-	skip:
+        skip:
             // add or subtract the value
             if (add) {
Index: /branches/cnb_branch_20090215/psModules/src/objects/pmModel.h
===================================================================
--- /branches/cnb_branch_20090215/psModules/src/objects/pmModel.h	(revision 21535)
+++ /branches/cnb_branch_20090215/psModules/src/objects/pmModel.h	(revision 21536)
@@ -5,6 +5,6 @@
  * @author EAM, IfA
  *
- * @version $Revision: 1.18 $ $Name: not supported by cvs2svn $
- * @date $Date: 2009-01-27 06:39:38 $
+ * @version $Revision: 1.18.8.1 $ $Name: not supported by cvs2svn $
+ * @date $Date: 2009-02-19 17:59:50 $
  *
  * Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -92,4 +92,5 @@
     float mag;                          ///< integrated model magnitude
     float magErr;                       ///< integrated model magnitude error
+    int nPix;                           ///< number of pixels used for fit
     int nDOF;                           ///< number of degrees of freedom
     int nIter;                          ///< number of iterations to reach min
@@ -150,5 +151,5 @@
     pmModel *model,                     ///< The input pmModel
     pmModelOpMode mode,                 ///< mode to control how the model is added into the image
-    psImageMaskType maskVal		///< Value to mask
+    psImageMaskType maskVal             ///< Value to mask
 );
 
@@ -168,5 +169,5 @@
     pmModel *model,                     ///< The input pmModel
     pmModelOpMode mode,                 ///< mode to control how the model is added into the image
-    psImageMaskType maskVal		///< Value to mask
+    psImageMaskType maskVal             ///< Value to mask
 );
 
Index: /branches/cnb_branch_20090215/psModules/src/objects/pmPeaks.c
===================================================================
--- /branches/cnb_branch_20090215/psModules/src/objects/pmPeaks.c	(revision 21535)
+++ /branches/cnb_branch_20090215/psModules/src/objects/pmPeaks.c	(revision 21536)
@@ -6,6 +6,6 @@
  *  @author EAM, IfA: significant modifications.
  *
- *  @version $Revision: 1.25 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2008-12-08 02:51:14 $
+ *  @version $Revision: 1.25.14.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-19 17:59:50 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -28,5 +28,5 @@
 AddPeak(): A private function which allocates a psArray, if the peaks
 argument is NULL, otherwise it adds the peak to that array.
-XXX EAM : row,col now refer to image coords, NOT parent (since this is private) 
+XXX EAM : row,col now refer to image coords, NOT parent (since this is private)
 XXX EAM : now also calculates fractional peak positions from 3x3 bicube region
 *****************************************************************************/
@@ -63,15 +63,18 @@
         peak->xf = min.x + ix + image->col0;
         peak->yf = min.y + iy + image->row0;
-	peak->dx = NAN;
-	peak->dy = NAN;
-	
-	// xf,yf must land on image with 0 pixel border
-	peak->xf = PS_MAX (PS_MIN (peak->xf, image->numCols - 1), image->col0);
-	peak->yf = PS_MAX (PS_MIN (peak->yf, image->numRows - 1), image->row0);
+
+        // These errors are fractional errors, and should be scaled by the
+        // error on the peak pixel (see, eg, psphotFindPeaks)
+        peak->dx = min.xErr;
+        peak->dy = min.yErr;
+
+        // xf,yf must land on image with 0 pixel border
+        peak->xf = PS_MAX (PS_MIN (peak->xf, image->numCols - 1), image->col0);
+        peak->yf = PS_MAX (PS_MIN (peak->yf, image->numRows - 1), image->row0);
     } else {
         peak->xf = ix;
         peak->yf = iy;
-	peak->dx = NAN;
-	peak->dy = NAN;
+        peak->dx = NAN;
+        peak->dy = NAN;
     }
 
@@ -86,5 +89,5 @@
 getRowVectorFromImage(): a private function which simply returns a
 psVector containing the specified row of data from the psImage.
- 
+
 XXX: Is there a better way to do this?
 XXX EAM: does this really need to alloc a new vector???
@@ -245,7 +248,7 @@
 above the given threshold.  Returns a vector of type PS_TYPE_U32 containing
 the location (x value) of all peaks.
- 
+
 XXX: What types should be supported?  Only F32 is implemented.
- 
+
 XXX: We currently step through the input vector twice; once to determine the
 size of the output vector, then to set the values of the output vector.
@@ -253,5 +256,5 @@
 *****************************************************************************/
 psVector *pmPeaksInVector(const psVector *vector,
-			 psF32 threshold)
+                         psF32 threshold)
 {
     psTrace("psModules.objects", 3, "---- %s() begin ----\n", __func__);
@@ -347,12 +350,12 @@
 above the given threshold.  Returns a psArray containing location (x/y value)
 of all peaks.
- 
+
 XXX: I'm not convinced the peak type definition in the SDRS is mutually
 exclusive.  Some peaks can have multiple types.  Edges for sure.  Also, a
 digonal line with the same value at each point will have a peak for every
 point on that line.
- 
+
 XXX: This does not work if image has either a single row, or a single column.
- 
+
 The peak is returned in the image parent coordinates
 
Index: /branches/cnb_branch_20090215/psModules/src/objects/pmSource.c
===================================================================
--- /branches/cnb_branch_20090215/psModules/src/objects/pmSource.c	(revision 21535)
+++ /branches/cnb_branch_20090215/psModules/src/objects/pmSource.c	(revision 21536)
@@ -6,6 +6,6 @@
  *  @author EAM, IfA: significant modifications.
  *
- *  @version $Revision: 1.69 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2009-02-06 02:31:25 $
+ *  @version $Revision: 1.69.4.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-19 17:59:50 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -113,4 +113,5 @@
     source->type = PM_SOURCE_TYPE_UNKNOWN;
     source->mode = PM_SOURCE_MODE_DEFAULT;
+    source->tmpFlags = 0;
     source->extpars = NULL;
     source->region = psRegionSet(NAN, NAN, NAN, NAN);
@@ -534,4 +535,6 @@
     float INNER_RADIUS = psMetadataLookupF32 (&status, recipe, "SKY_INNER_RADIUS");
 
+    pmSourceMode noMoments = PM_SOURCE_MODE_MOMENTS_FAILURE | PM_SOURCE_MODE_SKYVAR_FAILURE | PM_SOURCE_MODE_SKY_FAILURE | PM_SOURCE_MODE_BELOW_MOMENTS_SN;
+
     // XXX allow clump size to be scaled relative to sigmas?
     // make rough IDs based on clumpX,Y,DX,DY
@@ -540,14 +543,18 @@
         pmSource *source = (pmSource *) sources->data[i];
 
-        if (source->peak->x < region->x0) continue;
-        if (source->peak->x > region->x1) continue;
-        if (source->peak->y < region->y0) continue;
-        if (source->peak->y > region->y1) continue;
-
-        source->peak->type = 0;
+        // psf clumps are found for image subregions:
+        // skip sources not in this region
+        if (source->peak->x <  region->x0) continue;
+        if (source->peak->x >= region->x1) continue;
+        if (source->peak->y <  region->y0) continue;
+        if (source->peak->y >= region->y1) continue;
+
+        // should be set by pmSourceAlloc
+        psAssert (source->type == PM_SOURCE_TYPE_UNKNOWN, "source type was not init-ed?");
 
         // we are basically classifying by moments; use the default if not found
         if (!source->moments) {
             source->type = PM_SOURCE_TYPE_STAR;
+            psAssert (source->mode & noMoments, "why is this source missing moments?");
             Nstar++;
             continue;
@@ -1049,4 +1056,19 @@
 }
 
+// sort by Seq (ascending)
+int pmSourceSortBySeq (const void **a, const void **b)
+{
+    pmSource *A = *(pmSource **)a;
+    pmSource *B = *(pmSource **)b;
+
+    int iA = A->seq;
+    int iB = B->seq;
+
+    int diff = iA - iB;
+    if (diff > 0) return (+1);
+    if (diff < 0) return (-1);
+    return (0);
+}
+
 pmSourceMode pmSourceModeFromString (const char *name) {
   if (!strcasecmp (name, "DEFAULT"   )) return PM_SOURCE_MODE_DEFAULT;
@@ -1066,5 +1088,4 @@
   if (!strcasecmp (name, "CRLIMIT"   )) return PM_SOURCE_MODE_CR_LIMIT;
   if (!strcasecmp (name, "EXTLIMIT"  )) return PM_SOURCE_MODE_EXT_LIMIT;
-  if (!strcasecmp (name, "SUBTRACTED")) return PM_SOURCE_MODE_SUBTRACTED;
   return PM_SOURCE_MODE_DEFAULT;
 }
@@ -1088,5 +1109,4 @@
     case PM_SOURCE_MODE_CR_LIMIT   : return psStringCopy ("CRLIMIT"   );
     case PM_SOURCE_MODE_EXT_LIMIT  : return psStringCopy ("EXTLIMIT"  );
-    case PM_SOURCE_MODE_SUBTRACTED : return psStringCopy ("SUBTRACTED");
     default:
       return NULL;
Index: /branches/cnb_branch_20090215/psModules/src/objects/pmSource.h
===================================================================
--- /branches/cnb_branch_20090215/psModules/src/objects/pmSource.h	(revision 21535)
+++ /branches/cnb_branch_20090215/psModules/src/objects/pmSource.h	(revision 21536)
@@ -3,6 +3,6 @@
  * @author EAM, IfA; GLG, MHPCC
  *
- * @version $Revision: 1.28 $ $Name: not supported by cvs2svn $
- * @date $Date: 2009-02-06 02:31:25 $
+ * @version $Revision: 1.28.4.1 $ $Name: not supported by cvs2svn $
+ * @date $Date: 2009-02-19 17:59:50 $
  * Copyright 2004 Maui High Performance Computing Center, University of Hawaii
  */
@@ -35,23 +35,41 @@
 } pmSourceType;
 
+// bit flags to distinguish analysis results
 typedef enum {
-    PM_SOURCE_MODE_DEFAULT    = 0x0000, ///<
-    PM_SOURCE_MODE_PSFMODEL   = 0x0001, ///< Source fitted with a psf model (linear or non-linear)
-    PM_SOURCE_MODE_EXTMODEL   = 0x0002, ///< Source fitted with an extended-source model
-    PM_SOURCE_MODE_FITTED     = 0x0004, ///< Source fitted with non-linear model (PSF or EXT; good or bad)
-    PM_SOURCE_MODE_FAIL       = 0x0008, ///< Fit (non-linear) failed (non-converge, off-edge, run to zero)
-    PM_SOURCE_MODE_POOR       = 0x0010, ///< Fit succeeds, but low-SN, high-Chisq, or large (for PSF -- drop?)
-    PM_SOURCE_MODE_PAIR       = 0x0020, ///< Source fitted with a double psf
-    PM_SOURCE_MODE_PSFSTAR    = 0x0040, ///< Source used to define PSF model
-    PM_SOURCE_MODE_SATSTAR    = 0x0080, ///< Source model peak is above saturation
-    PM_SOURCE_MODE_BLEND      = 0x0100, ///< Source is a blend with other sourcers
-    PM_SOURCE_MODE_EXTERNAL   = 0x0200, ///< Source based on supplied input position
-    PM_SOURCE_MODE_BADPSF     = 0x0400, ///< Failed to get good estimate of object's PSF
-    PM_SOURCE_MODE_DEFECT     = 0x0800, ///< Source is thought to be a defect
-    PM_SOURCE_MODE_SATURATED  = 0x1000, ///< Source is thought to be saturated pixels (bleed trail)
-    PM_SOURCE_MODE_CR_LIMIT   = 0x2000, ///< Source has crNsigma above limit
-    PM_SOURCE_MODE_EXT_LIMIT  = 0x4000, ///< Source has extNsigma above limit
-    PM_SOURCE_MODE_SUBTRACTED = 0x8000, ///< XXX this flag is actually only used internally (move)
+    PM_SOURCE_MODE_DEFAULT          = 0x00000000, ///< Initial value: resets all bits
+    PM_SOURCE_MODE_PSFMODEL         = 0x00000001, ///< Source fitted with a psf model (linear or non-linear)
+    PM_SOURCE_MODE_EXTMODEL         = 0x00000002, ///< Source fitted with an extended-source model
+    PM_SOURCE_MODE_FITTED           = 0x00000004, ///< Source fitted with non-linear model (PSF or EXT; good or bad)
+    PM_SOURCE_MODE_FAIL             = 0x00000008, ///< Fit (non-linear) failed (non-converge, off-edge, run to zero)
+    PM_SOURCE_MODE_POOR             = 0x00000010, ///< Fit succeeds, but low-SN, high-Chisq, or large (for PSF -- drop?)
+    PM_SOURCE_MODE_PAIR             = 0x00000020, ///< Source fitted with a double psf
+    PM_SOURCE_MODE_PSFSTAR          = 0x00000040, ///< Source used to define PSF model
+    PM_SOURCE_MODE_SATSTAR          = 0x00000080, ///< Source model peak is above saturation
+    PM_SOURCE_MODE_BLEND            = 0x00000100, ///< Source is a blend with other sourcers
+    PM_SOURCE_MODE_EXTERNAL         = 0x00000200, ///< Source based on supplied input position
+    PM_SOURCE_MODE_BADPSF           = 0x00000400, ///< Failed to get good estimate of object's PSF
+    PM_SOURCE_MODE_DEFECT           = 0x00000800, ///< Source is thought to be a defect
+    PM_SOURCE_MODE_SATURATED        = 0x00001000, ///< Source is thought to be saturated pixels (bleed trail)
+    PM_SOURCE_MODE_CR_LIMIT         = 0x00002000, ///< Source has crNsigma above limit
+    PM_SOURCE_MODE_EXT_LIMIT        = 0x00004000, ///< Source has extNsigma above limit
+    PM_SOURCE_MODE_MOMENTS_FAILURE  = 0x00008000, ///< could not measure the moments
+    PM_SOURCE_MODE_SKY_FAILURE      = 0x00010000, ///< could not measure the local sky
+    PM_SOURCE_MODE_SKYVAR_FAILURE   = 0x00020000, ///< could not measure the local sky variance
+    PM_SOURCE_MODE_BELOW_MOMENTS_SN = 0x00040000, ///< moments not measured due to low S/N
+    PM_SOURCE_MODE_BIG_RADIUS       = 0x00100000, ///< poor moments for small radius, try large radius
+    PM_SOURCE_MODE_AP_MAGS          = 0x00200000, ///< source has an aperture magnitude
+    PM_SOURCE_MODE_BLEND_FIT        = 0x00400000, ///< source was fitted as a blend
+    PM_SOURCE_MODE_EXTENDED_FIT     = 0x00800000, ///< full extended fit was used
+    PM_SOURCE_MODE_EXTENDED_STATS   = 0x01000000, ///< extended aperture stats calculated
+    PM_SOURCE_MODE_LINEAR_FIT       = 0x02000000, ///< source fitted with the linear fit
+    PM_SOURCE_MODE_NONLINEAR_FIT    = 0x04000000, ///< source fitted with the non-linear fit
+    PM_SOURCE_MODE_RADIAL_FLUX      = 0x08000000, ///< radial flux measurements calculated
+    PM_SOURCE_MODE_SIZE_SKIPPED     = 0x10000000, ///< size could not be determined
 } pmSourceMode;
+
+typedef enum {
+    PM_SOURCE_TMPF_MODEL_GUESS = 0x0001,
+    PM_SOURCE_TMPF_SUBTRACTED  = 0x0002,
+} pmSourceTmpF;
 
 /** pmSource data structure
@@ -68,6 +86,6 @@
  */
 struct pmSource {
-    const int id;                       ///< Unique ID for object
-    int seq;                            ///< ID for output (generated on write)
+    const int id;                       ///< Unique ID for object (generated on alloc)
+    int seq;                            ///< ID for output (generated on write OR set on read)
     pmPeak  *peak;                      ///< Description of peak pixel.
     psImage *pixels;                    ///< Rectangular region including object pixels.
@@ -83,4 +101,5 @@
     pmSourceType type;                  ///< Best identification of object.
     pmSourceMode mode;                  ///< analysis flags set for object.
+    pmSourceTmpF tmpFlags;              ///< internal-only flags
     psArray *blends;                    ///< collection of sources thought to be confused with object
     float psfMag;                       ///< calculated from flux in modelPSF
@@ -240,6 +259,7 @@
 bool pmSourceCachePSF (pmSource *source, psImageMaskType maskVal);
 
-int             pmSourceSortBySN (const void **a, const void **b);
-int             pmSourceSortByY (const void **a, const void **b);
+int  pmSourceSortBySN (const void **a, const void **b);
+int  pmSourceSortByY (const void **a, const void **b);
+int  pmSourceSortBySeq (const void **a, const void **b);
 
 pmSourceMode pmSourceModeFromString (const char *name);
Index: /branches/cnb_branch_20090215/psModules/src/objects/pmSourceFitModel.c
===================================================================
--- /branches/cnb_branch_20090215/psModules/src/objects/pmSourceFitModel.c	(revision 21535)
+++ /branches/cnb_branch_20090215/psModules/src/objects/pmSourceFitModel.c	(revision 21536)
@@ -6,6 +6,6 @@
  *  @author GLG, MHPCC
  *
- *  @version $Revision: 1.30 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2009-02-06 02:31:25 $
+ *  @version $Revision: 1.30.4.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-19 17:59:50 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -184,4 +184,5 @@
     model->chisq = myMin->value;
     model->nIter = myMin->iter;
+    model->nPix  = y->n;
     model->nDOF  = y->n - nParams;
     model->flags |= PM_MODEL_STATUS_FITTED;
Index: /branches/cnb_branch_20090215/psModules/src/objects/pmSourceIO.c
===================================================================
--- /branches/cnb_branch_20090215/psModules/src/objects/pmSourceIO.c	(revision 21535)
+++ /branches/cnb_branch_20090215/psModules/src/objects/pmSourceIO.c	(revision 21536)
@@ -3,6 +3,6 @@
  *  @author EAM, IfA
  *
- *  @version $Revision: 1.69 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2008-12-08 02:51:14 $
+ *  @version $Revision: 1.69.14.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-19 17:59:50 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -488,8 +488,11 @@
             }
             if (!strcmp (exttype, "PS1_DEV_1")) {
-                status = pmSourcesWrite_PS1_DEV_1 (file->fits, sources, file->header, outhead, dataname, xsrcname);
+                status = pmSourcesWrite_PS1_DEV_1 (file->fits, sources, file->header, outhead, dataname);
             }
             if (!strcmp (exttype, "PS1_CAL_0")) {
-                status = pmSourcesWrite_PS1_CAL_0 (file->fits, readout, sources, file->header, outhead, dataname, xsrcname);
+                status = pmSourcesWrite_PS1_CAL_0 (file->fits, readout, sources, file->header, outhead, dataname);
+            }
+            if (!strcmp (exttype, "PS1_V1")) {
+                status = pmSourcesWrite_CMF_PS1_V1 (file->fits, readout, sources, file->header, outhead, dataname);
             }
             if (xsrcname) {
@@ -500,4 +503,7 @@
                   status = pmSourcesWrite_PS1_CAL_0_XSRC (file->fits, readout, sources, file->header, xsrcname, recipe);
               }
+              if (!strcmp (exttype, "PS1_V1")) {
+                  status = pmSourcesWrite_CMF_PS1_V1_XSRC (file->fits, sources, xsrcname, recipe);
+              }
             }
             if (xfitname) {
@@ -507,4 +513,7 @@
               if (!strcmp (exttype, "PS1_CAL_0")) {
                   status = pmSourcesWrite_PS1_CAL_0_XFIT (file->fits, readout, sources, file->header, xfitname);
+              }
+              if (!strcmp (exttype, "PS1_V1")) {
+                  status = pmSourcesWrite_CMF_PS1_V1_XFIT (file->fits, sources, xfitname);
               }
             }
@@ -929,6 +938,6 @@
                 sources = pmSourcesRead_PS1_DEV_1 (file->fits, hdu->header);
             }
-            if (!strcmp (exttype, "PS1_CAL_)")) {
-                sources = pmSourcesRead_PS1_CAL_0 (file->fits, hdu->header);
+            if (!strcmp (exttype, "PS1_V1")) {
+                sources = pmSourcesRead_CMF_PS1_V1 (file->fits, hdu->header);
             }
         }
Index: /branches/cnb_branch_20090215/psModules/src/objects/pmSourceIO.h
===================================================================
--- /branches/cnb_branch_20090215/psModules/src/objects/pmSourceIO.h	(revision 21535)
+++ /branches/cnb_branch_20090215/psModules/src/objects/pmSourceIO.h	(revision 21536)
@@ -4,6 +4,6 @@
  * @author EAM, IfA; GLG, MHPCC
  *
- * @version $Revision: 1.19 $ $Name: not supported by cvs2svn $
- * @date $Date: 2008-11-14 02:11:45 $
+ * @version $Revision: 1.19.16.1 $ $Name: not supported by cvs2svn $
+ * @date $Date: 2009-02-19 17:59:50 $
  * Copyright 2004 Maui High Performance Computing Center, University of Hawaii
  *
@@ -26,11 +26,16 @@
 bool pmSourcesWrite_SMPDATA (psFits *fits, psArray *sources, psMetadata *imageHeader, psMetadata *tableHeader, char *extname);
 bool pmSourcesWrite_PS1_DEV_0 (psFits *fits, psArray *sources, psMetadata *imageHeader, psMetadata *tableHeader, char *extname);
-bool pmSourcesWrite_PS1_DEV_1 (psFits *fits, psArray *sources, psMetadata *imageHeader, psMetadata *tableHeader, char *extname, char *xsrcname);
+
+bool pmSourcesWrite_PS1_DEV_1 (psFits *fits, psArray *sources, psMetadata *imageHeader, psMetadata *tableHeader, char *extname);
 bool pmSourcesWrite_PS1_DEV_1_XSRC (psFits *fits, psArray *sources, char *extname, psMetadata *recipe);
 bool pmSourcesWrite_PS1_DEV_1_XFIT (psFits *fits, psArray *sources, char *extname);
 
-bool pmSourcesWrite_PS1_CAL_0 (psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, psMetadata *tableHeader, char *extname, char *xsrcname);
+bool pmSourcesWrite_PS1_CAL_0 (psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, psMetadata *tableHeader, char *extname);
 bool pmSourcesWrite_PS1_CAL_0_XSRC (psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, char *extname, psMetadata *recipe);
 bool pmSourcesWrite_PS1_CAL_0_XFIT (psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, char *extname);
+
+bool pmSourcesWrite_CMF_PS1_V1 (psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, psMetadata *tableHeader, char *extname);
+bool pmSourcesWrite_CMF_PS1_V1_XSRC (psFits *fits, psArray *sources, char *extname, psMetadata *recipe);
+bool pmSourcesWrite_CMF_PS1_V1_XFIT (psFits *fits, psArray *sources, char *extname);
 
 bool pmSource_CMF_WritePHU (const pmFPAview *view, pmFPAfile *file, pmConfig *config);
@@ -42,4 +47,5 @@
 psArray *pmSourcesRead_PS1_DEV_1 (psFits *fits, psMetadata *header);
 psArray *pmSourcesRead_PS1_CAL_0 (psFits *fits, psMetadata *header);
+psArray *pmSourcesRead_CMF_PS1_V1 (psFits *fits, psMetadata *header);
 
 bool pmSourcesWritePSFs (psArray *sources, char *filename);
@@ -67,4 +73,6 @@
 bool pmReadoutCheckDataStatusForSources (const pmReadout *readout);
 
+bool pmSourceLocalAstrometry (psSphere *ptSky, float *posAngle, float *pltScale, pmChip *chip, float xPos, float yPos);
+
 /// @}
 # endif /* PM_SOURCE_IO_H */
Index: /branches/cnb_branch_20090215/psModules/src/objects/pmSourceIO_CMF_PS1_V1.c
===================================================================
--- /branches/cnb_branch_20090215/psModules/src/objects/pmSourceIO_CMF_PS1_V1.c	(revision 21536)
+++ /branches/cnb_branch_20090215/psModules/src/objects/pmSourceIO_CMF_PS1_V1.c	(revision 21536)
@@ -0,0 +1,675 @@
+/** @file  pmSourceIO.c
+ *
+ *  @author EAM, IfA
+ *
+ *  @version $Revision: 1.3.2.2 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-19 17:59:50 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+#include <pslib.h>
+
+#include "pmConfig.h"
+#include "pmDetrendDB.h"
+
+#include "pmHDU.h"
+#include "pmFPA.h"
+#include "pmFPALevel.h"
+#include "pmFPAview.h"
+#include "pmFPAfile.h"
+
+#include "pmSpan.h"
+#include "pmFootprint.h"
+#include "pmPeaks.h"
+#include "pmMoments.h"
+#include "pmGrowthCurve.h"
+#include "pmResiduals.h"
+#include "pmTrend2D.h"
+#include "pmPSF.h"
+#include "pmModel.h"
+#include "pmSource.h"
+#include "pmModelClass.h"
+#include "pmSourceIO.h"
+
+// panstarrs-style FITS table output (header + table in 1st extension)
+// this format consists of a header derived from the image header
+// followed by a zero-size matrix, followed by the table data
+
+bool pmSourcesWrite_CMF_PS1_V1 (psFits *fits, pmReadout *readout, psArray *sources, 
+				psMetadata *imageHeader, psMetadata *tableHeader, char *extname)
+{
+    PS_ASSERT_PTR_NON_NULL(fits, false);
+    PS_ASSERT_PTR_NON_NULL(sources, false);
+    PS_ASSERT_PTR_NON_NULL(extname, false);
+
+    psArray *table;
+    psMetadata *row;
+    int i;
+    psF32 *PAR, *dPAR;
+    psEllipseAxes axes;
+    psF32 xPos, yPos;
+    psF32 xErr, yErr;
+    psF32 errMag, chisq, apRadius;
+    psS32 nPix, nDOF;
+
+    pmChip *chip = readout->parent->parent;
+    pmFPA  *fpa  = chip->parent;
+
+    bool status1 = false;
+    bool status2 = false;
+    float magOffset = NAN;
+    float exptime   = psMetadataLookupF32 (&status1, fpa->concepts, "FPA.EXPOSURE");
+    float zeropt    = psMetadataLookupF32 (&status2, imageHeader, "ZPT_OBS");
+    float zeroptErr = psMetadataLookupF32 (&status2, imageHeader, "ZPT_ERR");
+    if (status1 && status2 && (exptime > 0.0)) {
+	magOffset = zeropt + 2.5*log10(exptime);
+    }
+
+    // if the sequence is defined, write these in seq order; otherwise
+    // write them in S/N order:
+    if (sources->n > 0) {
+        pmSource *source = (pmSource *) sources->data[0];
+	if (source->seq == -1) {
+	  // let's write these out in S/N order
+	  sources = psArraySort (sources, pmSourceSortBySN);
+	} else {
+	  sources = psArraySort (sources, pmSourceSortBySeq);
+	}
+    }
+
+    table = psArrayAllocEmpty (sources->n);
+
+    // we write out PSF-fits for all sources, regardless of quality.  the source flags tell us the state
+    // by the time we call this function, all values should be assigned.  let's use asserts to be sure in some cases.
+    for (i = 0; i < sources->n; i++) {
+        pmSource *source = (pmSource *) sources->data[i];
+
+	// If source->seq is -1, source was generated in this analysis.  If source->seq is
+	// not -1, source was read from elsewhere: in the latter case, preserve the source
+	// ID.  source.seq is used instead of source.id since the latter is a const
+	// generated on Alloc, and would thus be wrong for read in sources.
+	if (source->seq == -1) {
+	  source->seq = i;
+	}
+
+        // no difference between PSF and non-PSF model
+        pmModel *model = source->modelPSF;
+
+        if (model != NULL) {
+            PAR = model->params->data.F32;
+            dPAR = model->dparams->data.F32;
+            xPos = PAR[PM_PAR_XPOS];
+            yPos = PAR[PM_PAR_YPOS];
+	    if (source->mode & PM_SOURCE_MODE_NONLINEAR_FIT) {
+	      xErr = dPAR[PM_PAR_XPOS];
+	      yErr = dPAR[PM_PAR_YPOS];
+	    } else {
+	      // in linear-fit mode, there is no error on the centroid
+	      xErr = source->peak->dx;
+	      yErr = source->peak->dy;
+	    }	      
+	    if (isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX])) {
+		axes = pmPSF_ModelToAxes (PAR, 20.0);
+	    } else {
+		axes.major = NAN;
+		axes.minor = NAN;
+		axes.theta = NAN;
+	    }
+	    chisq = model->chisq;
+	    nDOF = model->nDOF;
+	    nPix = model->nPix;
+	    apRadius = model->radiusFit; // XXX should we really use the fitRadius for aperture Radius?
+	    errMag = model->dparams->data.F32[PM_PAR_I0] / model->params->data.F32[PM_PAR_I0];
+        } else {
+            xPos = source->peak->xf;
+            yPos = source->peak->yf;
+            xErr = source->peak->dx;
+            yErr = source->peak->dy;
+            axes.major = NAN;
+            axes.minor = NAN;
+            axes.theta = NAN;
+	    chisq = NAN;
+	    nDOF = 0;
+	    nPix = 0;
+	    apRadius = NAN;
+	    errMag = NAN;
+        }
+
+	float calMag = isfinite(magOffset) ? source->psfMag + magOffset : NAN;
+        float peakMag = (source->peak->flux > 0) ? -2.5*log10(source->peak->flux) : NAN;
+        psS16 nImageOverlap = 1;
+
+	psSphere ptSky = {0.0, 0.0, 0.0, 0.0};
+	float posAngle = 0.0;
+	float pltScale = 0.0;
+	pmSourceLocalAstrometry (&ptSky, &posAngle, &pltScale, chip, xPos, yPos);
+
+        row = psMetadataAlloc ();
+        psMetadataAdd (row, PS_LIST_TAIL, "IPP_IDET",         PS_DATA_U32, "IPP detection identifier index",             source->seq);
+        psMetadataAdd (row, PS_LIST_TAIL, "X_PSF",            PS_DATA_F32, "PSF x coordinate",                           xPos);
+        psMetadataAdd (row, PS_LIST_TAIL, "Y_PSF",            PS_DATA_F32, "PSF y coordinate",                           yPos);
+        psMetadataAdd (row, PS_LIST_TAIL, "X_PSF_SIG",        PS_DATA_F32, "Sigma in PSF x coordinate",                  xErr); // XXX this is only measured for non-linear fits
+        psMetadataAdd (row, PS_LIST_TAIL, "Y_PSF_SIG",        PS_DATA_F32, "Sigma in PSF y coordinate",                  yErr); // XXX this is only measured for non-linear fits
+        psMetadataAdd (row, PS_LIST_TAIL, "RA_PSF",           PS_DATA_F32, "PSF RA coordinate (degrees)",                ptSky.r*PS_DEG_RAD);
+        psMetadataAdd (row, PS_LIST_TAIL, "DEC_PSF",          PS_DATA_F32, "PSF DEC coordinate (degrees)",               ptSky.d*PS_DEG_RAD);
+        psMetadataAdd (row, PS_LIST_TAIL, "POSANGLE",         PS_DATA_F32, "position angle at source (degrees)",         posAngle*PS_DEG_RAD);
+        psMetadataAdd (row, PS_LIST_TAIL, "PLTSCALE",         PS_DATA_F32, "plate scale at source (arcsec/pixel)",       pltScale*PS_DEG_RAD*3600.0);
+        psMetadataAdd (row, PS_LIST_TAIL, "PSF_INST_MAG",     PS_DATA_F32, "PSF fit instrumental magnitude",             source->psfMag);
+        psMetadataAdd (row, PS_LIST_TAIL, "PSF_INST_MAG_SIG", PS_DATA_F32, "Sigma of PSF instrumental magnitude",        errMag);
+        psMetadataAdd (row, PS_LIST_TAIL, "AP_MAG",           PS_DATA_F32, "magnitude in standard aperture",             source->apMag);
+        psMetadataAdd (row, PS_LIST_TAIL, "AP_MAG_RADIUS",    PS_DATA_F32, "radius used for aperture mags",              apRadius);
+        psMetadataAdd (row, PS_LIST_TAIL, "PEAK_FLUX_AS_MAG", PS_DATA_F32, "Peak flux expressed as magnitude",           peakMag);
+        psMetadataAdd (row, PS_LIST_TAIL, "CAL_PSF_MAG",      PS_DATA_F32, "PSF Magnitude using supplied calibration",   calMag);
+        psMetadataAdd (row, PS_LIST_TAIL, "CAL_PSF_MAG_SIG",  PS_DATA_F32, "measured scatter of zero point calibration", zeroptErr);
+        psMetadataAdd (row, PS_LIST_TAIL, "SKY",              PS_DATA_F32, "Sky level",                                  source->sky);
+        psMetadataAdd (row, PS_LIST_TAIL, "SKY_SIGMA",        PS_DATA_F32, "Sigma of sky level",                         source->skyErr);
+
+        psMetadataAdd (row, PS_LIST_TAIL, "PSF_CHISQ",        PS_DATA_F32, "Chisq of PSF-fit",                           chisq);
+        psMetadataAdd (row, PS_LIST_TAIL, "CR_NSIGMA",        PS_DATA_F32, "Nsigma deviations from PSF to CF",           source->crNsigma);
+        psMetadataAdd (row, PS_LIST_TAIL, "EXT_NSIGMA",       PS_DATA_F32, "Nsigma deviations from PSF to EXT",          source->extNsigma);
+
+        psMetadataAdd (row, PS_LIST_TAIL, "PSF_MAJOR",        PS_DATA_F32, "PSF width (major axis)",                     axes.major);
+        psMetadataAdd (row, PS_LIST_TAIL, "PSF_MINOR",        PS_DATA_F32, "PSF width (minor axis)",                     axes.minor);
+        psMetadataAdd (row, PS_LIST_TAIL, "PSF_THETA",        PS_DATA_F32, "PSF orientation angle",                      axes.theta);
+        psMetadataAdd (row, PS_LIST_TAIL, "PSF_QF",           PS_DATA_F32, "PSF coverage/quality factor",                source->pixWeight);
+        psMetadataAdd (row, PS_LIST_TAIL, "PSF_NDOF",         PS_DATA_S32, "degrees of freedom",                         nDOF);
+        psMetadataAdd (row, PS_LIST_TAIL, "PSF_NPIX",         PS_DATA_S32, "number of pixels in fit",                    nPix);
+
+	// distinguish moments measure from window vs S/N > XX ??
+        psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_XX",       PS_DATA_F32, "second moments (X^2)",                      source->moments->Mxx);
+        psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_XY",       PS_DATA_F32, "second moments (X*Y)",                      source->moments->Mxy);
+        psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_YY",       PS_DATA_F32, "second moments (Y*Y)",                      source->moments->Myy);
+
+        psMetadataAdd (row, PS_LIST_TAIL, "FLAGS",            PS_DATA_U32, "psphot analysis flags",                      source->mode);
+
+        // XXX not sure how to get this : need to load Nimages with weight?
+        psMetadataAdd (row, PS_LIST_TAIL, "N_FRAMES",         PS_DATA_U16, "Number of frames overlapping source center", nImageOverlap);
+        psMetadataAdd (row, PS_LIST_TAIL, "PADDING",          PS_DATA_S16, "padding", 0);
+
+        psArrayAdd (table, 100, row);
+        psFree (row);
+
+	// EXT_NSIGMA will be NAN if: 1) contour ellipse is imaginary; 2) source is not
+	// subtracted
+
+	// CR_NSIGMA will be NAN if: 1) source is not subtracted; 2) source is on the image
+	// edge; 3) any pixels in the 3x3 peak region are masked; 
+    }
+
+    if (table->n == 0) {
+        psFitsWriteBlank (fits, tableHeader, extname);
+        psFree (table);
+        return true;
+    }
+
+    psTrace ("pmFPAfile", 5, "writing ext data %s\n", extname);
+    if (!psFitsWriteTable (fits, tableHeader, table, extname)) {
+        psError(PS_ERR_IO, false, "writing ext data %s\n", extname);
+        psFree(table);
+        return false;
+    }
+    psFree (table);
+
+    return true;
+}
+
+// read in a readout from the fits file
+psArray *pmSourcesRead_CMF_PS1_V1 (psFits *fits, psMetadata *header)
+{
+    PS_ASSERT_PTR_NON_NULL(fits, false);
+    PS_ASSERT_PTR_NON_NULL(header, false);
+
+    bool status;
+    psF32 *PAR, *dPAR;
+    psEllipseAxes axes;
+
+    // define PSF model type
+    // XXX need to carry the extra model parameters
+    int modelType = pmModelClassGetType ("PS_MODEL_GAUSS");
+
+    char *PSF_NAME = psMetadataLookupStr (&status, header, "PSF_NAME");
+    if (PSF_NAME != NULL) {
+        modelType = pmModelClassGetType (PSF_NAME);
+    }
+    assert (modelType > -1);
+
+    // We get the size of the table, and allocate the array of sources first because the table
+    // is large and ephemeral --- when the table gets blown away, whatever is allocated after
+    // the table is read blocks the free.  In fact, it's better to read the table row by row.
+    long numSources = psFitsTableSize(fits); // Number of sources in table
+    psArray *sources = psArrayAlloc(numSources); // Array of sources, to return
+
+    // convert the table to the pmSource entriesa
+    for (int i = 0; i < numSources; i++) {
+        psMetadata *row = psFitsReadTableRow(fits, i); // Table row
+
+        pmSource *source = pmSourceAlloc ();
+        pmModel *model = pmModelAlloc (modelType);
+        source->modelPSF  = model;
+        source->type = PM_SOURCE_TYPE_STAR; // XXX this should be added to the flags
+
+        // NOTE: A SEGV here because "model" is NULL is probably caused by not initialising the models.
+        PAR = model->params->data.F32;
+        dPAR = model->dparams->data.F32;
+
+        source->seq       = psMetadataLookupU32 (&status, row, "IPP_IDET");
+        PAR[PM_PAR_XPOS]  = psMetadataLookupF32 (&status, row, "X_PSF");
+        PAR[PM_PAR_YPOS]  = psMetadataLookupF32 (&status, row, "Y_PSF");
+        dPAR[PM_PAR_XPOS] = psMetadataLookupF32 (&status, row, "X_PSF_SIG");
+        dPAR[PM_PAR_YPOS] = psMetadataLookupF32 (&status, row, "Y_PSF_SIG");
+        axes.major        = psMetadataLookupF32 (&status, row, "PSF_MAJOR");
+        axes.minor        = psMetadataLookupF32 (&status, row, "PSF_MINOR");
+        axes.theta        = psMetadataLookupF32 (&status, row, "PSF_THETA");
+
+        PAR[PM_PAR_SKY]   = psMetadataLookupF32 (&status, row, "SKY");
+        dPAR[PM_PAR_SKY]  = psMetadataLookupF32 (&status, row, "SKY_SIGMA");
+        source->sky       = PAR[PM_PAR_SKY];
+        source->skyErr    = dPAR[PM_PAR_SKY];
+
+        // XXX use these to determine PAR[PM_PAR_I0]?
+        source->psfMag    = psMetadataLookupF32 (&status, row, "PSF_INST_MAG");
+        source->errMag    = psMetadataLookupF32 (&status, row, "PSF_INST_MAG_SIG");
+        source->apMag     = psMetadataLookupF32 (&status, row, "AP_MAG");
+
+	// XXX this scaling is incorrect: does not include the 2 \pi AREA factor 
+	PAR[PM_PAR_I0]    = (isfinite(source->psfMag)) ? pow(10.0, -0.4*source->psfMag) : NAN;
+	dPAR[PM_PAR_I0]   = (isfinite(source->psfMag)) ? PAR[PM_PAR_I0] * source->errMag : NAN;
+
+        pmPSF_AxesToModel (PAR, axes);
+
+        float peakMag     = psMetadataLookupF32 (&status, row, "PEAK_FLUX_AS_MAG");
+        float peakFlux    = (isfinite(peakMag)) ? pow(10.0, -0.4*peakMag) : NAN;
+
+	// recreate the peak to match (xPos, yPos) +/- (xErr, yErr)
+        source->peak = pmPeakAlloc(PAR[PM_PAR_XPOS], PAR[PM_PAR_YPOS], peakFlux, PM_PEAK_LONE);
+        source->peak->flux = peakFlux;
+        source->peak->dx   = dPAR[PM_PAR_XPOS];
+        source->peak->dy   = dPAR[PM_PAR_YPOS];
+
+        source->pixWeight = psMetadataLookupF32 (&status, row, "PSF_QF");
+        source->crNsigma  = psMetadataLookupF32 (&status, row, "CR_NSIGMA");
+        source->extNsigma = psMetadataLookupF32 (&status, row, "EXT_NSIGMA");
+
+	// note that some older versions used PSF_PROBABILITY: this was not well defined.
+        model->chisq 	  = psMetadataLookupF32 (&status, row, "PSF_CHISQ");
+        model->nDOF  	  = psMetadataLookupS32 (&status, row, "PSF_NDOF");
+        model->nPix  	  = psMetadataLookupS32 (&status, row, "PSF_NPIX");
+        model->radiusFit  = psMetadataLookupS32 (&status, row, "AP_MAG_RADIUS");
+
+	source->moments = pmMomentsAlloc ();
+        source->moments->Mxx = psMetadataLookupF32 (&status, row, "MOMENTS_XX");
+        source->moments->Mxy = psMetadataLookupF32 (&status, row, "MOMENTS_XY");
+        source->moments->Myy = psMetadataLookupF32 (&status, row, "MOMENTS_YY");
+
+        source->mode = psMetadataLookupU32 (&status, row, "FLAGS");
+        assert (status);
+
+        sources->data[i] = source;
+        psFree(row);
+    }
+
+    return sources;
+}
+
+// XXX this layout is still the same as PS1_DEV_1 
+bool pmSourcesWrite_CMF_PS1_V1_XSRC (psFits *fits, psArray *sources, char *extname, psMetadata *recipe)
+{
+
+    bool status;
+    psArray *table;
+    psMetadata *row;
+    psF32 *PAR, *dPAR;
+    psF32 xPos, yPos;
+    psF32 xErr, yErr;
+
+    // create a header to hold the output data
+    psMetadata *outhead = psMetadataAlloc ();
+
+    // write the links to the image header
+    psMetadataAddStr (outhead, PS_LIST_TAIL, "EXTNAME", PS_META_REPLACE, "xsrc table extension", extname);
+
+    // let's write these out in S/N order
+    sources = psArraySort (sources, pmSourceSortBySN);
+
+    table = psArrayAllocEmpty (sources->n);
+
+    // which extended source analyses should we perform?
+    bool doPetrosian    = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_PETROSIAN");
+    bool doIsophotal    = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_ISOPHOTAL");
+    bool doAnnuli       = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_ANNULI");
+    bool doKron         = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_KRON");
+
+    psVector *radialBinsLower = psMetadataLookupPtr (&status, recipe, "RADIAL.ANNULAR.BINS.LOWER");
+    psVector *radialBinsUpper = psMetadataLookupPtr (&status, recipe, "RADIAL.ANNULAR.BINS.UPPER");
+    assert (radialBinsLower->n == radialBinsUpper->n);
+
+    // we write out all sources, regardless of quality.  the source flags tell us the state
+    for (int i = 0; i < sources->n; i++) {
+	// skip source if it is not a ext sourc
+	// XXX we have two places that extended source parameters are measured:
+	// psphotExtendedSources, which measures the aperture-like parameters and (potentially) the psf-convolved extended source models,
+	// psphotFitEXT, which does the simple extended source model fit (not psf-convolved)
+	// should we require both?
+
+	pmSource *source = sources->data[i];
+
+	// skip sources without measurements
+	if (source->extpars == NULL) continue;
+
+	// we require a PSF model fit (ignore the real crud)
+	pmModel *model = source->modelPSF;
+	if (model == NULL) continue;
+
+	// XXX I need to split the extended models from the extended aperture measurements
+	PAR = model->params->data.F32;
+	dPAR = model->dparams->data.F32;
+	xPos = PAR[PM_PAR_XPOS];
+	yPos = PAR[PM_PAR_YPOS];
+	xErr = dPAR[PM_PAR_XPOS];
+	yErr = dPAR[PM_PAR_YPOS];
+
+        row = psMetadataAlloc ();
+
+        // XXX we are not writing out the mode (flags) or the type (psf, ext, etc)
+        psMetadataAdd (row, PS_LIST_TAIL, "IPP_IDET",         PS_DATA_U32, "IPP detection identifier index",             source->seq);
+        psMetadataAdd (row, PS_LIST_TAIL, "X_EXT",            PS_DATA_F32, "EXT model x coordinate",                     xPos);
+        psMetadataAdd (row, PS_LIST_TAIL, "Y_EXT",            PS_DATA_F32, "EXT model y coordinate",                     yPos);
+        psMetadataAdd (row, PS_LIST_TAIL, "X_EXT_SIG",        PS_DATA_F32, "Sigma in EXT x coordinate",                  xErr);
+        psMetadataAdd (row, PS_LIST_TAIL, "Y_EXT_SIG",        PS_DATA_F32, "Sigma in EXT y coordinate",                  yErr);
+
+	// Petrosian measurements
+	// XXX insert header data: petrosian ref radius, flux ratio
+	if (doPetrosian) {
+	    pmSourcePetrosianValues *petrosian = source->extpars->petrosian;
+	    if (petrosian) {
+		psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG",        PS_DATA_F32, "Petrosian Magnitude",       petrosian->mag);
+		psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG_ERR",    PS_DATA_F32, "Petrosian Magnitude Error", petrosian->magErr);
+		psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS",     PS_DATA_F32, "Petrosian Radius",          petrosian->rad);
+		psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_ERR", PS_DATA_F32, "Petrosian Radius Error",    petrosian->radErr);
+	    } else {
+		psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG",        PS_DATA_F32, "Petrosian Magnitude",       NAN);
+		psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG_ERR",    PS_DATA_F32, "Petrosian Magnitude Error", NAN);
+		psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS",     PS_DATA_F32, "Petrosian Radius",          NAN);
+		psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_ERR", PS_DATA_F32, "Petrosian Radius Error",    NAN);
+	    }
+	} 
+
+	// Kron measurements
+	if (doKron) {
+	    pmSourceKronValues *kron = source->extpars->kron;
+	    if (kron) {
+		psMetadataAdd (row, PS_LIST_TAIL, "KRON_MAG",        PS_DATA_F32, "Kron Magnitude",       kron->mag);
+		psMetadataAdd (row, PS_LIST_TAIL, "KRON_MAG_ERR",    PS_DATA_F32, "Kron Magnitude Error", kron->magErr);
+		psMetadataAdd (row, PS_LIST_TAIL, "KRON_RADIUS",     PS_DATA_F32, "Kron Radius",          kron->rad);
+		psMetadataAdd (row, PS_LIST_TAIL, "KRON_RADIUS_ERR", PS_DATA_F32, "Kron Radius Error",    kron->radErr);
+	    } else {
+		psMetadataAdd (row, PS_LIST_TAIL, "KRON_MAG",        PS_DATA_F32, "Kron Magnitude",       NAN);
+		psMetadataAdd (row, PS_LIST_TAIL, "KRON_MAG_ERR",    PS_DATA_F32, "Kron Magnitude Error", NAN);
+		psMetadataAdd (row, PS_LIST_TAIL, "KRON_RADIUS",     PS_DATA_F32, "Kron Radius",          NAN);
+		psMetadataAdd (row, PS_LIST_TAIL, "KRON_RADIUS_ERR", PS_DATA_F32, "Kron Radius Error",    NAN);
+	    }
+	}
+
+	// Isophot measurements
+	// XXX insert header data: isophotal level
+	if (doIsophotal) {
+	    pmSourceIsophotalValues *isophot = source->extpars->isophot;
+	    if (isophot) {
+		psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_MAG",        PS_DATA_F32, "Isophot Magnitude",       isophot->mag);
+		psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_MAG_ERR",    PS_DATA_F32, "Isophot Magnitude Error", isophot->magErr);
+		psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_RADIUS",     PS_DATA_F32, "Isophot Radius",          isophot->rad);
+		psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_RADIUS_ERR", PS_DATA_F32, "Isophot Radius Error",    isophot->radErr);
+	    } else {
+		psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_MAG",        PS_DATA_F32, "Isophot Magnitude",       NAN);
+		psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_MAG_ERR",    PS_DATA_F32, "Isophot Magnitude Error", NAN);
+		psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_RADIUS",     PS_DATA_F32, "Isophot Radius",          NAN);
+		psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_RADIUS_ERR", PS_DATA_F32, "Isophot Radius Error",    NAN);
+	    }
+	}
+
+	// Flux Annuli
+	if (doAnnuli) {
+	    pmSourceAnnuli *annuli = source->extpars->annuli;
+	    if (annuli) {
+		psVector *fluxVal = annuli->flux;
+		psVector *fluxErr = annuli->fluxErr;
+		psVector *fluxVar = annuli->fluxVar;
+
+		for (int j = 0; j < fluxVal->n; j++) {
+		    char name[32];
+		    sprintf (name, "FLUX_VAL_R_%02d", j);
+		    psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux value in annulus", fluxVal->data.F32[j]);
+		    sprintf (name, "FLUX_ERR_R_%02d", j);
+		    psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux error in annulus", fluxErr->data.F32[j]);
+		    sprintf (name, "FLUX_VAR_R_%02d", j);
+		    psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux stdev in annulus", fluxVar->data.F32[j]);
+		} 
+	    } else {
+		for (int j = 0; j < radialBinsLower->n; j++) {
+		    char name[32];
+		    sprintf (name, "FLUX_VAL_R_%02d", j);
+		    psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux value in annulus", NAN);
+		    sprintf (name, "FLUX_ERR_R_%02d", j);
+		    psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux error in annulus", NAN);
+		    sprintf (name, "FLUX_VAR_R_%02d", j);
+		    psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux stdev in annulus", NAN);
+		} 
+	    }
+	}
+
+	psArrayAdd (table, 100, row);
+	psFree (row);
+    }
+
+    if (table->n == 0) {
+	psFitsWriteBlank (fits, outhead, extname);
+	psFree (outhead);
+	psFree (table);
+	return true;
+    }
+
+    psTrace ("pmFPAfile", 5, "writing ext data %s\n", extname);
+    if (!psFitsWriteTable (fits, outhead, table, extname)) {
+	psError(PS_ERR_IO, false, "writing ext data %s\n", extname);
+	psFree (outhead);
+	psFree(table);
+	return false;
+    }
+    psFree (outhead);
+    psFree (table);
+
+    return true;
+}
+
+// XXX this layout is still the same as PS1_DEV_1 
+bool pmSourcesWrite_CMF_PS1_V1_XFIT (psFits *fits, psArray *sources, char *extname)
+{
+
+    psArray *table;
+    psMetadata *row;
+    psF32 *PAR, *dPAR;
+    psEllipseAxes axes;
+    psF32 xPos, yPos;
+    psF32 xErr, yErr;
+    char name[64];
+
+    // create a header to hold the output data
+    psMetadata *outhead = psMetadataAlloc ();
+
+    // write the links to the image header
+    psMetadataAddStr (outhead, PS_LIST_TAIL, "EXTNAME", PS_META_REPLACE, "xsrc table extension", extname);
+
+    // let's write these out in S/N order
+    sources = psArraySort (sources, pmSourceSortBySN);
+
+    // we are writing one row per model; we need to write out same number of columns for each row: find the max Nparams
+    int nParamMax = 0;
+    for (int i = 0; i < sources->n; i++) {
+	pmSource *source = sources->data[i];
+	if (source->modelFits == NULL) continue;
+	for (int j = 0; j < source->modelFits->n; j++) {
+	    pmModel *model = source->modelFits->data[j];
+	    assert (model);
+	    nParamMax = PS_MAX (nParamMax, model->params->n);
+	}
+    }
+
+    table = psArrayAllocEmpty (sources->n);
+
+    // we write out all sources, regardless of quality.  the source flags tell us the state
+    for (int i = 0; i < sources->n; i++) {
+
+	pmSource *source = sources->data[i];
+
+	// XXX if no model fits are saved, write out modelEXT?
+	if (source->modelFits == NULL) continue;
+
+	// We have multiple sources : need to flag the one used to subtract the light (the 'best' model)
+	for (int j = 0; j < source->modelFits->n; j++) {
+
+	    // choose the convolved EXT model, if available, otherwise the simple one
+	    pmModel *model = source->modelFits->data[j];
+	    assert (model);
+
+	    PAR = model->params->data.F32;
+	    dPAR = model->dparams->data.F32;
+	    xPos = PAR[PM_PAR_XPOS];
+	    yPos = PAR[PM_PAR_YPOS];
+	    xErr = dPAR[PM_PAR_XPOS];
+	    yErr = dPAR[PM_PAR_YPOS];
+
+	    axes = pmPSF_ModelToAxes (PAR, 20.0);
+
+	    row = psMetadataAlloc ();
+
+	    // XXX we are not writing out the mode (flags) or the type (psf, ext, etc)
+	    psMetadataAddU32 (row, PS_LIST_TAIL, "IPP_IDET",         0, "IPP detection identifier index",             source->seq);
+	    psMetadataAddF32 (row, PS_LIST_TAIL, "X_EXT",            0, "EXT model x coordinate",                     xPos);
+	    psMetadataAddF32 (row, PS_LIST_TAIL, "Y_EXT",            0, "EXT model y coordinate",                     yPos);
+	    psMetadataAddF32 (row, PS_LIST_TAIL, "X_EXT_SIG",        0, "Sigma in EXT x coordinate",                  xErr);
+	    psMetadataAddF32 (row, PS_LIST_TAIL, "Y_EXT_SIG",        0, "Sigma in EXT y coordinate",                  yErr);
+	    psMetadataAddF32 (row, PS_LIST_TAIL, "EXT_INST_MAG",     0, "EXT fit instrumental magnitude",             model->mag);
+	    psMetadataAddF32 (row, PS_LIST_TAIL, "EXT_INST_MAG_SIG", 0, "Sigma of PSF instrumental magnitude",        model->magErr);
+
+	    psMetadataAddF32 (row, PS_LIST_TAIL, "NPARAMS",          0, "number of model parameters",                 model->params->n);
+	    psMetadataAddStr (row, PS_LIST_TAIL, "MODEL_TYPE",       0, "name of model",                              pmModelClassGetName (model->type));
+
+	    // XXX these should be major and minor, not 'x' and 'y'
+	    psMetadataAddF32 (row, PS_LIST_TAIL, "EXT_WIDTH_MAJ",    0, "EXT width in x coordinate",                  axes.major);
+	    psMetadataAddF32 (row, PS_LIST_TAIL, "EXT_WIDTH_MIN",    0, "EXT width in y coordinate",                  axes.minor);
+	    psMetadataAddF32 (row, PS_LIST_TAIL, "EXT_THETA",        0, "EXT orientation angle",                      axes.theta);
+
+	    // write out the other generic parameters
+	    for (int k = 0; k < nParamMax; k++) {
+		if (k == PM_PAR_I0) continue;
+		if (k == PM_PAR_SKY) continue;
+		if (k == PM_PAR_XPOS) continue;
+		if (k == PM_PAR_YPOS) continue;
+		if (k == PM_PAR_SXX) continue;
+		if (k == PM_PAR_SXY) continue;
+		if (k == PM_PAR_SYY) continue;
+
+		snprintf (name, 64, "EXT_PAR_%02d", k);
+
+		if (k < model->params->n) {
+		    psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "", model->params->data.F32[k]);
+		} else {
+		    psMetadataAddF32 (row, PS_LIST_TAIL, name, PS_DATA_F32, "", NAN);
+		}
+	    }
+
+	    // XXX other parameters which may be set.
+	    // XXX flag / value to define the model
+	    // XXX write out the model type, fit status flags
+
+	    psArrayAdd (table, 100, row);
+	    psFree (row);
+	}
+    }
+
+    if (table->n == 0) {
+	psFitsWriteBlank (fits, outhead, extname);
+	psFree (outhead);
+	psFree (table);
+	return true;
+    }
+
+    psTrace ("pmFPAfile", 5, "writing ext data %s\n", extname);
+    if (!psFitsWriteTable (fits, outhead, table, extname)) {
+	psError(PS_ERR_IO, false, "writing ext data %s\n", extname);
+	psFree (outhead);
+	psFree(table);
+	return false;
+    }
+    psFree (outhead);
+    psFree (table);
+    return true;
+}
+
+bool pmSourceLocalAstrometry (psSphere *ptSky, float *posAngle, float *pltScale, pmChip *chip, float xPos, float yPos) {
+
+    pmFPA *fpa = chip->parent;
+
+    if (!chip->toFPA) goto escape;
+    if (!fpa->toTPA) goto escape;
+    if (!fpa->toSky) goto escape;
+
+    // generate RA,DEC
+    psPlane ptCH, ptFP, ptTP_o, ptTP_x, ptTP_y;
+
+    // calculate the astrometry for the coordinate of interest
+    ptCH.x = xPos;
+    ptCH.y = yPos;
+    psPlaneTransformApply (&ptFP, chip->toFPA, &ptCH);
+    psPlaneTransformApply (&ptTP_o, fpa->toTPA, &ptFP);
+    psDeproject (ptSky, &ptTP_o, fpa->toSky);
+
+    // calculate the astrometry for the coordinate + 1pix in X
+    ptCH.x = xPos + 1.0;
+    ptCH.y = yPos;
+    psPlaneTransformApply (&ptFP, chip->toFPA, &ptCH);
+    psPlaneTransformApply (&ptTP_x, fpa->toTPA, &ptFP);
+
+    // calculate the astrometry for the coordinate + 1pix in Y
+    ptCH.x = xPos;
+    ptCH.y = yPos + 1.0;
+    psPlaneTransformApply (&ptFP, chip->toFPA, &ptCH);
+    psPlaneTransformApply (&ptTP_y, fpa->toTPA, &ptFP);
+    
+    // the resulting Tangent Plane coordinates are in TP pixels; convert to local Tangent Plane
+    // degrees
+
+    float dTPx_dCHx = fpa->toSky->Xs * (ptTP_x.x - ptTP_o.x);
+    float dTPy_dCHx = fpa->toSky->Ys * (ptTP_x.y - ptTP_o.y);
+
+    float dTPx_dCHy = fpa->toSky->Xs * (ptTP_y.x - ptTP_o.x);
+    float dTPy_dCHy = fpa->toSky->Ys * (ptTP_y.y - ptTP_o.y);
+
+    float pltScale_x = hypot(dTPx_dCHx, dTPy_dCHx);
+    float pltScale_y = hypot(dTPx_dCHy, dTPy_dCHy);
+    *pltScale = 0.5*(pltScale_x + pltScale_y);
+
+    float posAngle_x = atan2 (+dTPy_dCHx, +dTPx_dCHx);
+    float posAngle_y = atan2 (-dTPy_dCHy, +dTPx_dCHy);
+    *posAngle = 0.5*(posAngle_x + posAngle_y);
+
+    return true;
+
+escape:
+    // no astrometry calibration, give up
+    ptSky->r = NAN;
+    ptSky->d = NAN;
+    *posAngle = NAN;
+    *pltScale = NAN;
+    
+    return false;
+}
Index: /branches/cnb_branch_20090215/psModules/src/objects/pmSourceIO_PS1_CAL_0.c
===================================================================
--- /branches/cnb_branch_20090215/psModules/src/objects/pmSourceIO_PS1_CAL_0.c	(revision 21535)
+++ /branches/cnb_branch_20090215/psModules/src/objects/pmSourceIO_PS1_CAL_0.c	(revision 21536)
@@ -3,6 +3,6 @@
  *  @author EAM, IfA
  *
- *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2008-12-08 02:51:14 $
+ *  @version $Revision: 1.2.14.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-19 17:59:50 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -49,6 +49,6 @@
 // XXX how do I generate the source tables which I need to send to PSPS?
 
-bool pmSourcesWrite_PS1_CAL_0 (psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader,
-                               psMetadata *tableHeader, char *extname, char *xsrcname)
+bool pmSourcesWrite_PS1_CAL_0 (psFits *fits, pmReadout *readout, psArray *sources,
+                               psMetadata *imageHeader, psMetadata *tableHeader, char *extname)
 {
     PS_ASSERT_PTR_NON_NULL(fits, false);
@@ -68,5 +68,5 @@
     pmFPA  *fpa  = chip->parent;
     if (!chip->toFPA || !fpa->toTPA || !fpa->toSky) {
-	psWarning ("astrometry calibration is missing, no calibrated coords");
+        psWarning ("astrometry calibration is missing, no calibrated coords");
     }
 
@@ -77,7 +77,7 @@
     float zeropt  = psMetadataLookupF32 (&status2, imageHeader, "ZPT_OBS");
     if (!status1 || !status2 || (exptime == 0.0)) {
-	psWarning ("exposure time or measured zero point not found for a readout, no calibrated mags");
+        psWarning ("exposure time or measured zero point not found for a readout, no calibrated mags");
     } else {
-	magOffset = zeropt + 2.5*log10(exptime);
+        magOffset = zeropt + 2.5*log10(exptime);
     }
 
@@ -90,7 +90,7 @@
     for (i = 0; i < sources->n; i++) {
         pmSource *source = (pmSource *) sources->data[i];
-	if (source->seq == -1) {
-	    source->seq = i;
-	}
+        if (source->seq == -1) {
+            source->seq = i;
+        }
 
         // no difference between PSF and non-PSF model
@@ -104,15 +104,15 @@
             xErr = dPAR[PM_PAR_XPOS];
             yErr = dPAR[PM_PAR_YPOS];
-	    if (isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX])) {
-		axes = pmPSF_ModelToAxes (PAR, 20.0);
-	    } else {
-		axes.major = NAN;
-		axes.minor = NAN;
-		axes.theta = NAN;
-	    }
-	    chisq = model->chisq;
-
-	    // need to determine the PSF photometry error: source->errMag is the error on the 'best' model mag.
-	    errMag = model->dparams->data.F32[PM_PAR_I0] / model->params->data.F32[PM_PAR_I0];
+            if (isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX])) {
+                axes = pmPSF_ModelToAxes (PAR, 20.0);
+            } else {
+                axes.major = NAN;
+                axes.minor = NAN;
+                axes.theta = NAN;
+            }
+            chisq = model->chisq;
+
+            // need to determine the PSF photometry error: source->errMag is the error on the 'best' model mag.
+            errMag = model->dparams->data.F32[PM_PAR_I0] / model->params->data.F32[PM_PAR_I0];
         } else {
             xPos = source->peak->xf;
@@ -123,26 +123,26 @@
             axes.minor = NAN;
             axes.theta = NAN;
-	    chisq = NAN;
-	    errMag = NAN;
-        }
-
-	float calMag = source->psfMag + magOffset;
+            chisq = NAN;
+            errMag = NAN;
+        }
+
+        float calMag = source->psfMag + magOffset;
         float peakMag = (source->peak->flux > 0) ? -2.5*log10(source->peak->flux) : NAN;
         psS16 nImageOverlap = 1;
 
-	// generate RA,DEC
-	psPlane ptCH, ptFP, ptTP;
-	psSphere ptSky;
-
-	ptCH.x = xPos;
-	ptCH.y = yPos;
-	if (chip->toFPA && fpa->toTPA && fpa->toSky) {
-	    psPlaneTransformApply (&ptFP, chip->toFPA, &ptCH);
-	    psPlaneTransformApply (&ptTP, fpa->toTPA, &ptFP);
-	    psDeproject (&ptSky, &ptTP, fpa->toSky);
-	} else {
-	    ptSky.r = NAN;
-	    ptSky.d = NAN;
-	}
+        // generate RA,DEC
+        psPlane ptCH, ptFP, ptTP;
+        psSphere ptSky;
+
+        ptCH.x = xPos;
+        ptCH.y = yPos;
+        if (chip->toFPA && fpa->toTPA && fpa->toSky) {
+            psPlaneTransformApply (&ptFP, chip->toFPA, &ptCH);
+            psPlaneTransformApply (&ptTP, fpa->toTPA, &ptFP);
+            psDeproject (&ptSky, &ptTP, fpa->toSky);
+        } else {
+            ptSky.r = NAN;
+            ptSky.d = NAN;
+        }
 
         row = psMetadataAlloc ();
@@ -150,5 +150,5 @@
         psMetadataAdd (row, PS_LIST_TAIL, "RA_PSF",           PS_DATA_F32, "PSF RA coordinate (degrees)",                ptSky.r*PS_DEG_RAD);
         psMetadataAdd (row, PS_LIST_TAIL, "DEC_PSF",          PS_DATA_F32, "PSF DEC coordinate (degrees)",               ptSky.d*PS_DEG_RAD);
-	// XXX need to do the error propagation correctly..
+        // XXX need to do the error propagation correctly..
         // psMetadataAdd (row, PS_LIST_TAIL, "RA_PSF_SIG",       PS_DATA_F32, "Sigma of PSF fit RA",                     dRA);
         // psMetadataAdd (row, PS_LIST_TAIL, "DEC_PSF_SIG",      PS_DATA_F32, "Sigma of PSF fit DEC",                    dDEC);
@@ -170,9 +170,9 @@
         psMetadataAdd (row, PS_LIST_TAIL, "EXT_NSIGMA",       PS_DATA_F32,  "Nsigma deviations from PSF to EXT",         source->extNsigma);
 
-	// EXT_NSIGMA will be NAN if: 1) contour ellipse is imaginary; 2) source is not
-	// subtracted
-
-	// CR_NSIGMA will be NAN if: 1) source is not subtracted; 2) source is on the image
-	// edge; 3) any pixels in the 3x3 peak region are masked; 
+        // EXT_NSIGMA will be NAN if: 1) contour ellipse is imaginary; 2) source is not
+        // subtracted
+
+        // CR_NSIGMA will be NAN if: 1) source is not subtracted; 2) source is on the image
+        // edge; 3) any pixels in the 3x3 peak region are masked;
 
         // XXX these should be major and minor, not 'x' and 'y'
@@ -277,6 +277,6 @@
         source->psfMag    = psMetadataLookupF32 (&status, row, "PSF_INST_MAG");
         source->errMag    = psMetadataLookupF32 (&status, row, "PSF_INST_MAG_SIG");
-	PAR[PM_PAR_I0]    = (isfinite(source->psfMag)) ? pow(10.0, -0.4*source->psfMag) : NAN;
-	dPAR[PM_PAR_I0]   = (isfinite(source->psfMag)) ? PAR[PM_PAR_I0] * source->errMag : NAN;
+        PAR[PM_PAR_I0]    = (isfinite(source->psfMag)) ? pow(10.0, -0.4*source->psfMag) : NAN;
+        dPAR[PM_PAR_I0]   = (isfinite(source->psfMag)) ? PAR[PM_PAR_I0] * source->errMag : NAN;
 
         pmPSF_AxesToModel (PAR, axes);
@@ -289,5 +289,5 @@
         source->pixWeight = psMetadataLookupF32 (&status, row, "PSF_QF");
 
-	// note that some older versions used PSF_PROBABILITY: this was not well defined.
+        // note that some older versions used PSF_PROBABILITY: this was not well defined.
         model->chisq      = psMetadataLookupF32 (&status, row, "PSF_CHISQ");
         source->crNsigma  = psMetadataLookupF32 (&status, row, "CR_NSIGMA");
@@ -321,5 +321,5 @@
     pmFPA  *fpa  = chip->parent;
     if (!chip->toFPA || !fpa->toTPA || !fpa->toSky) {
-	psWarning ("astrometry calibration is missing, no calibrated coords");
+        psWarning ("astrometry calibration is missing, no calibrated coords");
     }
 
@@ -331,8 +331,8 @@
     float zeropt  = psMetadataLookupF32 (&status2, imageHeader, "ZPT_OBS");
     if (!status1 || !status2 || (exptime == 0.0)) {
-	psWarning ("exposure time or measured zero point not found for a readout, no calibrated mags");
+        psWarning ("exposure time or measured zero point not found for a readout, no calibrated mags");
     } else {
-	magOffset = zeropt + 2.5*log10(exptime);
-	calMags = true;
+        magOffset = zeropt + 2.5*log10(exptime);
+        calMags = true;
     }
 
@@ -360,41 +360,41 @@
     // we write out all sources, regardless of quality.  the source flags tell us the state
     for (int i = 0; i < sources->n; i++) {
-	// skip source if it is not a ext sourc
-	// XXX we have two places that extended source parameters are measured:
-	// psphotExtendedSources, which measures the aperture-like parameters and (potentially) the psf-convolved extended source models,
-	// psphotFitEXT, which does the simple extended source model fit (not psf-convolved)
-	// should we require both?
-
-	pmSource *source = sources->data[i];
-
-	// skip sources without measurements
-	if (source->extpars == NULL) continue;
-
-	// we require a PSF model fit (ignore the real crud)
-	pmModel *model = source->modelPSF;
-	if (model == NULL) continue;
-
-	// XXX I need to split the extended models from the extended aperture measurements
-	PAR = model->params->data.F32;
-	dPAR = model->dparams->data.F32;
-	xPos = PAR[PM_PAR_XPOS];
-	yPos = PAR[PM_PAR_YPOS];
-	xErr = dPAR[PM_PAR_XPOS];
-	yErr = dPAR[PM_PAR_YPOS];
-
-	// generate RA,DEC
-	psPlane ptCH, ptFP, ptTP;
-	psSphere ptSky;
-
-	ptCH.x = xPos;
-	ptCH.y = yPos;
-	if (chip->toFPA && fpa->toTPA && fpa->toSky) {
-	    psPlaneTransformApply (&ptFP, chip->toFPA, &ptCH);
-	    psPlaneTransformApply (&ptTP, fpa->toTPA, &ptFP);
-	    psDeproject (&ptSky, &ptTP, fpa->toSky);
-	} else {
-	    ptSky.r = NAN;
-	    ptSky.d = NAN;
-	}
+        // skip source if it is not a ext sourc
+        // XXX we have two places that extended source parameters are measured:
+        // psphotExtendedSources, which measures the aperture-like parameters and (potentially) the psf-convolved extended source models,
+        // psphotFitEXT, which does the simple extended source model fit (not psf-convolved)
+        // should we require both?
+
+        pmSource *source = sources->data[i];
+
+        // skip sources without measurements
+        if (source->extpars == NULL) continue;
+
+        // we require a PSF model fit (ignore the real crud)
+        pmModel *model = source->modelPSF;
+        if (model == NULL) continue;
+
+        // XXX I need to split the extended models from the extended aperture measurements
+        PAR = model->params->data.F32;
+        dPAR = model->dparams->data.F32;
+        xPos = PAR[PM_PAR_XPOS];
+        yPos = PAR[PM_PAR_YPOS];
+        xErr = dPAR[PM_PAR_XPOS];
+        yErr = dPAR[PM_PAR_YPOS];
+
+        // generate RA,DEC
+        psPlane ptCH, ptFP, ptTP;
+        psSphere ptSky;
+
+        ptCH.x = xPos;
+        ptCH.y = yPos;
+        if (chip->toFPA && fpa->toTPA && fpa->toSky) {
+            psPlaneTransformApply (&ptFP, chip->toFPA, &ptCH);
+            psPlaneTransformApply (&ptTP, fpa->toTPA, &ptFP);
+            psDeproject (&ptSky, &ptTP, fpa->toSky);
+        } else {
+            ptSky.r = NAN;
+            ptSky.d = NAN;
+        }
 
         row = psMetadataAlloc ();
@@ -410,113 +410,113 @@
         psMetadataAdd (row, PS_LIST_TAIL, "Y_EXT_SIG",        PS_DATA_F32, "Sigma in EXT y coordinate",                  yErr);
 
-	// Petrosian measurements
-	// XXX insert header data: petrosian ref radius, flux ratio
-	if (doPetrosian) {
-	    pmSourcePetrosianValues *petrosian = source->extpars->petrosian;
-	    if (petrosian) {
-		if (calMags) {
-		    psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG_CAL",    PS_DATA_F32, "Petrosian Magnitude (calibrated)", petrosian->mag + magOffset);
-		} else {
-		    psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG_INST",   PS_DATA_F32, "Petrosian Magnitude (instrumental)", petrosian->mag);
-		}
-		psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG_ERR",    PS_DATA_F32, "Petrosian Magnitude Error", petrosian->magErr);
-		psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS",     PS_DATA_F32, "Petrosian Radius",          petrosian->rad);
-		psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_ERR", PS_DATA_F32, "Petrosian Radius Error",    petrosian->radErr);
-	    } else {
-		psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG",        PS_DATA_F32, "Petrosian Magnitude",       NAN);
-		psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG_ERR",    PS_DATA_F32, "Petrosian Magnitude Error", NAN);
-		psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS",     PS_DATA_F32, "Petrosian Radius",          NAN);
-		psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_ERR", PS_DATA_F32, "Petrosian Radius Error",    NAN);
-	    }
-	} 
-
-	// Kron measurements
-	if (doKron) {
-	    pmSourceKronValues *kron = source->extpars->kron;
-	    if (kron) {
-		if (calMags) {
-		    psMetadataAdd (row, PS_LIST_TAIL, "KRON_MAG_CAL",  PS_DATA_F32, "Kron Magnitude",     kron->mag + magOffset);
-		} else {
-		    psMetadataAdd (row, PS_LIST_TAIL, "KRON_MAG_INST", PS_DATA_F32, "Kron Magnitude",     kron->mag);
-		}
-		psMetadataAdd (row, PS_LIST_TAIL, "KRON_MAG_ERR",    PS_DATA_F32, "Kron Magnitude Error", kron->magErr);
-		psMetadataAdd (row, PS_LIST_TAIL, "KRON_RADIUS",     PS_DATA_F32, "Kron Radius",          kron->rad);
-		psMetadataAdd (row, PS_LIST_TAIL, "KRON_RADIUS_ERR", PS_DATA_F32, "Kron Radius Error",    kron->radErr);
-	    } else {
-		psMetadataAdd (row, PS_LIST_TAIL, "KRON_MAG",        PS_DATA_F32, "Kron Magnitude",       NAN);
-		psMetadataAdd (row, PS_LIST_TAIL, "KRON_MAG_ERR",    PS_DATA_F32, "Kron Magnitude Error", NAN);
-		psMetadataAdd (row, PS_LIST_TAIL, "KRON_RADIUS",     PS_DATA_F32, "Kron Radius",          NAN);
-		psMetadataAdd (row, PS_LIST_TAIL, "KRON_RADIUS_ERR", PS_DATA_F32, "Kron Radius Error",    NAN);
-	    }
-	}
-
-	// Isophot measurements
-	// XXX insert header data: isophotal level
-	if (doIsophotal) {
-	    pmSourceIsophotalValues *isophot = source->extpars->isophot;
-	    if (isophot) {
-		if (calMags) {
-		    psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_MAG_CAL",    PS_DATA_F32, "Isophot Magnitude (calibrated)",   isophot->mag + magOffset);
-		} else {
-		    psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_MAG_INST",   PS_DATA_F32, "Isophot Magnitude (uncalibrated)", isophot->mag);
-		}
-		psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_MAG_ERR",    PS_DATA_F32, "Isophot Magnitude Error", isophot->magErr);
-		psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_RADIUS",     PS_DATA_F32, "Isophot Radius",          isophot->rad);
-		psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_RADIUS_ERR", PS_DATA_F32, "Isophot Radius Error",    isophot->radErr);
-	    } else {
-		psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_MAG",        PS_DATA_F32, "Isophot Magnitude",       NAN);
-		psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_MAG_ERR",    PS_DATA_F32, "Isophot Magnitude Error", NAN);
-		psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_RADIUS",     PS_DATA_F32, "Isophot Radius",          NAN);
-		psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_RADIUS_ERR", PS_DATA_F32, "Isophot Radius Error",    NAN);
-	    }
-	}
-
-	// Flux Annuli
-	if (doAnnuli) {
-	    pmSourceAnnuli *annuli = source->extpars->annuli;
-	    if (annuli) {
-		psVector *fluxVal = annuli->flux;
-		psVector *fluxErr = annuli->fluxErr;
-		psVector *fluxVar = annuli->fluxVar;
-
-		for (int j = 0; j < fluxVal->n; j++) {
-		    char name[32];
-		    sprintf (name, "FLUX_VAL_R_%02d", j);
-		    psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux value in annulus", fluxVal->data.F32[j]);
-		    sprintf (name, "FLUX_ERR_R_%02d", j);
-		    psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux error in annulus", fluxErr->data.F32[j]);
-		    sprintf (name, "FLUX_VAR_R_%02d", j);
-		    psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux stdev in annulus", fluxVar->data.F32[j]);
-		} 
-	    } else {
-		for (int j = 0; j < radialBinsLower->n; j++) {
-		    char name[32];
-		    sprintf (name, "FLUX_VAL_R_%02d", j);
-		    psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux value in annulus", NAN);
-		    sprintf (name, "FLUX_ERR_R_%02d", j);
-		    psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux error in annulus", NAN);
-		    sprintf (name, "FLUX_VAR_R_%02d", j);
-		    psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux stdev in annulus", NAN);
-		} 
-	    }
-	}
-
-	psArrayAdd (table, 100, row);
-	psFree (row);
+        // Petrosian measurements
+        // XXX insert header data: petrosian ref radius, flux ratio
+        if (doPetrosian) {
+            pmSourcePetrosianValues *petrosian = source->extpars->petrosian;
+            if (petrosian) {
+                if (calMags) {
+                    psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG_CAL",    PS_DATA_F32, "Petrosian Magnitude (calibrated)", petrosian->mag + magOffset);
+                } else {
+                    psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG_INST",   PS_DATA_F32, "Petrosian Magnitude (instrumental)", petrosian->mag);
+                }
+                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG_ERR",    PS_DATA_F32, "Petrosian Magnitude Error", petrosian->magErr);
+                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS",     PS_DATA_F32, "Petrosian Radius",          petrosian->rad);
+                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_ERR", PS_DATA_F32, "Petrosian Radius Error",    petrosian->radErr);
+            } else {
+                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG",        PS_DATA_F32, "Petrosian Magnitude",       NAN);
+                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG_ERR",    PS_DATA_F32, "Petrosian Magnitude Error", NAN);
+                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS",     PS_DATA_F32, "Petrosian Radius",          NAN);
+                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_ERR", PS_DATA_F32, "Petrosian Radius Error",    NAN);
+            }
+        }
+
+        // Kron measurements
+        if (doKron) {
+            pmSourceKronValues *kron = source->extpars->kron;
+            if (kron) {
+                if (calMags) {
+                    psMetadataAdd (row, PS_LIST_TAIL, "KRON_MAG_CAL",  PS_DATA_F32, "Kron Magnitude",     kron->mag + magOffset);
+                } else {
+                    psMetadataAdd (row, PS_LIST_TAIL, "KRON_MAG_INST", PS_DATA_F32, "Kron Magnitude",     kron->mag);
+                }
+                psMetadataAdd (row, PS_LIST_TAIL, "KRON_MAG_ERR",    PS_DATA_F32, "Kron Magnitude Error", kron->magErr);
+                psMetadataAdd (row, PS_LIST_TAIL, "KRON_RADIUS",     PS_DATA_F32, "Kron Radius",          kron->rad);
+                psMetadataAdd (row, PS_LIST_TAIL, "KRON_RADIUS_ERR", PS_DATA_F32, "Kron Radius Error",    kron->radErr);
+            } else {
+                psMetadataAdd (row, PS_LIST_TAIL, "KRON_MAG",        PS_DATA_F32, "Kron Magnitude",       NAN);
+                psMetadataAdd (row, PS_LIST_TAIL, "KRON_MAG_ERR",    PS_DATA_F32, "Kron Magnitude Error", NAN);
+                psMetadataAdd (row, PS_LIST_TAIL, "KRON_RADIUS",     PS_DATA_F32, "Kron Radius",          NAN);
+                psMetadataAdd (row, PS_LIST_TAIL, "KRON_RADIUS_ERR", PS_DATA_F32, "Kron Radius Error",    NAN);
+            }
+        }
+
+        // Isophot measurements
+        // XXX insert header data: isophotal level
+        if (doIsophotal) {
+            pmSourceIsophotalValues *isophot = source->extpars->isophot;
+            if (isophot) {
+                if (calMags) {
+                    psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_MAG_CAL",    PS_DATA_F32, "Isophot Magnitude (calibrated)",   isophot->mag + magOffset);
+                } else {
+                    psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_MAG_INST",   PS_DATA_F32, "Isophot Magnitude (uncalibrated)", isophot->mag);
+                }
+                psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_MAG_ERR",    PS_DATA_F32, "Isophot Magnitude Error", isophot->magErr);
+                psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_RADIUS",     PS_DATA_F32, "Isophot Radius",          isophot->rad);
+                psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_RADIUS_ERR", PS_DATA_F32, "Isophot Radius Error",    isophot->radErr);
+            } else {
+                psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_MAG",        PS_DATA_F32, "Isophot Magnitude",       NAN);
+                psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_MAG_ERR",    PS_DATA_F32, "Isophot Magnitude Error", NAN);
+                psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_RADIUS",     PS_DATA_F32, "Isophot Radius",          NAN);
+                psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_RADIUS_ERR", PS_DATA_F32, "Isophot Radius Error",    NAN);
+            }
+        }
+
+        // Flux Annuli
+        if (doAnnuli) {
+            pmSourceAnnuli *annuli = source->extpars->annuli;
+            if (annuli) {
+                psVector *fluxVal = annuli->flux;
+                psVector *fluxErr = annuli->fluxErr;
+                psVector *fluxVar = annuli->fluxVar;
+
+                for (int j = 0; j < fluxVal->n; j++) {
+                    char name[32];
+                    sprintf (name, "FLUX_VAL_R_%02d", j);
+                    psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux value in annulus", fluxVal->data.F32[j]);
+                    sprintf (name, "FLUX_ERR_R_%02d", j);
+                    psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux error in annulus", fluxErr->data.F32[j]);
+                    sprintf (name, "FLUX_VAR_R_%02d", j);
+                    psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux stdev in annulus", fluxVar->data.F32[j]);
+                }
+            } else {
+                for (int j = 0; j < radialBinsLower->n; j++) {
+                    char name[32];
+                    sprintf (name, "FLUX_VAL_R_%02d", j);
+                    psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux value in annulus", NAN);
+                    sprintf (name, "FLUX_ERR_R_%02d", j);
+                    psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux error in annulus", NAN);
+                    sprintf (name, "FLUX_VAR_R_%02d", j);
+                    psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux stdev in annulus", NAN);
+                }
+            }
+        }
+
+        psArrayAdd (table, 100, row);
+        psFree (row);
     }
 
     if (table->n == 0) {
-	psFitsWriteBlank (fits, outhead, extname);
-	psFree (outhead);
-	psFree (table);
-	return true;
+        psFitsWriteBlank (fits, outhead, extname);
+        psFree (outhead);
+        psFree (table);
+        return true;
     }
 
     psTrace ("pmFPAfile", 5, "writing ext data %s\n", extname);
     if (!psFitsWriteTable (fits, outhead, table, extname)) {
-	psError(PS_ERR_IO, false, "writing ext data %s\n", extname);
-	psFree (outhead);
-	psFree(table);
-	return false;
+        psError(PS_ERR_IO, false, "writing ext data %s\n", extname);
+        psFree (outhead);
+        psFree(table);
+        return false;
     }
     psFree (outhead);
@@ -540,5 +540,5 @@
     pmFPA  *fpa  = chip->parent;
     if (!chip->toFPA || !fpa->toTPA || !fpa->toSky) {
-	psWarning ("astrometry calibration is missing, no calibrated coords");
+        psWarning ("astrometry calibration is missing, no calibrated coords");
     }
 
@@ -549,7 +549,7 @@
     float zeropt  = psMetadataLookupF32 (&status2, imageHeader, "ZPT_OBS");
     if (!status1 || !status2 || (exptime == 0.0)) {
-	psWarning ("exposure time or measured zero point not found for a readout, no calibrated mags");
+        psWarning ("exposure time or measured zero point not found for a readout, no calibrated mags");
     } else {
-	magOffset = zeropt + 2.5*log10(exptime);
+        magOffset = zeropt + 2.5*log10(exptime);
     }
 
@@ -566,11 +566,11 @@
     int nParamMax = 0;
     for (int i = 0; i < sources->n; i++) {
-	pmSource *source = sources->data[i];
-	if (source->modelFits == NULL) continue;
-	for (int j = 0; j < source->modelFits->n; j++) {
-	    pmModel *model = source->modelFits->data[j];
-	    assert (model);
-	    nParamMax = PS_MAX (nParamMax, model->params->n);
-	}
+        pmSource *source = sources->data[i];
+        if (source->modelFits == NULL) continue;
+        for (int j = 0; j < source->modelFits->n; j++) {
+            pmModel *model = source->modelFits->data[j];
+            assert (model);
+            nParamMax = PS_MAX (nParamMax, model->params->n);
+        }
     }
 
@@ -580,103 +580,103 @@
     for (int i = 0; i < sources->n; i++) {
 
-	pmSource *source = sources->data[i];
-
-	// XXX if no model fits are saved, write out modelEXT?
-	if (source->modelFits == NULL) continue;
-
-	// We have multiple sources : need to flag the one used to subtract the light (the 'best' model)
-	for (int j = 0; j < source->modelFits->n; j++) {
-
-	    // choose the convolved EXT model, if available, otherwise the simple one
-	    pmModel *model = source->modelFits->data[j];
-	    assert (model);
-
-	    PAR = model->params->data.F32;
-	    dPAR = model->dparams->data.F32;
-	    xPos = PAR[PM_PAR_XPOS];
-	    yPos = PAR[PM_PAR_YPOS];
-	    xErr = dPAR[PM_PAR_XPOS];
-	    yErr = dPAR[PM_PAR_YPOS];
-
-	    axes = pmPSF_ModelToAxes (PAR, 20.0);
-
-	    // generate RA,DEC
-	    psPlane ptCH, ptFP, ptTP;
-	    psSphere ptSky;
-
-	    ptCH.x = xPos;
-	    ptCH.y = yPos;
-	    if (chip->toFPA && fpa->toTPA && fpa->toSky) {
-		psPlaneTransformApply (&ptFP, chip->toFPA, &ptCH);
-		psPlaneTransformApply (&ptTP, fpa->toTPA, &ptFP);
-		psDeproject (&ptSky, &ptTP, fpa->toSky);
-	    } else {
-		ptSky.r = NAN;
-		ptSky.d = NAN;
-	    }
-
-	    row = psMetadataAlloc ();
-
-	    // XXX we are not writing out the mode (flags) or the type (psf, ext, etc)
-	    psMetadataAddU32 (row, PS_LIST_TAIL, "IPP_IDET",         0, "IPP detection identifier index",             source->seq);
-	    psMetadataAddF32 (row, PS_LIST_TAIL, "RA_EXT",           0, "EXT model RA (degrees)",                     ptSky.r);
-	    psMetadataAddF32 (row, PS_LIST_TAIL, "DEC_EXT",          0, "EXT model DEC (degrees)",                    ptSky.d);
-	    psMetadataAddF32 (row, PS_LIST_TAIL, "X_EXT",            0, "EXT model x coordinate",                     xPos);
-	    psMetadataAddF32 (row, PS_LIST_TAIL, "Y_EXT",            0, "EXT model y coordinate",                     yPos);
-	    psMetadataAddF32 (row, PS_LIST_TAIL, "X_EXT_SIG",        0, "Sigma in EXT x coordinate",                  xErr);
-	    psMetadataAddF32 (row, PS_LIST_TAIL, "Y_EXT_SIG",        0, "Sigma in EXT y coordinate",                  yErr);
-	    psMetadataAddF32 (row, PS_LIST_TAIL, "EXT_CAL_MAG",      0, "EXT fit calibrated magnitude",               model->mag + magOffset);
-	    psMetadataAddF32 (row, PS_LIST_TAIL, "EXT_INST_MAG",     0, "EXT fit instrumental magnitude",             model->mag);
-	    psMetadataAddF32 (row, PS_LIST_TAIL, "EXT_INST_MAG_SIG", 0, "Sigma of PSF instrumental magnitude",        model->magErr);
-
-	    psMetadataAddF32 (row, PS_LIST_TAIL, "NPARAMS",          0, "number of model parameters",                 model->params->n);
-	    psMetadataAddStr (row, PS_LIST_TAIL, "MODEL_TYPE",       0, "name of model",                              pmModelClassGetName (model->type));
-
-	    // XXX these should be major and minor, not 'x' and 'y'
-	    psMetadataAddF32 (row, PS_LIST_TAIL, "EXT_WIDTH_MAJ",    0, "EXT width in x coordinate",                  axes.major);
-	    psMetadataAddF32 (row, PS_LIST_TAIL, "EXT_WIDTH_MIN",    0, "EXT width in y coordinate",                  axes.minor);
-	    psMetadataAddF32 (row, PS_LIST_TAIL, "EXT_THETA",        0, "EXT orientation angle",                      axes.theta);
-
-	    // write out the other generic parameters
-	    for (int k = 0; k < nParamMax; k++) {
-		if (k == PM_PAR_I0) continue;
-		if (k == PM_PAR_SKY) continue;
-		if (k == PM_PAR_XPOS) continue;
-		if (k == PM_PAR_YPOS) continue;
-		if (k == PM_PAR_SXX) continue;
-		if (k == PM_PAR_SXY) continue;
-		if (k == PM_PAR_SYY) continue;
-
-		snprintf (name, 64, "EXT_PAR_%02d", k);
-
-		if (k < model->params->n) {
-		    psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "", model->params->data.F32[k]);
-		} else {
-		    psMetadataAddF32 (row, PS_LIST_TAIL, name, PS_DATA_F32, "", NAN);
-		}
-	    }
-
-	    // XXX other parameters which may be set.
-	    // XXX flag / value to define the model
-	    // XXX write out the model type, fit status flags
-
-	    psArrayAdd (table, 100, row);
-	    psFree (row);
-	}
+        pmSource *source = sources->data[i];
+
+        // XXX if no model fits are saved, write out modelEXT?
+        if (source->modelFits == NULL) continue;
+
+        // We have multiple sources : need to flag the one used to subtract the light (the 'best' model)
+        for (int j = 0; j < source->modelFits->n; j++) {
+
+            // choose the convolved EXT model, if available, otherwise the simple one
+            pmModel *model = source->modelFits->data[j];
+            assert (model);
+
+            PAR = model->params->data.F32;
+            dPAR = model->dparams->data.F32;
+            xPos = PAR[PM_PAR_XPOS];
+            yPos = PAR[PM_PAR_YPOS];
+            xErr = dPAR[PM_PAR_XPOS];
+            yErr = dPAR[PM_PAR_YPOS];
+
+            axes = pmPSF_ModelToAxes (PAR, 20.0);
+
+            // generate RA,DEC
+            psPlane ptCH, ptFP, ptTP;
+            psSphere ptSky;
+
+            ptCH.x = xPos;
+            ptCH.y = yPos;
+            if (chip->toFPA && fpa->toTPA && fpa->toSky) {
+                psPlaneTransformApply (&ptFP, chip->toFPA, &ptCH);
+                psPlaneTransformApply (&ptTP, fpa->toTPA, &ptFP);
+                psDeproject (&ptSky, &ptTP, fpa->toSky);
+            } else {
+                ptSky.r = NAN;
+                ptSky.d = NAN;
+            }
+
+            row = psMetadataAlloc ();
+
+            // XXX we are not writing out the mode (flags) or the type (psf, ext, etc)
+            psMetadataAddU32 (row, PS_LIST_TAIL, "IPP_IDET",         0, "IPP detection identifier index",             source->seq);
+            psMetadataAddF32 (row, PS_LIST_TAIL, "RA_EXT",           0, "EXT model RA (degrees)",                     ptSky.r);
+            psMetadataAddF32 (row, PS_LIST_TAIL, "DEC_EXT",          0, "EXT model DEC (degrees)",                    ptSky.d);
+            psMetadataAddF32 (row, PS_LIST_TAIL, "X_EXT",            0, "EXT model x coordinate",                     xPos);
+            psMetadataAddF32 (row, PS_LIST_TAIL, "Y_EXT",            0, "EXT model y coordinate",                     yPos);
+            psMetadataAddF32 (row, PS_LIST_TAIL, "X_EXT_SIG",        0, "Sigma in EXT x coordinate",                  xErr);
+            psMetadataAddF32 (row, PS_LIST_TAIL, "Y_EXT_SIG",        0, "Sigma in EXT y coordinate",                  yErr);
+            psMetadataAddF32 (row, PS_LIST_TAIL, "EXT_CAL_MAG",      0, "EXT fit calibrated magnitude",               model->mag + magOffset);
+            psMetadataAddF32 (row, PS_LIST_TAIL, "EXT_INST_MAG",     0, "EXT fit instrumental magnitude",             model->mag);
+            psMetadataAddF32 (row, PS_LIST_TAIL, "EXT_INST_MAG_SIG", 0, "Sigma of PSF instrumental magnitude",        model->magErr);
+
+            psMetadataAddF32 (row, PS_LIST_TAIL, "NPARAMS",          0, "number of model parameters",                 model->params->n);
+            psMetadataAddStr (row, PS_LIST_TAIL, "MODEL_TYPE",       0, "name of model",                              pmModelClassGetName (model->type));
+
+            // XXX these should be major and minor, not 'x' and 'y'
+            psMetadataAddF32 (row, PS_LIST_TAIL, "EXT_WIDTH_MAJ",    0, "EXT width in x coordinate",                  axes.major);
+            psMetadataAddF32 (row, PS_LIST_TAIL, "EXT_WIDTH_MIN",    0, "EXT width in y coordinate",                  axes.minor);
+            psMetadataAddF32 (row, PS_LIST_TAIL, "EXT_THETA",        0, "EXT orientation angle",                      axes.theta);
+
+            // write out the other generic parameters
+            for (int k = 0; k < nParamMax; k++) {
+                if (k == PM_PAR_I0) continue;
+                if (k == PM_PAR_SKY) continue;
+                if (k == PM_PAR_XPOS) continue;
+                if (k == PM_PAR_YPOS) continue;
+                if (k == PM_PAR_SXX) continue;
+                if (k == PM_PAR_SXY) continue;
+                if (k == PM_PAR_SYY) continue;
+
+                snprintf (name, 64, "EXT_PAR_%02d", k);
+
+                if (k < model->params->n) {
+                    psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "", model->params->data.F32[k]);
+                } else {
+                    psMetadataAddF32 (row, PS_LIST_TAIL, name, PS_DATA_F32, "", NAN);
+                }
+            }
+
+            // XXX other parameters which may be set.
+            // XXX flag / value to define the model
+            // XXX write out the model type, fit status flags
+
+            psArrayAdd (table, 100, row);
+            psFree (row);
+        }
     }
 
     if (table->n == 0) {
-	psFitsWriteBlank (fits, outhead, extname);
-	psFree (outhead);
-	psFree (table);
-	return true;
+        psFitsWriteBlank (fits, outhead, extname);
+        psFree (outhead);
+        psFree (table);
+        return true;
     }
 
     psTrace ("pmFPAfile", 5, "writing ext data %s\n", extname);
     if (!psFitsWriteTable (fits, outhead, table, extname)) {
-	psError(PS_ERR_IO, false, "writing ext data %s\n", extname);
-	psFree (outhead);
-	psFree(table);
-	return false;
+        psError(PS_ERR_IO, false, "writing ext data %s\n", extname);
+        psFree (outhead);
+        psFree(table);
+        return false;
     }
     psFree (outhead);
Index: /branches/cnb_branch_20090215/psModules/src/objects/pmSourceIO_PS1_DEV_1.c
===================================================================
--- /branches/cnb_branch_20090215/psModules/src/objects/pmSourceIO_PS1_DEV_1.c	(revision 21535)
+++ /branches/cnb_branch_20090215/psModules/src/objects/pmSourceIO_PS1_DEV_1.c	(revision 21536)
@@ -3,6 +3,6 @@
  *  @author EAM, IfA
  *
- *  @version $Revision: 1.14 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2008-12-08 02:51:14 $
+ *  @version $Revision: 1.14.14.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-19 17:59:50 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -49,6 +49,6 @@
 // XXX how do I generate the source tables which I need to send to PSPS?
 
-bool pmSourcesWrite_PS1_DEV_1 (psFits *fits, psArray *sources, psMetadata *imageHeader,
-                               psMetadata *tableHeader, char *extname, char *xsrcname)
+bool pmSourcesWrite_PS1_DEV_1 (psFits *fits, psArray *sources,
+                               psMetadata *imageHeader, psMetadata *tableHeader, char *extname)
 {
     PS_ASSERT_PTR_NON_NULL(fits, false);
@@ -73,7 +73,7 @@
     for (i = 0; i < sources->n; i++) {
         pmSource *source = (pmSource *) sources->data[i];
-	if (source->seq == -1) {
-	    source->seq = i;
-	}
+        if (source->seq == -1) {
+            source->seq = i;
+        }
 
         // no difference between PSF and non-PSF model
@@ -87,15 +87,15 @@
             xErr = dPAR[PM_PAR_XPOS];
             yErr = dPAR[PM_PAR_YPOS];
-	    if (isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX])) {
-		axes = pmPSF_ModelToAxes (PAR, 20.0);
-	    } else {
-		axes.major = NAN;
-		axes.minor = NAN;
-		axes.theta = NAN;
-	    }
-	    chisq = model->chisq;
-
-	    // need to determine the PSF photometry error: source->errMag is the error on the 'best' model mag.
-	    errMag = model->dparams->data.F32[PM_PAR_I0] / model->params->data.F32[PM_PAR_I0];
+            if (isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX])) {
+                axes = pmPSF_ModelToAxes (PAR, 20.0);
+            } else {
+                axes.major = NAN;
+                axes.minor = NAN;
+                axes.theta = NAN;
+            }
+            chisq = model->chisq;
+
+            // need to determine the PSF photometry error: source->errMag is the error on the 'best' model mag.
+            errMag = model->dparams->data.F32[PM_PAR_I0] / model->params->data.F32[PM_PAR_I0];
         } else {
             xPos = source->peak->xf;
@@ -106,6 +106,6 @@
             axes.minor = NAN;
             axes.theta = NAN;
-	    chisq = NAN;
-	    errMag = NAN;
+            chisq = NAN;
+            errMag = NAN;
         }
 
@@ -130,11 +130,11 @@
         psMetadataAdd (row, PS_LIST_TAIL, "EXT_NSIGMA",       PS_DATA_F32,  "Nsigma deviations from PSF to EXT",         source->extNsigma);
 
-	// EXT_NSIGMA will be NAN if: 1) contour ellipse is imaginary; 2) source is not
-	// subtracted
-
-	// CR_NSIGMA will be NAN if: 1) source is not subtracted; 2) source is on the image
-	// edge; 3) any pixels in the 3x3 peak region are masked; 
-
-	// CR_NSIGMA and 
+        // EXT_NSIGMA will be NAN if: 1) contour ellipse is imaginary; 2) source is not
+        // subtracted
+
+        // CR_NSIGMA will be NAN if: 1) source is not subtracted; 2) source is on the image
+        // edge; 3) any pixels in the 3x3 peak region are masked;
+
+        // CR_NSIGMA and
 
         // XXX these should be major and minor, not 'x' and 'y'
@@ -247,6 +247,6 @@
         source->psfMag    = psMetadataLookupF32 (&status, row, "PSF_INST_MAG");
         source->errMag    = psMetadataLookupF32 (&status, row, "PSF_INST_MAG_SIG");
-	PAR[PM_PAR_I0]    = (isfinite(source->psfMag)) ? pow(10.0, -0.4*source->psfMag) : NAN;
-	dPAR[PM_PAR_I0]   = (isfinite(source->psfMag)) ? PAR[PM_PAR_I0] * source->errMag : NAN;
+        PAR[PM_PAR_I0]    = (isfinite(source->psfMag)) ? pow(10.0, -0.4*source->psfMag) : NAN;
+        dPAR[PM_PAR_I0]   = (isfinite(source->psfMag)) ? PAR[PM_PAR_I0] * source->errMag : NAN;
 
         pmPSF_AxesToModel (PAR, axes);
@@ -259,5 +259,5 @@
         source->pixWeight = psMetadataLookupF32 (&status, row, "PSF_QF");
 
-	// note that some older versions used PSF_PROBABILITY: this was not well defined.
+        // note that some older versions used PSF_PROBABILITY: this was not well defined.
         model->chisq      = psMetadataLookupF32 (&status, row, "PSF_CHISQ");
         source->crNsigma  = psMetadataLookupF32 (&status, row, "CR_NSIGMA");
@@ -311,26 +311,26 @@
     // we write out all sources, regardless of quality.  the source flags tell us the state
     for (int i = 0; i < sources->n; i++) {
-	// skip source if it is not a ext sourc
-	// XXX we have two places that extended source parameters are measured:
-	// psphotExtendedSources, which measures the aperture-like parameters and (potentially) the psf-convolved extended source models,
-	// psphotFitEXT, which does the simple extended source model fit (not psf-convolved)
-	// should we require both?
-
-	pmSource *source = sources->data[i];
-
-	// skip sources without measurements
-	if (source->extpars == NULL) continue;
-
-	// we require a PSF model fit (ignore the real crud)
-	pmModel *model = source->modelPSF;
-	if (model == NULL) continue;
-
-	// XXX I need to split the extended models from the extended aperture measurements
-	PAR = model->params->data.F32;
-	dPAR = model->dparams->data.F32;
-	xPos = PAR[PM_PAR_XPOS];
-	yPos = PAR[PM_PAR_YPOS];
-	xErr = dPAR[PM_PAR_XPOS];
-	yErr = dPAR[PM_PAR_YPOS];
+        // skip source if it is not a ext sourc
+        // XXX we have two places that extended source parameters are measured:
+        // psphotExtendedSources, which measures the aperture-like parameters and (potentially) the psf-convolved extended source models,
+        // psphotFitEXT, which does the simple extended source model fit (not psf-convolved)
+        // should we require both?
+
+        pmSource *source = sources->data[i];
+
+        // skip sources without measurements
+        if (source->extpars == NULL) continue;
+
+        // we require a PSF model fit (ignore the real crud)
+        pmModel *model = source->modelPSF;
+        if (model == NULL) continue;
+
+        // XXX I need to split the extended models from the extended aperture measurements
+        PAR = model->params->data.F32;
+        dPAR = model->dparams->data.F32;
+        xPos = PAR[PM_PAR_XPOS];
+        yPos = PAR[PM_PAR_YPOS];
+        xErr = dPAR[PM_PAR_XPOS];
+        yErr = dPAR[PM_PAR_YPOS];
 
         row = psMetadataAlloc ();
@@ -343,101 +343,101 @@
         psMetadataAdd (row, PS_LIST_TAIL, "Y_EXT_SIG",        PS_DATA_F32, "Sigma in EXT y coordinate",                  yErr);
 
-	// Petrosian measurements
-	// XXX insert header data: petrosian ref radius, flux ratio
-	if (doPetrosian) {
-	    pmSourcePetrosianValues *petrosian = source->extpars->petrosian;
-	    if (petrosian) {
-		psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG",        PS_DATA_F32, "Petrosian Magnitude",       petrosian->mag);
-		psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG_ERR",    PS_DATA_F32, "Petrosian Magnitude Error", petrosian->magErr);
-		psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS",     PS_DATA_F32, "Petrosian Radius",          petrosian->rad);
-		psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_ERR", PS_DATA_F32, "Petrosian Radius Error",    petrosian->radErr);
-	    } else {
-		psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG",        PS_DATA_F32, "Petrosian Magnitude",       NAN);
-		psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG_ERR",    PS_DATA_F32, "Petrosian Magnitude Error", NAN);
-		psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS",     PS_DATA_F32, "Petrosian Radius",          NAN);
-		psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_ERR", PS_DATA_F32, "Petrosian Radius Error",    NAN);
-	    }
-	} 
-
-	// Kron measurements
-	if (doKron) {
-	    pmSourceKronValues *kron = source->extpars->kron;
-	    if (kron) {
-		psMetadataAdd (row, PS_LIST_TAIL, "KRON_MAG",        PS_DATA_F32, "Kron Magnitude",       kron->mag);
-		psMetadataAdd (row, PS_LIST_TAIL, "KRON_MAG_ERR",    PS_DATA_F32, "Kron Magnitude Error", kron->magErr);
-		psMetadataAdd (row, PS_LIST_TAIL, "KRON_RADIUS",     PS_DATA_F32, "Kron Radius",          kron->rad);
-		psMetadataAdd (row, PS_LIST_TAIL, "KRON_RADIUS_ERR", PS_DATA_F32, "Kron Radius Error",    kron->radErr);
-	    } else {
-		psMetadataAdd (row, PS_LIST_TAIL, "KRON_MAG",        PS_DATA_F32, "Kron Magnitude",       NAN);
-		psMetadataAdd (row, PS_LIST_TAIL, "KRON_MAG_ERR",    PS_DATA_F32, "Kron Magnitude Error", NAN);
-		psMetadataAdd (row, PS_LIST_TAIL, "KRON_RADIUS",     PS_DATA_F32, "Kron Radius",          NAN);
-		psMetadataAdd (row, PS_LIST_TAIL, "KRON_RADIUS_ERR", PS_DATA_F32, "Kron Radius Error",    NAN);
-	    }
-	}
-
-	// Isophot measurements
-	// XXX insert header data: isophotal level
-	if (doIsophotal) {
-	    pmSourceIsophotalValues *isophot = source->extpars->isophot;
-	    if (isophot) {
-		psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_MAG",        PS_DATA_F32, "Isophot Magnitude",       isophot->mag);
-		psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_MAG_ERR",    PS_DATA_F32, "Isophot Magnitude Error", isophot->magErr);
-		psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_RADIUS",     PS_DATA_F32, "Isophot Radius",          isophot->rad);
-		psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_RADIUS_ERR", PS_DATA_F32, "Isophot Radius Error",    isophot->radErr);
-	    } else {
-		psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_MAG",        PS_DATA_F32, "Isophot Magnitude",       NAN);
-		psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_MAG_ERR",    PS_DATA_F32, "Isophot Magnitude Error", NAN);
-		psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_RADIUS",     PS_DATA_F32, "Isophot Radius",          NAN);
-		psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_RADIUS_ERR", PS_DATA_F32, "Isophot Radius Error",    NAN);
-	    }
-	}
-
-	// Flux Annuli
-	if (doAnnuli) {
-	    pmSourceAnnuli *annuli = source->extpars->annuli;
-	    if (annuli) {
-		psVector *fluxVal = annuli->flux;
-		psVector *fluxErr = annuli->fluxErr;
-		psVector *fluxVar = annuli->fluxVar;
-
-		for (int j = 0; j < fluxVal->n; j++) {
-		    char name[32];
-		    sprintf (name, "FLUX_VAL_R_%02d", j);
-		    psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux value in annulus", fluxVal->data.F32[j]);
-		    sprintf (name, "FLUX_ERR_R_%02d", j);
-		    psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux error in annulus", fluxErr->data.F32[j]);
-		    sprintf (name, "FLUX_VAR_R_%02d", j);
-		    psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux stdev in annulus", fluxVar->data.F32[j]);
-		} 
-	    } else {
-		for (int j = 0; j < radialBinsLower->n; j++) {
-		    char name[32];
-		    sprintf (name, "FLUX_VAL_R_%02d", j);
-		    psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux value in annulus", NAN);
-		    sprintf (name, "FLUX_ERR_R_%02d", j);
-		    psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux error in annulus", NAN);
-		    sprintf (name, "FLUX_VAR_R_%02d", j);
-		    psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux stdev in annulus", NAN);
-		} 
-	    }
-	}
-
-	psArrayAdd (table, 100, row);
-	psFree (row);
+        // Petrosian measurements
+        // XXX insert header data: petrosian ref radius, flux ratio
+        if (doPetrosian) {
+            pmSourcePetrosianValues *petrosian = source->extpars->petrosian;
+            if (petrosian) {
+                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG",        PS_DATA_F32, "Petrosian Magnitude",       petrosian->mag);
+                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG_ERR",    PS_DATA_F32, "Petrosian Magnitude Error", petrosian->magErr);
+                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS",     PS_DATA_F32, "Petrosian Radius",          petrosian->rad);
+                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_ERR", PS_DATA_F32, "Petrosian Radius Error",    petrosian->radErr);
+            } else {
+                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG",        PS_DATA_F32, "Petrosian Magnitude",       NAN);
+                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG_ERR",    PS_DATA_F32, "Petrosian Magnitude Error", NAN);
+                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS",     PS_DATA_F32, "Petrosian Radius",          NAN);
+                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_ERR", PS_DATA_F32, "Petrosian Radius Error",    NAN);
+            }
+        }
+
+        // Kron measurements
+        if (doKron) {
+            pmSourceKronValues *kron = source->extpars->kron;
+            if (kron) {
+                psMetadataAdd (row, PS_LIST_TAIL, "KRON_MAG",        PS_DATA_F32, "Kron Magnitude",       kron->mag);
+                psMetadataAdd (row, PS_LIST_TAIL, "KRON_MAG_ERR",    PS_DATA_F32, "Kron Magnitude Error", kron->magErr);
+                psMetadataAdd (row, PS_LIST_TAIL, "KRON_RADIUS",     PS_DATA_F32, "Kron Radius",          kron->rad);
+                psMetadataAdd (row, PS_LIST_TAIL, "KRON_RADIUS_ERR", PS_DATA_F32, "Kron Radius Error",    kron->radErr);
+            } else {
+                psMetadataAdd (row, PS_LIST_TAIL, "KRON_MAG",        PS_DATA_F32, "Kron Magnitude",       NAN);
+                psMetadataAdd (row, PS_LIST_TAIL, "KRON_MAG_ERR",    PS_DATA_F32, "Kron Magnitude Error", NAN);
+                psMetadataAdd (row, PS_LIST_TAIL, "KRON_RADIUS",     PS_DATA_F32, "Kron Radius",          NAN);
+                psMetadataAdd (row, PS_LIST_TAIL, "KRON_RADIUS_ERR", PS_DATA_F32, "Kron Radius Error",    NAN);
+            }
+        }
+
+        // Isophot measurements
+        // XXX insert header data: isophotal level
+        if (doIsophotal) {
+            pmSourceIsophotalValues *isophot = source->extpars->isophot;
+            if (isophot) {
+                psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_MAG",        PS_DATA_F32, "Isophot Magnitude",       isophot->mag);
+                psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_MAG_ERR",    PS_DATA_F32, "Isophot Magnitude Error", isophot->magErr);
+                psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_RADIUS",     PS_DATA_F32, "Isophot Radius",          isophot->rad);
+                psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_RADIUS_ERR", PS_DATA_F32, "Isophot Radius Error",    isophot->radErr);
+            } else {
+                psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_MAG",        PS_DATA_F32, "Isophot Magnitude",       NAN);
+                psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_MAG_ERR",    PS_DATA_F32, "Isophot Magnitude Error", NAN);
+                psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_RADIUS",     PS_DATA_F32, "Isophot Radius",          NAN);
+                psMetadataAdd (row, PS_LIST_TAIL, "ISOPHOT_RADIUS_ERR", PS_DATA_F32, "Isophot Radius Error",    NAN);
+            }
+        }
+
+        // Flux Annuli
+        if (doAnnuli) {
+            pmSourceAnnuli *annuli = source->extpars->annuli;
+            if (annuli) {
+                psVector *fluxVal = annuli->flux;
+                psVector *fluxErr = annuli->fluxErr;
+                psVector *fluxVar = annuli->fluxVar;
+
+                for (int j = 0; j < fluxVal->n; j++) {
+                    char name[32];
+                    sprintf (name, "FLUX_VAL_R_%02d", j);
+                    psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux value in annulus", fluxVal->data.F32[j]);
+                    sprintf (name, "FLUX_ERR_R_%02d", j);
+                    psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux error in annulus", fluxErr->data.F32[j]);
+                    sprintf (name, "FLUX_VAR_R_%02d", j);
+                    psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux stdev in annulus", fluxVar->data.F32[j]);
+                }
+            } else {
+                for (int j = 0; j < radialBinsLower->n; j++) {
+                    char name[32];
+                    sprintf (name, "FLUX_VAL_R_%02d", j);
+                    psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux value in annulus", NAN);
+                    sprintf (name, "FLUX_ERR_R_%02d", j);
+                    psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux error in annulus", NAN);
+                    sprintf (name, "FLUX_VAR_R_%02d", j);
+                    psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux stdev in annulus", NAN);
+                }
+            }
+        }
+
+        psArrayAdd (table, 100, row);
+        psFree (row);
     }
 
     if (table->n == 0) {
-	psFitsWriteBlank (fits, outhead, extname);
-	psFree (outhead);
-	psFree (table);
-	return true;
+        psFitsWriteBlank (fits, outhead, extname);
+        psFree (outhead);
+        psFree (table);
+        return true;
     }
 
     psTrace ("pmFPAfile", 5, "writing ext data %s\n", extname);
     if (!psFitsWriteTable (fits, outhead, table, extname)) {
-	psError(PS_ERR_IO, false, "writing ext data %s\n", extname);
-	psFree (outhead);
-	psFree(table);
-	return false;
+        psError(PS_ERR_IO, false, "writing ext data %s\n", extname);
+        psFree (outhead);
+        psFree(table);
+        return false;
     }
     psFree (outhead);
@@ -470,11 +470,11 @@
     int nParamMax = 0;
     for (int i = 0; i < sources->n; i++) {
-	pmSource *source = sources->data[i];
-	if (source->modelFits == NULL) continue;
-	for (int j = 0; j < source->modelFits->n; j++) {
-	    pmModel *model = source->modelFits->data[j];
-	    assert (model);
-	    nParamMax = PS_MAX (nParamMax, model->params->n);
-	}
+        pmSource *source = sources->data[i];
+        if (source->modelFits == NULL) continue;
+        for (int j = 0; j < source->modelFits->n; j++) {
+            pmModel *model = source->modelFits->data[j];
+            assert (model);
+            nParamMax = PS_MAX (nParamMax, model->params->n);
+        }
     }
 
@@ -484,85 +484,85 @@
     for (int i = 0; i < sources->n; i++) {
 
-	pmSource *source = sources->data[i];
-
-	// XXX if no model fits are saved, write out modelEXT?
-	if (source->modelFits == NULL) continue;
-
-	// We have multiple sources : need to flag the one used to subtract the light (the 'best' model)
-	for (int j = 0; j < source->modelFits->n; j++) {
-
-	    // choose the convolved EXT model, if available, otherwise the simple one
-	    pmModel *model = source->modelFits->data[j];
-	    assert (model);
-
-	    PAR = model->params->data.F32;
-	    dPAR = model->dparams->data.F32;
-	    xPos = PAR[PM_PAR_XPOS];
-	    yPos = PAR[PM_PAR_YPOS];
-	    xErr = dPAR[PM_PAR_XPOS];
-	    yErr = dPAR[PM_PAR_YPOS];
-
-	    axes = pmPSF_ModelToAxes (PAR, 20.0);
-
-	    row = psMetadataAlloc ();
-
-	    // XXX we are not writing out the mode (flags) or the type (psf, ext, etc)
-	    psMetadataAddU32 (row, PS_LIST_TAIL, "IPP_IDET",         0, "IPP detection identifier index",             source->seq);
-	    psMetadataAddF32 (row, PS_LIST_TAIL, "X_EXT",            0, "EXT model x coordinate",                     xPos);
-	    psMetadataAddF32 (row, PS_LIST_TAIL, "Y_EXT",            0, "EXT model y coordinate",                     yPos);
-	    psMetadataAddF32 (row, PS_LIST_TAIL, "X_EXT_SIG",        0, "Sigma in EXT x coordinate",                  xErr);
-	    psMetadataAddF32 (row, PS_LIST_TAIL, "Y_EXT_SIG",        0, "Sigma in EXT y coordinate",                  yErr);
-	    psMetadataAddF32 (row, PS_LIST_TAIL, "EXT_INST_MAG",     0, "EXT fit instrumental magnitude",             model->mag);
-	    psMetadataAddF32 (row, PS_LIST_TAIL, "EXT_INST_MAG_SIG", 0, "Sigma of PSF instrumental magnitude",        model->magErr);
-
-	    psMetadataAddF32 (row, PS_LIST_TAIL, "NPARAMS",          0, "number of model parameters",                 model->params->n);
-	    psMetadataAddStr (row, PS_LIST_TAIL, "MODEL_TYPE",       0, "name of model",                              pmModelClassGetName (model->type));
-
-	    // XXX these should be major and minor, not 'x' and 'y'
-	    psMetadataAddF32 (row, PS_LIST_TAIL, "EXT_WIDTH_MAJ",    0, "EXT width in x coordinate",                  axes.major);
-	    psMetadataAddF32 (row, PS_LIST_TAIL, "EXT_WIDTH_MIN",    0, "EXT width in y coordinate",                  axes.minor);
-	    psMetadataAddF32 (row, PS_LIST_TAIL, "EXT_THETA",        0, "EXT orientation angle",                      axes.theta);
-
-	    // write out the other generic parameters
-	    for (int k = 0; k < nParamMax; k++) {
-		if (k == PM_PAR_I0) continue;
-		if (k == PM_PAR_SKY) continue;
-		if (k == PM_PAR_XPOS) continue;
-		if (k == PM_PAR_YPOS) continue;
-		if (k == PM_PAR_SXX) continue;
-		if (k == PM_PAR_SXY) continue;
-		if (k == PM_PAR_SYY) continue;
-
-		snprintf (name, 64, "EXT_PAR_%02d", k);
-
-		if (k < model->params->n) {
-		    psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "", model->params->data.F32[k]);
-		} else {
-		    psMetadataAddF32 (row, PS_LIST_TAIL, name, PS_DATA_F32, "", NAN);
-		}
-	    }
-
-	    // XXX other parameters which may be set.
-	    // XXX flag / value to define the model
-	    // XXX write out the model type, fit status flags
-
-	    psArrayAdd (table, 100, row);
-	    psFree (row);
-	}
+        pmSource *source = sources->data[i];
+
+        // XXX if no model fits are saved, write out modelEXT?
+        if (source->modelFits == NULL) continue;
+
+        // We have multiple sources : need to flag the one used to subtract the light (the 'best' model)
+        for (int j = 0; j < source->modelFits->n; j++) {
+
+            // choose the convolved EXT model, if available, otherwise the simple one
+            pmModel *model = source->modelFits->data[j];
+            assert (model);
+
+            PAR = model->params->data.F32;
+            dPAR = model->dparams->data.F32;
+            xPos = PAR[PM_PAR_XPOS];
+            yPos = PAR[PM_PAR_YPOS];
+            xErr = dPAR[PM_PAR_XPOS];
+            yErr = dPAR[PM_PAR_YPOS];
+
+            axes = pmPSF_ModelToAxes (PAR, 20.0);
+
+            row = psMetadataAlloc ();
+
+            // XXX we are not writing out the mode (flags) or the type (psf, ext, etc)
+            psMetadataAddU32 (row, PS_LIST_TAIL, "IPP_IDET",         0, "IPP detection identifier index",             source->seq);
+            psMetadataAddF32 (row, PS_LIST_TAIL, "X_EXT",            0, "EXT model x coordinate",                     xPos);
+            psMetadataAddF32 (row, PS_LIST_TAIL, "Y_EXT",            0, "EXT model y coordinate",                     yPos);
+            psMetadataAddF32 (row, PS_LIST_TAIL, "X_EXT_SIG",        0, "Sigma in EXT x coordinate",                  xErr);
+            psMetadataAddF32 (row, PS_LIST_TAIL, "Y_EXT_SIG",        0, "Sigma in EXT y coordinate",                  yErr);
+            psMetadataAddF32 (row, PS_LIST_TAIL, "EXT_INST_MAG",     0, "EXT fit instrumental magnitude",             model->mag);
+            psMetadataAddF32 (row, PS_LIST_TAIL, "EXT_INST_MAG_SIG", 0, "Sigma of PSF instrumental magnitude",        model->magErr);
+
+            psMetadataAddF32 (row, PS_LIST_TAIL, "NPARAMS",          0, "number of model parameters",                 model->params->n);
+            psMetadataAddStr (row, PS_LIST_TAIL, "MODEL_TYPE",       0, "name of model",                              pmModelClassGetName (model->type));
+
+            // XXX these should be major and minor, not 'x' and 'y'
+            psMetadataAddF32 (row, PS_LIST_TAIL, "EXT_WIDTH_MAJ",    0, "EXT width in x coordinate",                  axes.major);
+            psMetadataAddF32 (row, PS_LIST_TAIL, "EXT_WIDTH_MIN",    0, "EXT width in y coordinate",                  axes.minor);
+            psMetadataAddF32 (row, PS_LIST_TAIL, "EXT_THETA",        0, "EXT orientation angle",                      axes.theta);
+
+            // write out the other generic parameters
+            for (int k = 0; k < nParamMax; k++) {
+                if (k == PM_PAR_I0) continue;
+                if (k == PM_PAR_SKY) continue;
+                if (k == PM_PAR_XPOS) continue;
+                if (k == PM_PAR_YPOS) continue;
+                if (k == PM_PAR_SXX) continue;
+                if (k == PM_PAR_SXY) continue;
+                if (k == PM_PAR_SYY) continue;
+
+                snprintf (name, 64, "EXT_PAR_%02d", k);
+
+                if (k < model->params->n) {
+                    psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "", model->params->data.F32[k]);
+                } else {
+                    psMetadataAddF32 (row, PS_LIST_TAIL, name, PS_DATA_F32, "", NAN);
+                }
+            }
+
+            // XXX other parameters which may be set.
+            // XXX flag / value to define the model
+            // XXX write out the model type, fit status flags
+
+            psArrayAdd (table, 100, row);
+            psFree (row);
+        }
     }
 
     if (table->n == 0) {
-	psFitsWriteBlank (fits, outhead, extname);
-	psFree (outhead);
-	psFree (table);
-	return true;
+        psFitsWriteBlank (fits, outhead, extname);
+        psFree (outhead);
+        psFree (table);
+        return true;
     }
 
     psTrace ("pmFPAfile", 5, "writing ext data %s\n", extname);
     if (!psFitsWriteTable (fits, outhead, table, extname)) {
-	psError(PS_ERR_IO, false, "writing ext data %s\n", extname);
-	psFree (outhead);
-	psFree(table);
-	return false;
+        psError(PS_ERR_IO, false, "writing ext data %s\n", extname);
+        psFree (outhead);
+        psFree(table);
+        return false;
     }
     psFree (outhead);
Index: /branches/cnb_branch_20090215/psModules/src/objects/pmSourcePhotometry.c
===================================================================
--- /branches/cnb_branch_20090215/psModules/src/objects/pmSourcePhotometry.c	(revision 21535)
+++ /branches/cnb_branch_20090215/psModules/src/objects/pmSourcePhotometry.c	(revision 21536)
@@ -3,6 +3,6 @@
  *  @author EAM, IfA; GLG, MHPCC
  *
- *  @version $Revision: 1.49 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2009-02-06 02:31:25 $
+ *  @version $Revision: 1.49.4.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-19 17:59:50 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -145,5 +145,5 @@
     // measure the contribution of included pixels
     if (mode & PM_SOURCE_PHOT_WEIGHT) {
-        pmSourcePixelWeight (&source->pixWeight, model, source->pixels, source->maskObj, maskVal);
+        pmSourcePixelWeight (&source->pixWeight, model, source->maskObj, maskVal);
     }
 
@@ -164,5 +164,5 @@
     // XXX full model or just analytical?
     // XXX use pmSourceAdd instead?
-    if (source->mode & PM_SOURCE_MODE_SUBTRACTED) {
+    if (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED) {
         pmModelAdd (source->pixels, source->maskObj, model, PM_MODEL_OP_FULL, maskVal);
     }
@@ -170,5 +170,4 @@
     // if we are measuring aperture photometry and applying the growth correction,
     // we need to shift the flux in the selected pixels (but not the mask)
-    // psImageShift ();
     psImage *flux = NULL, *mask = NULL; // Star flux and mask images, to photometer
     if (mode & PM_SOURCE_PHOT_INTERP) {
@@ -186,57 +185,4 @@
         }
 
-        // XXX this is test code to verify the shift is doing the right thing (seems to be)
-        # if (0)
-            // measure centroid of unshifted gaussian (should be 16.0,16.0)
-        {
-            psImage *image = source->pixels;
-            float xo = 0.0;
-            float yo = 0.0;
-            float xo2 = 0.0;
-            float yo2 = 0.0;
-            float no = 0.0;
-            for (int j = 0; j < image->numRows; j++)
-            {
-                for (int i = 0; i < image->numCols; i++) {
-                    xo += i*image->data.F32[j][i];
-                    yo += j*image->data.F32[j][i];
-                    xo2 += i*i*image->data.F32[j][i];
-                    yo2 += j*j*image->data.F32[j][i];
-                    no += image->data.F32[j][i];
-                }
-            }
-            xo /= no;
-            yo /= no;
-            xo2 = sqrt (xo2/no - xo*xo);
-            yo2 = sqrt (yo2/no - yo*yo);
-            fprintf (stderr, "pre-shift centroid: %f,%f, sigma: %f,%f: flux: %f\n", xo, yo, xo2, yo2, no);
-        }
-
-        // measure centroid of unshifted gaussian (should be 16.0,16.0)
-        {
-            psImage *image = flux;
-            float xo = 0.0;
-            float yo = 0.0;
-            float xo2 = 0.0;
-            float yo2 = 0.0;
-            float no = 0.0;
-            for (int j = 0; j < image->numRows; j++)
-            {
-                for (int i = 0; i < image->numCols; i++) {
-                    xo += i*image->data.F32[j][i];
-                    yo += j*image->data.F32[j][i];
-                    xo2 += i*i*image->data.F32[j][i];
-                    yo2 += j*j*image->data.F32[j][i];
-                    no += image->data.F32[j][i];
-                }
-            }
-            xo /= no;
-            yo /= no;
-            xo2 = sqrt (xo2/no - xo*xo);
-            yo2 = sqrt (yo2/no - yo*yo);
-            fprintf (stderr, "pre-shift centroid: %f,%f, sigma: %f,%f: flux: %f\n", xo, yo, xo2, yo2, no);
-        }
-        # endif
-
     } else {
         flux = source->pixels;
@@ -269,5 +215,5 @@
     // if source was originally subtracted, re-subtract object, leave local sky
     // XXX replace with pmSourceSub...
-    if (source->mode & PM_SOURCE_MODE_SUBTRACTED) {
+    if (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED) {
         pmModelSub (source->pixels, source->maskObj, model, PM_MODEL_OP_FULL, maskVal);
     }
@@ -344,8 +290,7 @@
 
 // return source aperture magnitude
-bool pmSourcePixelWeight (float *pixWeight, pmModel *model, psImage *image, psImage *mask, psImageMaskType maskVal)
+bool pmSourcePixelWeight (float *pixWeight, pmModel *model, psImage *mask, psImageMaskType maskVal)
 {
     PS_ASSERT_PTR_NON_NULL(pixWeight, false);
-    PS_ASSERT_PTR_NON_NULL(image, false);
     PS_ASSERT_PTR_NON_NULL(mask, false);
     PS_ASSERT_PTR_NON_NULL(model, false);
@@ -377,13 +322,13 @@
     Yo = params->data.F32[PM_PAR_YPOS];
 
-    dX = Xo - image->col0;
-    dP = image->numCols - dX;
+    dX = Xo - mask->col0;
+    dP = mask->numCols - dX;
     DX = PS_MAX(dX, dP);
-    NX = image->numCols;
-
-    dY = Yo - image->row0;
-    dP = image->numRows - dY;
+    NX = mask->numCols;
+
+    dY = Yo - mask->row0;
+    dP = mask->numRows - dY;
     DY = PS_MAX(dY, dP);
-    NY = image->numRows;
+    NY = mask->numRows;
 
     // measure modelSum and validSum.  this function is applied to a sources' subimage.  the
@@ -612,4 +557,5 @@
 # endif
 
+// determine chisq, etc for linear normalization-only fit
 bool pmSourceChisq (pmModel *model, psImage *image, psImage *mask, psImage *variance,
                     psImageMaskType maskVal)
@@ -632,4 +578,5 @@
         }
     }
+    model->nPix = Npix;
     model->nDOF = Npix - 1;
     model->chisq = dC;
@@ -817,2 +764,54 @@
 }
 
+// XXX this is test code to verify the shift is doing the right thing (seems to be)
+# if (0)
+// measure centroid of unshifted gaussian (should be 16.0,16.0)
+        {
+          psImage *image = source->pixels;
+          float xo = 0.0;
+          float yo = 0.0;
+          float xo2 = 0.0;
+          float yo2 = 0.0;
+          float no = 0.0;
+          for (int j = 0; j < image->numRows; j++)
+          {
+            for (int i = 0; i < image->numCols; i++) {
+              xo += i*image->data.F32[j][i];
+              yo += j*image->data.F32[j][i];
+              xo2 += i*i*image->data.F32[j][i];
+              yo2 += j*j*image->data.F32[j][i];
+              no += image->data.F32[j][i];
+            }
+          }
+          xo /= no;
+          yo /= no;
+          xo2 = sqrt (xo2/no - xo*xo);
+          yo2 = sqrt (yo2/no - yo*yo);
+          fprintf (stderr, "pre-shift centroid: %f,%f, sigma: %f,%f: flux: %f\n", xo, yo, xo2, yo2, no);
+        }
+
+// measure centroid of unshifted gaussian (should be 16.0,16.0)
+        {
+          psImage *image = flux;
+          float xo = 0.0;
+          float yo = 0.0;
+          float xo2 = 0.0;
+          float yo2 = 0.0;
+          float no = 0.0;
+          for (int j = 0; j < image->numRows; j++)
+          {
+            for (int i = 0; i < image->numCols; i++) {
+              xo += i*image->data.F32[j][i];
+              yo += j*image->data.F32[j][i];
+              xo2 += i*i*image->data.F32[j][i];
+              yo2 += j*j*image->data.F32[j][i];
+              no += image->data.F32[j][i];
+            }
+          }
+          xo /= no;
+          yo /= no;
+          xo2 = sqrt (xo2/no - xo*xo);
+          yo2 = sqrt (yo2/no - yo*yo);
+          fprintf (stderr, "pre-shift centroid: %f,%f, sigma: %f,%f: flux: %f\n", xo, yo, xo2, yo2, no);
+        }
+# endif
Index: /branches/cnb_branch_20090215/psModules/src/objects/pmSourcePhotometry.h
===================================================================
--- /branches/cnb_branch_20090215/psModules/src/objects/pmSourcePhotometry.h	(revision 21535)
+++ /branches/cnb_branch_20090215/psModules/src/objects/pmSourcePhotometry.h	(revision 21536)
@@ -4,6 +4,6 @@
  * @author EAM, IfA; GLG, MHPCC
  *
- * @version $Revision: 1.12 $ $Name: not supported by cvs2svn $
- * @date $Date: 2009-01-27 06:39:38 $
+ * @version $Revision: 1.12.8.1 $ $Name: not supported by cvs2svn $
+ * @date $Date: 2009-02-19 17:59:50 $
  * Copyright 2004 Maui High Performance Computing Center, University of Hawaii
  */
@@ -46,10 +46,10 @@
     psImage *image,                     ///< image pixels to be used
     psImage *mask,                      ///< mask of pixels to ignore
-    psImageMaskType maskVal		///< Value to mask
+    psImageMaskType maskVal             ///< Value to mask
 );
 
 bool pmSourceMagnitudesInit (psMetadata *config);
 bool pmSourceMagnitudes (pmSource *source, pmPSF *psf, pmSourcePhotometryMode mode, psImageMaskType maskVal);
-bool pmSourcePixelWeight (float *pixWeight, pmModel *model, psImage *image, psImage *mask, psImageMaskType maskVal);
+bool pmSourcePixelWeight (float *pixWeight, pmModel *model, psImage *mask, psImageMaskType maskVal);
 bool pmSourceChisq (pmModel *model, psImage *image, psImage *mask, psImage *weight, psImageMaskType maskVal);
 
Index: /branches/cnb_branch_20090215/psModules/src/objects/pmSourceVisual.c
===================================================================
--- /branches/cnb_branch_20090215/psModules/src/objects/pmSourceVisual.c	(revision 21535)
+++ /branches/cnb_branch_20090215/psModules/src/objects/pmSourceVisual.c	(revision 21536)
@@ -9,9 +9,9 @@
 # if (HAVE_KAPA)
 # include <kapa.h>
+#include "pmVisual.h"
 
 // functions used to visualize the analysis as it goes
 // these are invoked by the -visual options
 
-static bool isVisual = false;
 static int kapa1 = -1;
 // static int kapa2 = -1;
@@ -20,26 +20,21 @@
 bool pmSourcePlotPoints3D (int myKapa, Graphdata *graphdata, psVector *xn, psVector *yn, psVector *zn, float theta, float phi);
 
-bool pmSourceSetVisual (bool mode) {
-
-    isVisual = mode;
-    return true;
-}
 
 bool pmSourceVisualPSFModelResid (pmTrend2D *trend, psVector *x, psVector *y, psVector *param, psVector *mask) {
 
-    KapaSection section;  // put the positive profile in one and the residuals in another? 
+    KapaSection section;  // put the positive profile in one and the residuals in another?
 
     Graphdata graphdata;
 
-    if (!isVisual) return true;
+    if (!pmVisualIsVisual()) return true;
 
     if (kapa1 == -1) {
         kapa1 = KapaOpenNamedSocket ("kapa", "pmSource:plots");
-	if (kapa1 == -1) {
-	    fprintf (stderr, "failure to open kapa; visual mode disabled\n");
-	    isVisual = false;
-	    return false;
-	}
-    }  
+        if (kapa1 == -1) {
+            fprintf (stderr, "failure to open kapa; visual mode disabled\n");
+            pmVisualSetVisual(false);
+            return false;
+        }
+    }
 
     KapaClearPlots (kapa1);
@@ -55,11 +50,11 @@
 
     for (int i = 0; i < x->n; i++) {
-	model->data.F32[i] = pmTrend2DEval (trend, x->data.F32[i], y->data.F32[i]);
-	resid->data.F32[i] = param->data.F32[i] - model->data.F32[i];
-	if (mask->data.PS_TYPE_VECTOR_MASK_DATA[i]) continue;
-	min = PS_MIN (min, resid->data.F32[i]);
-	max = PS_MAX (max, resid->data.F32[i]);
-	Min = PS_MIN (min, param->data.F32[i]);
-	Max = PS_MAX (max, param->data.F32[i]);
+        model->data.F32[i] = pmTrend2DEval (trend, x->data.F32[i], y->data.F32[i]);
+        resid->data.F32[i] = param->data.F32[i] - model->data.F32[i];
+        if (mask->data.PS_TYPE_VECTOR_MASK_DATA[i]) continue;
+        min = PS_MIN (min, resid->data.F32[i]);
+        max = PS_MAX (max, resid->data.F32[i]);
+        Min = PS_MIN (min, param->data.F32[i]);
+        Max = PS_MAX (max, param->data.F32[i]);
     }
 
@@ -70,9 +65,9 @@
     psVector *Fn = psVectorAlloc (x->n, PS_TYPE_F32);
     for (int i = 0; i < x->n; i++) {
-	xn->data.F32[i] = x->data.F32[i] / 5000.0;
-	yn->data.F32[i] = y->data.F32[i] / 5000.0;
-	zn->data.F32[i] = (resid->data.F32[i] - min) / (max - min);
-	Zn->data.F32[i] = (param->data.F32[i] - Min) / (Max - Min);
-	Fn->data.F32[i] = (model->data.F32[i] - Min) / (Max - Min);
+        xn->data.F32[i] = x->data.F32[i] / 5000.0;
+        yn->data.F32[i] = y->data.F32[i] / 5000.0;
+        zn->data.F32[i] = (resid->data.F32[i] - min) / (max - min);
+        Zn->data.F32[i] = (param->data.F32[i] - Min) / (Max - Min);
+        Fn->data.F32[i] = (model->data.F32[i] - Min) / (Max - Min);
     }
 
@@ -155,5 +150,5 @@
     fprintf (stdout, "[c]ontinue? ");
     if (!fgets(key, 8, stdin)) {
-	psWarning("Unable to read option");
+        psWarning("Unable to read option");
     }
     return true;
@@ -173,18 +168,18 @@
 
     for (int i = 0; i < xn->n; i++) {
-	xv->data.F32[2*i+0] = +xn->data.F32[i]*cos(theta) + yn->data.F32[i]*sin(theta)*cos(phi) + zn->data.F32[i]*sin(theta)*sin(phi);
-	yv->data.F32[2*i+0] = -xn->data.F32[i]*sin(theta) + yn->data.F32[i]*cos(theta)*cos(phi) + zn->data.F32[i]*cos(theta)*sin(phi);
-	zv->data.F32[2*i+0] = -yn->data.F32[i]*sin(phi)   + zn->data.F32[i]*cos(phi);
-	xv->data.F32[2*i+1] = +xn->data.F32[i]*cos(theta) + yn->data.F32[i]*sin(theta)*cos(phi);
-	yv->data.F32[2*i+1] = -xn->data.F32[i]*sin(theta) + yn->data.F32[i]*cos(theta)*cos(phi);
-	zv->data.F32[2*i+1] = -yn->data.F32[i]*sin(phi);
-	graphdata->xmin = PS_MIN(graphdata->xmin, xv->data.F32[2*i+0]);
-	graphdata->xmax = PS_MAX(graphdata->xmax, xv->data.F32[2*i+0]);
-	graphdata->ymin = PS_MIN(graphdata->ymin, zv->data.F32[2*i+0]);
-	graphdata->ymax = PS_MAX(graphdata->ymax, zv->data.F32[2*i+0]);
-	graphdata->xmin = PS_MIN(graphdata->xmin, xv->data.F32[2*i+1]);
-	graphdata->xmax = PS_MAX(graphdata->xmax, xv->data.F32[2*i+1]);
-	graphdata->ymin = PS_MIN(graphdata->ymin, zv->data.F32[2*i+1]);
-	graphdata->ymax = PS_MAX(graphdata->ymax, zv->data.F32[2*i+1]);
+        xv->data.F32[2*i+0] = +xn->data.F32[i]*cos(theta) + yn->data.F32[i]*sin(theta)*cos(phi) + zn->data.F32[i]*sin(theta)*sin(phi);
+        yv->data.F32[2*i+0] = -xn->data.F32[i]*sin(theta) + yn->data.F32[i]*cos(theta)*cos(phi) + zn->data.F32[i]*cos(theta)*sin(phi);
+        zv->data.F32[2*i+0] = -yn->data.F32[i]*sin(phi)   + zn->data.F32[i]*cos(phi);
+        xv->data.F32[2*i+1] = +xn->data.F32[i]*cos(theta) + yn->data.F32[i]*sin(theta)*cos(phi);
+        yv->data.F32[2*i+1] = -xn->data.F32[i]*sin(theta) + yn->data.F32[i]*cos(theta)*cos(phi);
+        zv->data.F32[2*i+1] = -yn->data.F32[i]*sin(phi);
+        graphdata->xmin = PS_MIN(graphdata->xmin, xv->data.F32[2*i+0]);
+        graphdata->xmax = PS_MAX(graphdata->xmax, xv->data.F32[2*i+0]);
+        graphdata->ymin = PS_MIN(graphdata->ymin, zv->data.F32[2*i+0]);
+        graphdata->ymax = PS_MAX(graphdata->ymax, zv->data.F32[2*i+0]);
+        graphdata->xmin = PS_MIN(graphdata->xmin, xv->data.F32[2*i+1]);
+        graphdata->xmax = PS_MAX(graphdata->xmax, xv->data.F32[2*i+1]);
+        graphdata->ymin = PS_MIN(graphdata->ymin, zv->data.F32[2*i+1]);
+        graphdata->ymax = PS_MAX(graphdata->ymax, zv->data.F32[2*i+1]);
     }
     xv->n = xn->n;
Index: /branches/cnb_branch_20090215/psModules/src/objects/pmSourceVisual.h
===================================================================
--- /branches/cnb_branch_20090215/psModules/src/objects/pmSourceVisual.h	(revision 21535)
+++ /branches/cnb_branch_20090215/psModules/src/objects/pmSourceVisual.h	(revision 21536)
@@ -1,9 +1,9 @@
 /* @file  pmKapaPlots.h
- * @brief functions to make plots with the external program 'kapa' 
+ * @brief functions to make plots with the external program 'kapa'
  *
  * @author EAM, IfA
  *
- * @version $Revision: 1.1 $ $Name: not supported by cvs2svn $
- * @date $Date: 2008-11-08 01:52:34 $
+ * @version $Revision: 1.1.16.1 $ $Name: not supported by cvs2svn $
+ * @date $Date: 2009-02-19 17:59:50 $
  * Copyright 2006 Institute for Astronomy, University of Hawaii
  */
@@ -15,5 +15,4 @@
 /// @{
 
-bool pmSourceSetVisual (bool mode);
 bool pmSourceVisualPSFModelResid (pmTrend2D *trend, psVector *x, psVector *y, psVector *param, psVector *mask);
 
Index: /branches/cnb_branch_20090215/psastro/src/psastroArguments.c
===================================================================
--- /branches/cnb_branch_20090215/psastro/src/psastroArguments.c	(revision 21535)
+++ /branches/cnb_branch_20090215/psastro/src/psastroArguments.c	(revision 21536)
@@ -6,6 +6,6 @@
  *
  *  @author IfA
- *  @version $Revision: 1.34 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2009-02-09 21:25:34 $
+ *  @version $Revision: 1.34.2.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-19 17:59:50 $
  *  Copyright 2009 Institute for Astronomy, University of Hawaii
  */
@@ -100,5 +100,5 @@
     if ((N = psArgumentGet (argc, argv, "-visual"))) {
         psArgumentRemove (N, &argc, argv);
-        pmAstromSetVisual (true);
+        pmVisualSetVisual (true);
     }
 
Index: /branches/cnb_branch_20090215/psastro/src/psastroCleanup.c
===================================================================
--- /branches/cnb_branch_20090215/psastro/src/psastroCleanup.c	(revision 21535)
+++ /branches/cnb_branch_20090215/psastro/src/psastroCleanup.c	(revision 21536)
@@ -6,6 +6,6 @@
  *
  *  @author IfA
- *  @version $Revision: 1.8 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2009-02-09 21:25:34 $
+ *  @version $Revision: 1.8.2.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-19 17:59:50 $
  *  Copyright 2009 Institute for Astronomy, University of Hawaii
  */
@@ -16,5 +16,5 @@
 
     psFree (config);
-    pmAstromVisualClose ();
+    pmVisualClose ();
 
     psTimerStop ();
Index: anches/cnb_branch_20090215/psastro/src/psastroVisual.c
===================================================================
--- /branches/cnb_branch_20090215/psastro/src/psastroVisual.c	(revision 21535)
+++ 	(revision )
@@ -1,1320 +1,0 @@
-/** @file psastroVisual.c
- *
- *  @brief Diagnostic plots for psastro
- *
- *  @ingroup libpsastro
- *
- *  @author IfA
- *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2009-02-07 02:03:34 $
- *  Copyright 2009 Institute for Astronomy, University of Hawaii
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-# include "psastroInternal.h"
-# include <string.h>
-# include <stdlib.h>
-# include <stdio.h>
-
-# if (HAVE_KAPA)
-# include <kapa.h>
-
-# define KAPAX  700
-# define KAPAY  700
-
-//variables to determine when things are plotted
-static bool isVisual             = false;
-static bool plotRawStars         = true;
-static bool plotRefStars         = false;
-static bool plotLumFunc          = true;
-static bool plotRemoveClumps     = true;
-static bool plotOneChipFit       = true;
-static bool plotFixChips         = true;
-static bool plotAstromGuessCheck = true;
-static bool plotMosaicMatches    = true;
-static bool plotCommonScale      = true;
-static bool plotMosaicOneChip    = true;
-
-// variables to store plotting window indices
-static int kapa = -1;
-static int kapa2 = -1;
-
-// helper routine prototypes
-bool psastroVisualInitGraph (int kapa, KapaSection *section, Graphdata *graphdata);
-bool psastroVisualTriplePlot (int kapa, Graphdata *graphdata, psVector *xVec, psVector *yVec, psVector *zVec, bool increasing);
-bool psastroVisualScaleGraphdata(Graphdata *graphdata, psVector *xVec, psVector *yVec, bool clip);
-bool psastroVisualTripleOverplot (int kapa, Graphdata *graphdata, psVector *xVec, psVector *yVec, psVector *zVec, bool increasing);
-bool psastroVisualCreateScaleVec (psVector *zVec, psVector *zScale, bool increasing);
-bool psastroVisualResidPlot (psArray *rawstars, psArray *refstars, psArray *match, psMetadata *recipe, char *title);
-
-
-/*****************************/
-/** Initialization Routines **/
-/*****************************/
-
-/**  
- * start or stop plotting 
- */
-bool psastroSetVisual (bool mode) {
-    isVisual = mode;
-    return true;
-}
-
-
-/** 
- * open, name, and resize a window if necessary
- */
-bool psastroVisualInitWindow( int *kapid, char *name ) {
-    if (*kapid == -1) {
-        *kapid = KapaOpenNamedSocket("kapa", name);
-        if (*kapid == -1) {
-            fprintf (stderr, "failure to open kapa; visual mode disabled\n");
-            isVisual = false;
-            return false;
-        }
-        KapaResize (*kapid, KAPAX, KAPAY);
-    }
-    return true;
-}
-
-
-/** 
- * ask the user how to proceed
- */
-bool psastroVisualAskUser( bool *plotflag ) {
-    char key[10];
-    fprintf (stdout, "[c]ontinue? [s]kip the rest of these plots? [a]bort all visual plots?");
-    if (!fgets(key, 8, stdin)) {
-        psWarning("Unable to read option");
-    }
-    if (key[0] == 's') {
-        *plotflag = false;
-    }
-    if (key[0] == 'a') {
-        psastroSetVisual(false);
-        pmAstromSetVisual(false);
-    }
-    return true;
-}
-
-
-/** 
- * destroy windows at the end of a run
- */
-bool psastroVisualClose() {
-    if(kapa != -1)
-        KiiClose(kapa);
-    if (kapa2 != -1)
-        KiiClose(kapa2);
-    return true;
-}
-
-
-/***********************/
-/** Plotting Routines **/
-/***********************/
-
-
-/**
- * Plot raw stars as determined from first pass astrometry fit
- * Called within psastroAstromGeuss
- */
-bool psastroVisualPlotRawStars (psArray *rawstars, pmFPA *fpa, pmChip *chip, psMetadata *recipe)
-{
-    // make sure we want to plot this
-    if (!plotRawStars || !isVisual) return true;
-
-    //set up plot region
-    if (!psastroVisualInitWindow (&kapa, "psastro:plots"))
-        return false;
-    Graphdata graphdata;
-    KapaSection section;
-
-    KapaInitGraph (&graphdata);
-    KapaClearPlots (kapa);
-
-    graphdata.color = KapaColorByName ("black");
-    graphdata.ptype = 7;
-    graphdata.size = 0.5;
-    graphdata.style = 2;
-
-    section.dx = 0.4;
-    section.dy = 0.4;
-
-    //initialize and populate plotting vectors
-    bool status = false;
-    float iMagMin = psMetadataLookupF32 (&status, recipe, "PSASTRO.PLOT.INST.MAG.MIN");
-    float iMagMax = psMetadataLookupF32 (&status, recipe, "PSASTRO.PLOT.INST.MAG.MAX");
-
-    psVector *xVec = psVectorAlloc (rawstars->n, PS_TYPE_F32);
-    psVector *yVec = psVectorAlloc (rawstars->n, PS_TYPE_F32);
-    psVector *zVec = psVectorAlloc (rawstars->n, PS_TYPE_F32);
-
-    section.x = 0.0;
-    section.y = 0.5;
-    section.name = NULL;
-    psStringAppend (&section.name, "a0");
-    KapaSetSection (kapa, &section);
-    psFree (section.name);
-
-    //Chip coordinates
-    int n = 0;
-    for (int i = 0; i < rawstars->n; i++) {
-        pmAstromObj *raw = rawstars->data[i];
-        if (!isfinite(raw->Mag)) continue;
-        if (raw->Mag < iMagMin) continue;
-        if (raw->Mag > iMagMax) continue;
-
-        xVec->data.F32[n] = raw->chip->x;
-        yVec->data.F32[n] = raw->chip->y;
-        zVec->data.F32[n] = raw->Mag;
-        n++;
-    }
-    xVec->n = yVec->n = zVec->n = n;
-
-    KapaSendLabel(kapa, "Chip", KAPA_LABEL_XP);
-    KapaSendLabel(kapa, "X", KAPA_LABEL_XM);
-    KapaSendLabel(kapa, "Y", KAPA_LABEL_YM);
-    psastroVisualTriplePlot (kapa, &graphdata, xVec, yVec, zVec, false);
-
-    //Focal Plane Coordinates
-    section.x = 0.5;
-    section.y = 0.5;
-    section.name = NULL;
-    psStringAppend (&section.name, "a1");
-    KapaSetSection (kapa, &section);
-    psFree (section.name);
-
-    n = 0;
-    for (int i = 0; i < rawstars->n; i++) {
-        pmAstromObj *raw = rawstars->data[i];
-        if (!isfinite(raw->Mag)) continue;
-        if (raw->Mag < iMagMin) continue;
-        if (raw->Mag > iMagMax) continue;
-
-        xVec->data.F32[n] = raw->FP->x;
-        yVec->data.F32[n] = raw->FP->y;
-        zVec->data.F32[n] = raw->Mag;
-        n++;
-    }
-    xVec->n = yVec->n = zVec->n = n;
-
-    KapaSendLabel (kapa, "Focal Plane", KAPA_LABEL_XP);
-    KapaSendLabel (kapa, "L", KAPA_LABEL_XM);
-    KapaSendLabel (kapa, "M", KAPA_LABEL_YM);
-    psastroVisualTriplePlot (kapa, &graphdata, xVec, yVec, zVec, false);
-
-    // Tangent Plane Coordinates
-    section.x = 0.0;
-    section.y = 0.0;
-    section.name = NULL;
-    psStringAppend (&section.name, "a2");
-    KapaSetSection (kapa, &section);
-    psFree (section.name);
-
-    n = 0;
-    for (int i = 0; i < rawstars->n; i++) {
-        pmAstromObj *raw = rawstars->data[i];
-        if (!isfinite(raw->Mag)) continue;
-        if (raw->Mag < iMagMin) continue;
-        if (raw->Mag > iMagMax) continue;
-
-        xVec->data.F32[n] = raw->TP->x;
-        yVec->data.F32[n] = raw->TP->y;
-        zVec->data.F32[n] = raw->Mag;
-        n++;
-    }
-    xVec->n = yVec->n = zVec->n = n;
-
-    KapaSendLabel (kapa, "Tangential Plane", KAPA_LABEL_XP);
-    KapaSendLabel (kapa, "P", KAPA_LABEL_XM);
-    KapaSendLabel (kapa, "Q", KAPA_LABEL_YM);
-    psastroVisualTriplePlot (kapa, &graphdata, xVec, yVec, zVec, false);
-
-    //sky coordinates
-    section.x = 0.5;
-    section.y = 0.0;
-    section.name = NULL;
-    psStringAppend (&section.name, "a3");
-    KapaSetSection (kapa, &section);
-    psFree (section.name);
-
-    n = 0;
-    for (int i = 0; i < rawstars->n; i++) {
-        pmAstromObj *raw = rawstars->data[i];
-        if (!isfinite(raw->Mag)) continue;
-        if (raw->Mag < iMagMin) continue;
-        if (raw->Mag > iMagMax) continue;
-
-        xVec->data.F32[n] = DEG_RAD*raw->sky->r;
-        yVec->data.F32[n] = DEG_RAD*raw->sky->d;
-        zVec->data.F32[n] = raw->Mag;
-        n++;
-    }
-    xVec->n = yVec->n = zVec->n = n;
-
-    KapaSendLabel (kapa, "Sky", KAPA_LABEL_XP);
-    KapaSendLabel(kapa, "RA", KAPA_LABEL_XM);
-    KapaSendLabel(kapa, "Dec", KAPA_LABEL_YM);
-    psastroVisualTriplePlot (kapa, &graphdata, xVec, yVec, zVec, false);
-
-    // flip x (East increase to left)
-    SWAP (graphdata.xmin, graphdata.xmax);
-    KapaSetLimits (kapa, &graphdata);
-
-    // plot label
-    section.x = 0.0;
-    section.y = 0.0;
-    section.dx = .95;
-    section.dy = .95;
-    section.name = NULL;
-    psStringAppend (&section.name, "a5");
-    KapaSetSection (kapa, &section);
-    KapaSendLabel (kapa, "Raw Star Selection - Initial Astrometry", KAPA_LABEL_XP);
-    psFree (section.name);
-
-    // pause and wait for user input:
-    psastroVisualAskUser( &plotRawStars );
-
-    psFree (xVec);
-    psFree (yVec);
-    psFree (zVec);
-    return true;
-}
-
-
-/**
- * plot the location of references stars over the entire fpa
- * invoked during psastroChooseRefStars
- */
-bool psastroVisualPlotRefStars (psArray *refstars, psMetadata *recipe)
-{
-    //make sure we want to plot this
-    if (!isVisual || !plotRefStars) return true;
-
-    //set up plotting variables
-    if (!psastroVisualInitWindow (&kapa, "psastro:plots"))
-        return false;
-
-    Graphdata graphdata;
-    KapaInitGraph (&graphdata);
-    KapaClearSections (kapa);
-
-    graphdata.color = KapaColorByName ("black");
-    graphdata.ptype = 7;
-    graphdata.size = 0.5;
-    graphdata.style = 2;
-
-    //initialize and populate plot vectors
-    bool status = false;
-    float rMagMin = psMetadataLookupF32 (&status, recipe, "PSASTRO.PLOT.REF.MAG.MIN");
-    float rMagMax = psMetadataLookupF32 (&status, recipe, "PSASTRO.PLOT.REF.MAG.MAX");
-
-    psVector *xVec = psVectorAlloc (refstars->n, PS_TYPE_F32);
-    psVector *yVec = psVectorAlloc (refstars->n, PS_TYPE_F32);
-    psVector *zVec = psVectorAlloc (refstars->n, PS_TYPE_F32);
-
-    int n = 0;
-    for (int i = 0; i < refstars->n; i++) {
-        pmAstromObj *ref = refstars->data[i];
-        if (!isfinite(ref->Mag)) continue;
-        if (ref->Mag > rMagMax) continue;
-        if (ref->Mag < rMagMin) continue;
-
-        xVec->data.F32[n] = DEG_RAD*ref->sky->r;
-        yVec->data.F32[n] = DEG_RAD*ref->sky->d;
-        zVec->data.F32[n] = ref->Mag;
-        n++;
-    }
-    xVec->n = yVec->n = zVec->n = n;
-
-    KapaSendLabel (kapa, "RA", KAPA_LABEL_XM);
-    KapaSendLabel (kapa, "Dec", KAPA_LABEL_YM);
-    KapaSendLabel (kapa, "Reference Stars", KAPA_LABEL_XP);
-    psastroVisualTriplePlot(kapa, &graphdata, xVec, yVec, zVec, false);
-
-    // flip x (East increase to left)
-    SWAP (graphdata.xmin, graphdata.xmax);
-    KapaSetLimits (kapa, &graphdata);
-
-    // pause and wait for user input:
-    psastroVisualAskUser(&plotRefStars);
-
-    psFree (xVec);
-    psFree (yVec);
-    psFree (zVec);
-    return true;
-}
-
-
-/**
- * Plot the two luminosity functions created within psastroRefStarSubset
- * The luminosity functions are used to select a subset of reference stars,
- * so we plot the cutoff that defines this subset
- */
-bool psastroVisualPlotLuminosityFunction (psVector *lnMag,   ///< Log(n) for each magnitude bin
-                                          psVector *Mag,     ///< magnitude bins
-                                          pmLumFunc *lumFunc,///< Fit to the reference star luminosity function
-                                          pmLumFunc *rawFunc ///< Fit to the raw star luminoisty function
-                                          )
-{
-
-    // make sure we want to plot this
-    if ( !isVisual || !plotLumFunc ) return true;
-
-    //set up plotting variables
-    if ( !psastroVisualInitWindow (&kapa, "psastro:plots"))
-        return false;
-
-    Graphdata graphdata;
-    KapaSection section1 = {"s1", .1, .1, .85, .35};
-    KapaSection section2 =  {"s2", .1, .5, .85, .35};
-    KapaSection section;
-    if(rawFunc == NULL)
-        section = section1;
-    else
-        section = section2;
-    if (rawFunc == NULL)
-        KapaClearPlots(kapa);
-    KapaInitGraph(&graphdata);
-
-    //Determine Plot Limits
-    psastroVisualScaleGraphdata(&graphdata, Mag, lnMag, false);
-
-    //Make a line for the fit
-    float x[2] = {graphdata.xmin, graphdata.xmax};
-    float y[2] = {lumFunc->offset + x[0] * lumFunc->slope,
-                 lumFunc->offset + x[1] * lumFunc->slope};
-
-    //Plot Data
-    KapaSetSection(kapa, &section);
-    KapaSetLimits(kapa, &graphdata);
-
-    KapaSetFont (kapa, "helvetica", 14);
-    KapaBox (kapa, &graphdata);
-    KapaSendLabel (kapa, "Magnitude", KAPA_LABEL_XM);
-    KapaSendLabel (kapa, "Log(N)", KAPA_LABEL_YM);
-    if (rawFunc == NULL)
-        KapaSendLabel (kapa, "Raw Star Luminosity Function", KAPA_LABEL_XP);
-    else
-        KapaSendLabel (kapa,
-                       "Reference Star Luminosity Function, Shifted Raw Fit, and Cutoff",
-                       KAPA_LABEL_XP);
-    graphdata.color=KapaColorByName("black");
-    graphdata.style = 1;
-    KapaPrepPlot (kapa, lnMag->n, &graphdata);
-    KapaPlotVector(kapa, lnMag->n,   Mag->data.F32, "x");
-    KapaPlotVector(kapa, lnMag->n, lnMag->data.F32, "y");
-
-    //Overplot fit
-    graphdata.style=0;
-    KapaPrepPlot(kapa,2,&graphdata);
-    KapaPlotVector(kapa, 2, x, "x");
-    KapaPlotVector(kapa, 2, y, "y");
-
-    //If rawFunc was supplied, overplot the raw star fit + cutoff
-    if( rawFunc != NULL) {
-        double mRef = 0.5*(lumFunc->mMin + lumFunc->mMax);
-        double logRho = mRef * lumFunc->slope + lumFunc->offset;
-        double mRaw = (logRho - rawFunc->offset) / rawFunc->slope;
-        double deltaM = mRef - mRaw;
-        double mRefMax = rawFunc->mMax + deltaM;
-
-        float xraw[2] = {rawFunc->mMin + deltaM, rawFunc->mMax + deltaM};
-        float yraw[2] = {rawFunc->offset + (rawFunc->slope) * rawFunc->mMin,
-                        rawFunc->offset + (rawFunc->slope) * rawFunc->mMax};
-        float x[2] = {mRefMax, mRefMax};
-        float y[2] = {graphdata.ymin, graphdata.ymax};
-        graphdata.color= KapaColorByName("red");
-        KapaPrepPlot(kapa, 2, &graphdata);
-        KapaPlotVector(kapa, 2, x, "x");
-        KapaPlotVector(kapa, 2, y, "y");
-        KapaPrepPlot (kapa, 2, &graphdata);
-        KapaPlotVector (kapa, 2, xraw, "x");
-        KapaPlotVector (kapa, 2, yraw, "y");
-
-        // pause and wait for user input:
-        psastroVisualAskUser (&plotLumFunc);
-    }
-    return true;
-} // end of psastroVisualPlotLuminosityFunction
-
-
-/**
- * Plot the stars in a region, and indicate which stars are part of 'clumps'
- * These stars are flagged during astrometric fitting, since dense regions are
- * harder to cross-match than sparse ones. Called during psastroRemoveClumps.
- */
-bool psastroVisualPlotRemoveClumps (psArray *input, ///< Array containing the field stars
-                                    psImage *count, ///< A 2D histogram of the field star distribution
-                                    int scale,      ///< The pixel size of the histogram
-                                    float limit     ///< The minimum numuber of stars in a bin flagged as a clump
-                                    )
-{
-
-    //make sure we want to plot this
-    if (!isVisual || !plotRemoveClumps) return true;
-
-    //set up plot variables
-    if ( !psastroVisualInitWindow (&kapa, "psastro:plots")) return false;
-
-    KapaSection section;
-    Graphdata graphdata;
-    section.x = 0;
-    section.dx = .9;
-    section.y = 0;
-    section.dy = .9;
-    section.name = NULL;
-    psStringAppend( &section.name, "a0");
-    KapaInitGraph(&graphdata);
-    KapaSetSection(kapa, &section);
-    psFree(section.name);
-
-    graphdata.ptype = 7;
-    graphdata.size = 0.5;
-    graphdata.style = 2;
-    graphdata.color = KapaColorByName ("black");
-    KapaClearPlots(kapa);
-
-    //set up plot vectors
-    float Xmin = +FLT_MAX;
-    float Xmax = -FLT_MAX;
-    float Ymin = +FLT_MAX;
-    float Ymax = -FLT_MAX;
-    psVector *xVec = psVectorAlloc (input->n, PS_TYPE_F32);
-    psVector *yVec = psVectorAlloc (input->n, PS_TYPE_F32);
-
-    //determine boundaries for histogram bin calculation
-    int n = 0;
-    for (int i=0; i< input->n; i++) {
-        pmAstromObj *obj = (pmAstromObj *)input->data[i];
-        if (!isfinite(obj->FP->x)) continue;
-        if (!isfinite(obj->FP->y)) continue;
-        xVec->data.F32[n] = obj->FP->x;
-        yVec->data.F32[n] = obj->FP->y;
-        Xmin = PS_MIN (Xmin, xVec->data.F32[n]);
-        Xmax = PS_MAX (Xmax, xVec->data.F32[n]);
-        Ymin = PS_MIN (Ymin, yVec->data.F32[n]);
-        Ymax = PS_MAX (Ymax, yVec->data.F32[n]);
-        n++;
-    }
-    xVec->n = yVec->n = n;
-
-    //plot stars
-    graphdata.xmax = Xmax;
-    graphdata.xmin = Xmin;
-    graphdata.ymax = Ymax;
-    graphdata.ymin = Ymin;
-    KapaSetLimits (kapa, &graphdata);
-    KapaSetFont (kapa, "helvetica", 14);
-
-    KapaBox (kapa, &graphdata);
-
-    KapaSendLabel (kapa, "L (pixels)", KAPA_LABEL_XM);
-    KapaSendLabel (kapa, "M (pixels)", KAPA_LABEL_YM);
-    KapaSendLabel (kapa, "Regions Flagged as Clumps (Red Boxes)",
-                   KAPA_LABEL_XP);
-
-    KapaPrepPlot (kapa, xVec->n, &graphdata);
-    KapaPlotVector (kapa, xVec->n, xVec->data.F32, "x");
-    KapaPlotVector (kapa, yVec->n, yVec->data.F32, "y");
-
-    graphdata.color = KapaColorByName ("red");
-    graphdata.style = 1;
-
-    //overplot clumpy regions excluded from analysis
-    for(int i = 0; i < count->numCols; i++) {
-        for (int j = 0; j < count->numRows; j++) {
-            if(count->data.U32[j][i] <= limit) continue; //not a clump
-            float Xbot = (i - 5) * scale + Xmin;
-            float Ybot = (j - 5) * scale + Ymin;
-            if(Xbot < graphdata.xmin || Xbot > graphdata.xmax ||
-               Ybot < graphdata.ymin || Ybot > graphdata.ymax) continue;
-            float x[5] = {Xbot, Xbot + scale, Xbot + scale, Xbot, Xbot};
-            float y[5] = {Ybot, Ybot, Ybot + scale, Ybot + scale, Ybot};
-            KapaPrepPlot (kapa, 5, &graphdata);
-            KapaPlotVector (kapa, 5, x, "x");
-            KapaPlotVector (kapa, 5, y, "y");
-        }
-    }
-
-    //ask for user input and finish
-    psastroVisualAskUser (&plotRemoveClumps);
-    psFree (xVec);
-    psFree (yVec);
-
-    return true;
-}
-
-
-/**
- * Assess the goodness of fit for a signle chip by
- * plotting the fit residuals
- * invoked during psastroOneChipFit
- */
-bool psastroVisualPlotOneChipFit (psArray *rawstars, ///< stars detected in the image
-                                  psArray *refstars, ///< reference stars over the same region
-                                  psArray *match,    ///< contains which rawstars match to which refstars
-                                  psMetadata *recipe ///< data reduction recipe
-                                  )
-{
-
-    //make sure we want to plot this
-    if (!isVisual || !plotOneChipFit)
-        return true;
-
-    //plot the residuals
-    if (!psastroVisualResidPlot(rawstars, refstars, match, recipe, "Single Chip Fit Residuals (Chip Coordinates)"))
-        return false;
-
-    //ask for user input and finish
-    psastroVisualAskUser(&plotOneChipFit);
-    return true;
-}
-
-
-/**
- * Plots the chip corners in the FP before and after chips with inconsistent solutions have been fixed.
- * Invoked during psastroFixChips
- */
-bool psastroVisualPlotFixChips (pmFPAfile *input, ///< focal plane array file
-                                psVector *xOld, ///< old X location of chip cornerss
-                                psVector *yOld ///< old Y location of chip corners
-                                )
-{
-    //make sure we want to plot this
-    if(!isVisual || !plotFixChips) return true;
-
-    if(!psastroVisualInitWindow(&kapa, "psastro:plots")) return false;
-
-    KapaSection section = {"s1", .05, .05, .9, .9};
-    Graphdata graphdata;
-    KapaInitGraph( &graphdata);
-    KapaClearPlots (kapa);
-    graphdata.ptype = 2;
-    graphdata.style = 2;
-
-    psVector *xNew = psVectorAllocEmpty (xOld->n, PS_TYPE_F32);
-    psVector *yNew = psVectorAllocEmpty (yOld->n, PS_TYPE_F32);
-
-    // copy of the code in psastroFixChips that generated xOld, yOld, but for xNew, yNew
-    pmFPAview *view = pmFPAviewAlloc (0);
-
-    pmChip *obsChip = NULL;
-    while ((obsChip = pmFPAviewNextChip (view, input->fpa, 1)) != NULL) {
-        if (!obsChip->process || !obsChip->file_exists || !obsChip->data_exists) { continue; }
-
-        psRegion *region = pmChipPixels (obsChip);
-        psPlane ptCP, ptFP;
-
-        ptCP.x = region->x0; ptCP.y = region->y0;
-        psPlaneTransformApply (&ptFP, obsChip->toFPA, &ptCP);
-	psVectorAppend (xNew, ptFP.x);
-	psVectorAppend (yNew, ptFP.y);
-
-        ptCP.x = region->x0; ptCP.y = region->y1;
-        psPlaneTransformApply (&ptFP, obsChip->toFPA, &ptCP);
-	psVectorAppend (xNew, ptFP.x);
-	psVectorAppend (yNew, ptFP.y);
-
-        ptCP.x = region->x1; ptCP.y = region->y1;
-        psPlaneTransformApply (&ptFP, obsChip->toFPA, &ptCP);
-	psVectorAppend (xNew, ptFP.x);
-	psVectorAppend (yNew, ptFP.y);
-
-        ptCP.x = region->x1; ptCP.y = region->y0;
-        psPlaneTransformApply (&ptFP, obsChip->toFPA, &ptCP);
-	psVectorAppend (xNew, ptFP.x);
-	psVectorAppend (yNew, ptFP.y);
-
-        psFree (region);
-    }
-
-    //set up graph
-    psastroVisualScaleGraphdata(&graphdata, xOld, yOld, true);
-    psastroVisualInitGraph(kapa, &section, &graphdata);
-    KapaSendLabel (kapa, "L (FP)", KAPA_LABEL_XM);
-    KapaSendLabel (kapa, "M (FP)", KAPA_LABEL_YM);
-    KapaSendLabel (kapa, "Chip corners before (black) and after (red) FixChips", KAPA_LABEL_XP);
-    KapaPrepPlot (kapa, xOld->n, &graphdata);
-    KapaPlotVector (kapa, xOld->n, xOld->data.F32, "x");
-    KapaPlotVector (kapa, xOld->n, yOld->data.F32, "y");
-
-    graphdata.ptype = 1;
-    graphdata.color = KapaColorByName("red");
-    KapaPrepPlot (kapa, xNew->n, &graphdata);
-    KapaPlotVector (kapa, xNew->n, xNew->data.F32, "x");
-    KapaPlotVector (kapa, xNew->n, yNew->data.F32, "y");
-
-    psastroVisualAskUser(&plotFixChips);
-    psFree(xNew);
-    psFree(yNew);
-    psFree(view);
-    return true;
-}
-
-
-/**
- *  Plots the fpa chip corners projected on to the tangential plane before and after
- *  the astrometry solution has been applied. In psastroAstromGuessCheck, the old corners
- *  are then fit to the new corners to get a sense at how far off the initial WCS info was
- *  in offset, rotation, and scale. This procedure also plots the residuals of the fit from
- *  old to new coordinates
- */
-bool psastroVisualPlotAstromGuessCheck (psVector *cornerPo, ///< P coordinates of chip corners before fitting
-                                        psVector *cornerQo, ///< Q coordinates of chip corners before fitting
-                                        psVector *cornerPn, ///< P coordinates of chip corners after fitting
-                                        psVector *cornerQn, ///< Q coordinates of chip corners after fitting
-                                        psVector *cornerPd, ///< P coordinate residuals of fit from old to new coordinates
-                                        psVector *cornerQd  ///< Q coordinate residuals of fit from old to new coordinates
-                                        )
-{
-
-    //make sure we want to plot this
-    if (!isVisual || !plotAstromGuessCheck) return true;
-
-    //set up graph window
-    if ( !psastroVisualInitWindow (&kapa, "psastro:plots"))
-        return false;
-    Graphdata graphdata;
-    KapaSection section;
-    KapaInitGraph(&graphdata);
-    KapaClearPlots (kapa);
-
-    graphdata.color = KapaColorByName ("black");
-    graphdata.ptype = 2;
-    graphdata.size = 0.5;
-    graphdata.style = 2;
-
-    section.dx = 0.4;
-    section.dy = 0.4;
-
-    //Old Corners
-    section.x = 0.30;
-    section.y = 0.50;
-    section.name = NULL;
-    psStringAppend (&section.name, "a0");
-    KapaSetSection (kapa, &section);
-    psFree(section.name);
-
-    psastroVisualScaleGraphdata (&graphdata, cornerPo, cornerPo, true);
-    KapaSetLimits (kapa, &graphdata);
-    KapaBox (kapa, &graphdata);
-    KapaSendLabel (kapa, "P (Pixels)", KAPA_LABEL_XM);
-    KapaSendLabel (kapa, "Q (Pixels)", KAPA_LABEL_YM);
-    KapaSendLabel (kapa,
-                   "Fiducial Points in the Tangent Plane. Black: Initial Astrometry. Red: Final Astrometry",
-                   KAPA_LABEL_XP);
-    KapaPrepPlot (kapa, cornerPo->n, &graphdata);
-    KapaPlotVector (kapa, cornerPo->n, cornerPo->data.F32, "x");
-    KapaPlotVector (kapa, cornerQo->n, cornerQo->data.F32, "y");
-
-    // New Corners
-    graphdata.color = KapaColorByName("red");
-    graphdata.ptype = 7;
-    graphdata.size = 1.5;
-    KapaPrepPlot (kapa, cornerPn->n, &graphdata);
-    KapaPlotVector (kapa, cornerPn->n, cornerPn->data.F32, "x");
-    KapaPlotVector (kapa, cornerQn->n, cornerQn->data.F32, "y");
-
-    // Residuals
-    psVector *xResid = psVectorAlloc(cornerPn->n, PS_DATA_F32);
-    psVector *yResid = psVectorAlloc(cornerQn->n, PS_DATA_F32);
-    for(int i=0; i < cornerPn->n; i++) {
-        xResid->data.F32[i] = (cornerPd->data.F32[i]);
-        yResid->data.F32[i] = (cornerQd->data.F32[i]);
-    }
-
-    graphdata.color = KapaColorByName("black");
-    graphdata.size=0.5;
-    section.x = 0.3;
-    section.y = 0.0;
-    section.name = NULL;
-    psStringAppend (&section.name, "a1");
-    KapaSetSection (kapa, &section);
-    psFree(section.name);
-
-    psastroVisualScaleGraphdata (&graphdata, xResid, yResid, true);
-    KapaSetLimits (kapa, &graphdata);
-    KapaBox (kapa, &graphdata);
-    KapaSendLabel (kapa, "dP", KAPA_LABEL_XM);
-    KapaSendLabel (kapa, "dQ", KAPA_LABEL_YM);
-    KapaSendLabel (kapa,
-                   "Residual of the Fit from the Initial Astrometry to the Final Astrometry",
-                   KAPA_LABEL_XP);
-    KapaPrepPlot (kapa, cornerPd->n, &graphdata);
-    KapaPlotVector (kapa, cornerPd->n, xResid->data.F32, "x");
-    KapaPlotVector (kapa, cornerQd->n, yResid->data.F32, "y");
-
-    psFree(xResid);
-    psFree(yResid);
-    psastroVisualAskUser (&plotAstromGuessCheck);
-    return true;
-}
-
-
-/**
- * Plots the pixel scales of the fpa before they are
- * equalized in psastroMosaicCommonScale
- */
-bool psastroVisualPlotCommonScale (pmFPA *fpa,         ///< the fpa
-                                   psVector *oldScale  ///< the old pixel scale of each chip in the fpa
-                                   )
-{
-    //make sure we want to plot this
-    if (!isVisual || !plotCommonScale) return false;
-
-    if (!psastroVisualInitWindow(&kapa, "psastro:plots")) return false;
-
-    KapaSection section = {"s1", .05, .05, .9, .9};
-    Graphdata graphdata;
-    psPlane ptCH, ptFP;
-    ptCH.x = 0;
-    ptCH.y = 0;
-    psVector *xVec = psVectorAlloc (oldScale->n, PS_TYPE_F32);
-    psVector *yVec = psVectorAlloc (oldScale->n, PS_TYPE_F32);
-
-    int nobj = 0;
-
-    //project each chip corner to the Focal Plane
-    for(int i = 0; i < fpa->chips->n; i++) {
-        pmChip *chip = fpa->chips->data[i];
-        if (!chip->process || !chip->file_exists) { continue; }
-        if (!chip->toFPA) { continue; }
-
-        psPlaneTransformApply (&ptFP, chip->toFPA, &ptCH);
-        xVec->data.F32[nobj] = ptFP.x;
-        yVec->data.F32[nobj] = ptFP.y;
-        nobj++;
-    }
-
-    //set up plot window
-    KapaInitGraph (&graphdata);
-    KapaClearPlots (kapa);
-    KapaSetSection (kapa, &section);
-    KapaSetFont (kapa, "helvetica", 14);
-    psastroVisualTriplePlot (kapa, &graphdata, xVec, yVec, oldScale, false);
-    KapaSendLabel (kapa, "L (FP)", KAPA_LABEL_XM);
-    KapaSendLabel (kapa, "M (FP)", KAPA_LABEL_YM);
-    KapaSendLabel (kapa, "Old Pixel Scale of FPA Chips (Not to Scale)", KAPA_LABEL_XP);
-
-    psastroVisualAskUser (&plotCommonScale);
-    return true;
-}
-
-
-/**
- *   plot the residuals between raw stars and ref stars after
- *   fitting in psastroMosaicOneChip
- */
-bool psastroVisualPlotMosaicOneChip (psArray *rawstars, psArray *refstars,
-                                     psArray *match, psMetadata *recipe)
-{
-
-    //make sure we want to plot this
-    if (!isVisual || !plotMosaicOneChip) return false;
-
-    //plot the residuals
-    if (!psastroVisualResidPlot(rawstars, refstars, match, recipe, "Single Chip Fit Residuals - Mosaic Mode"))
-        return false;
-
-    //ask for user input and finish
-    psastroVisualAskUser(&plotMosaicOneChip);
-
-    return true;
-}
-
-/** psastroVisualPlotMosaicMatches
- * Plot the matches between raw and reference stars during psastroVisualMosaicSetMatch
- */
-bool psastroVisualPlotMosaicMatches( psArray *rawstars, psArray *refstars,
-                                    psArray *match, int iteration,
-                                    psMetadata *recipe)
-{
-    //make sure we want to plot this
-    if (!isVisual || !plotMosaicMatches) return true;
-
-    char title[60];
-    sprintf(title, "Matches found during psastroMosaicSetMatch iteration %d", iteration);
-
-    if (!psastroVisualResidPlot(rawstars, refstars, match, recipe, title))
-        return false;
-
-    //ask for user input
-    psastroVisualAskUser (&plotMosaicMatches);
-    return true;
-}
-
-
-/*********************/
-/** Helper Routines **/
-/*********************/
-
-
-/** psastroVisualInitGraph (kapa, *section, *graphdata)
- * Initializes graph, sets the section, sets the font,
- * sets the limits, draws the box
- */
-bool psastroVisualInitGraph (int kapa, KapaSection *section, Graphdata *graphdata)
-{
-    KapaSetSection (kapa, section);
-    KapaSetFont (kapa, "helvetica", 14);
-    KapaSetLimits (kapa, graphdata);
-    KapaBox (kapa, graphdata);
-    return true;
-}
-
-
-/** psastroVisualTriplePlot
- * plot 2 vectors whose point sizes are scaled by a third vector
- * autoscales the plot
- */
-bool psastroVisualTriplePlot (int kapid, Graphdata *graphdata, psVector *xVec, psVector *yVec, psVector *zVec, bool increasing)
-{
-    psastroVisualScaleGraphdata (graphdata, xVec, yVec, true);
-    //printf("%f %f %f %f \n",graphdata->xmin, graphdata->xmax, graphdata->ymin, graphdata->ymax);
-    // set the scale vector
-    psVector *zScale = psVectorAlloc (zVec->n, PS_DATA_F32);
-    psastroVisualCreateScaleVec (zVec, zScale, increasing);
-
-    KapaSetFont (kapid, "helvetica", 14);
-    KapaSetLimits(kapid, graphdata);
-    KapaBox (kapid, graphdata);
-
-    // the point size will be scaled from the z vector
-    graphdata->ptype = 7;
-    graphdata->style = 2;
-    graphdata->size = -1;
-    KapaPrepPlot (kapid, xVec->n, graphdata);
-    KapaPlotVector (kapid, xVec->n, xVec->data.F32, "x");
-    KapaPlotVector (kapid, yVec->n, yVec->data.F32, "y");
-    KapaPlotVector (kapid, zVec->n, zScale->data.F32, "z");
-    psFree (zScale);
-    return true;
-}
-
-
-/** psastroVisualTripleOverplot
- * same as above, but does not rescale the plot or redraw the bounding box
- */
-bool psastroVisualTripleOverplot (int kapid, Graphdata *graphdata, psVector *xVec, psVector *yVec, psVector *zVec, bool increasing) {
-
-    // set the scale vector
-    psVector *zScale = psVectorAlloc (zVec->n, PS_DATA_F32);
-    psastroVisualCreateScaleVec (zVec, zScale, increasing);
-
-    KapaSetFont (kapid, "helvetica", 14);
-
-    // the point size will be scaled from the z vector
-    graphdata->size = -1;
-    KapaPrepPlot (kapid, xVec->n, graphdata);
-    KapaPlotVector (kapid, xVec->n, xVec->data.F32, "x");
-    KapaPlotVector (kapid, yVec->n, yVec->data.F32, "y");
-    KapaPlotVector (kapid, zVec->n, zScale->data.F32, "z");
-    psFree (zScale);
-    return true;
-}
-
-
-/** psastroVisualCreateScaleVec
- * create a vector of plot point sizes from a vector
- */
-bool psastroVisualCreateScaleVec (psVector *zVec, psVector *zScale, bool increasing) {
-    // set limits based on data values
-    float zmin = +FLT_MAX;
-    float zmax = -FLT_MAX;
-
-    for (int i = 0; i < zVec->n; i++) {
-        zmin = PS_MIN (zmin, zVec->data.F32[i]);
-        zmax = PS_MAX (zmax, zVec->data.F32[i]);
-    }
-
-    float range = zmax - zmin;
-    if (range == 0.0) {
-        psVectorInit (zScale, 1.0);
-    } else {
-        for (int i = 0; i < zVec->n; i++) {
-            if (increasing) {
-                zScale->data.F32[i] = PS_MIN (1.5, PS_MAX(0.05, 1.5*(zVec->data.F32[i] - zmin)/range));
-            } else {
-                zScale->data.F32[i] = PS_MIN (1.5, PS_MAX(0.05, 1.5*(zmax - zVec->data.F32[i])/range));
-            }
-        }
-    }
-    return true;
-}
-
-
-/** psastroVisualScaleGraphdata
- * Scale the graphdata structure based on x and y coordinates. Use sigma clipping to
- * prevent outliers from making te plot region too big.
- */
-bool psastroVisualScaleGraphdata(Graphdata *graphdata, psVector *xVec, psVector *yVec, bool clip) {
-
-    graphdata->xmin = +FLT_MAX;
-    graphdata->xmax = -FLT_MAX;
-    graphdata->ymin = +FLT_MAX;
-    graphdata->ymax = -FLT_MAX;
-
-    //determine standard deviation of xVec and yVec
-    psStats *statsX = psStatsAlloc(PS_STAT_SAMPLE_MEDIAN | PS_STAT_SAMPLE_STDEV);
-    psStats *statsY = psStatsAlloc(PS_STAT_SAMPLE_MEDIAN | PS_STAT_SAMPLE_STDEV);
-    psVectorStats (statsX, xVec, NULL, NULL, 0);
-    psVectorStats (statsY, yVec, NULL, NULL, 0);
-
-    float xhi = +FLT_MAX, xlo = -FLT_MAX, yhi = +FLT_MAX, ylo = -FLT_MAX;
-    if (clip) {
-        xhi  = statsX->sampleMedian + 3 *statsX->sampleStdev;
-        xlo = statsX->sampleMedian - 3 *statsX->sampleStdev;
-        yhi = statsY->sampleMedian + 3 *statsY->sampleStdev;
-        ylo = statsY->sampleMedian - 3 *statsY->sampleStdev;
-    }
-
-    // abort if there is no good data
-    if (!isfinite(xhi) || !isfinite(xlo) || !isfinite(yhi) || !isfinite(ylo)) {
-        graphdata->xmin = -1;
-        graphdata->ymin  = -1;
-        graphdata->xmax = 1;
-        graphdata->ymax = 1;
-        psFree(statsX);
-        psFree(statsY);
-        return false;
-    }
-
-    for(int i = 0; i < xVec->n; i++) {
-        if (!isfinite(xVec->data.F32[i])) continue;
-        if (xVec->data.F32[i] > xhi || xVec->data.F32[i] < xlo) continue;
-        graphdata->xmin = PS_MIN (graphdata->xmin, xVec->data.F32[i]);
-        graphdata->xmax = PS_MAX (graphdata->xmax, xVec->data.F32[i]);
-    }
-
-    for (int i = 0; i < yVec->n; i++) {
-        if (!isfinite(xVec->data.F32[i])) continue;
-        if (yVec->data.F32[i] > yhi || yVec->data.F32[i] < ylo) continue;
-        graphdata->ymin = PS_MIN (graphdata->ymin, yVec->data.F32[i]);
-        graphdata->ymax = PS_MAX (graphdata->ymax, yVec->data.F32[i]);
-    }
-
-    // add a whitespace border
-    float range = graphdata->xmax - graphdata->xmin;
-    if (range == 0) range = 1;
-    graphdata->xmin -= .05 * range;
-    graphdata->xmax += .05 * range;
-
-    range = graphdata->ymax - graphdata->ymin;
-    if (range == 0) range = 1;
-    graphdata->ymin -= .05 * range;
-    graphdata->ymax += .05 * range;
-
-    psFree (statsX);
-    psFree (statsY);
-    return true;
-}
-
-
-/** psastroVisualResdiPlot
- * Plots the residuals between matched raw and reference stars. Used to assess the quality of an
- * astrometry solution
- */
-bool psastroVisualResidPlot (psArray *rawstars, psArray *refstars, psArray *match, psMetadata *recipe, char *title) {
-
-    //set up the first window
-    if (!psastroVisualInitWindow( &kapa, "psastro:plots")) return false;
-
-    //initialize graph information
-    Graphdata graphdata;
-    KapaSection section;
-
-    KapaInitGraph (&graphdata);
-    KapaClearPlots (kapa);
-
-    graphdata.color = KapaColorByName ("black");
-    graphdata.ptype = 7;
-    graphdata.size = 0.5;
-    graphdata.style = 2;
-
-    section.dx = 0.4;
-    section.dy = 0.4;
-
-    //initialize and populate the plotting vectors
-    bool status = false;
-    float iMagMin = psMetadataLookupF32 (&status, recipe, "PSASTRO.PLOT.INST.MAG.MIN");
-    float iMagMax = psMetadataLookupF32 (&status, recipe, "PSASTRO.PLOT.INST.MAG.MAX");
-    float rMagMin = psMetadataLookupF32 (&status, recipe, "PSASTRO.PLOT.REF.MAG.MIN");
-    float rMagMax = psMetadataLookupF32 (&status, recipe, "PSASTRO.PLOT.REF.MAG.MAX");
-
-    psVector *xVec = psVectorAlloc (match->n, PS_TYPE_F32);
-    psVector *yVec = psVectorAlloc (match->n, PS_TYPE_F32);
-    psVector *zVec = psVectorAlloc (match->n, PS_TYPE_F32);
-
-    // X vs dX
-    section.x = 0.0;
-    section.y = 0.5;
-    section.name = NULL;
-    psStringAppend (&section.name, "a0");
-    KapaSetSection (kapa, &section);
-    psFree (section.name);
-
-    int n = 0;
-    for (int i = 0; i < match->n; i++) {
-        pmAstromMatch *pair = match->data[i];
-        pmAstromObj *raw = rawstars->data[pair->raw];
-        pmAstromObj *ref = refstars->data[pair->ref];
-
-        if (!isfinite(raw->Mag)) continue;
-        if (raw->Mag < iMagMin) continue;
-        if (raw->Mag > iMagMax) continue;
-        if (ref->Mag < rMagMin) continue;
-        if (ref->Mag > rMagMax) continue;
-
-        xVec->data.F32[n] = raw->chip->x;
-        yVec->data.F32[n] = raw->chip->x - ref->chip->x;
-        zVec->data.F32[n] = raw->Mag;
-        n++;
-    }
-    xVec->n = yVec->n = zVec->n = n;
-
-    KapaSendLabel (kapa, "X", KAPA_LABEL_XM);
-    KapaSendLabel (kapa, "dX", KAPA_LABEL_YM);
-    psastroVisualTriplePlot (kapa, &graphdata, xVec, yVec, zVec, false);
-
-    // X vs dY
-    section.x = 0.5;
-    section.y = 0.5;
-    section.name = NULL;
-    psStringAppend (&section.name, "a1");
-    KapaSetSection (kapa, &section);
-    psFree (section.name);
-
-    n = 0;
-    for (int i = 0; i < match->n; i++) {
-        pmAstromMatch *pair = match->data[i];
-        pmAstromObj *raw = rawstars->data[pair->raw];
-        pmAstromObj *ref = refstars->data[pair->ref];
-
-        if (!isfinite(raw->Mag)) continue;
-        if (raw->Mag < iMagMin) continue;
-        if (raw->Mag > iMagMax) continue;
-        if (ref->Mag < rMagMin) continue;
-        if (ref->Mag > rMagMax) continue;
-
-        xVec->data.F32[n] = raw->chip->x;
-        yVec->data.F32[n] = raw->chip->y - ref->chip->y;
-        zVec->data.F32[n] = raw->Mag;
-        n++;
-    }
-    xVec->n = yVec->n = zVec->n = n;
-
-    KapaSendLabel (kapa, "X", KAPA_LABEL_XM);
-    KapaSendLabel (kapa, "dY", KAPA_LABEL_YM);
-    psastroVisualTriplePlot (kapa, &graphdata, xVec, yVec, zVec, false);
-
-    // Y vs dX
-    section.x = 0.0;
-    section.y = 0.0;
-    section.name = NULL;
-    psStringAppend (&section.name, "a2");
-    KapaSetSection (kapa, &section);
-    psFree (section.name);
-
-    n = 0;
-    for (int i = 0; i < match->n; i++) {
-        pmAstromMatch *pair = match->data[i];
-        pmAstromObj *raw = rawstars->data[pair->raw];
-        pmAstromObj *ref = refstars->data[pair->ref];
-
-        if (!isfinite(raw->Mag)) continue;
-        if (raw->Mag < iMagMin) continue;
-        if (raw->Mag > iMagMax) continue;
-        if (ref->Mag < rMagMin) continue;
-        if (ref->Mag > rMagMax) continue;
-
-        xVec->data.F32[n] = raw->chip->y;
-        yVec->data.F32[n] = raw->chip->x - ref->chip->x;
-        zVec->data.F32[n] = raw->Mag;
-        n++;
-    }
-    xVec->n = yVec->n = zVec->n = n;
-
-    KapaSendLabel (kapa, "Y", KAPA_LABEL_XM);
-    KapaSendLabel (kapa, "dX", KAPA_LABEL_YM);
-    psastroVisualTriplePlot (kapa, &graphdata, xVec, yVec, zVec, false);
-
-    // Y vs dY
-    section.x = 0.5;
-    section.y = 0.0;
-    section.name = NULL;
-    psStringAppend (&section.name, "a3");
-    KapaSetSection (kapa, &section);
-    psFree (section.name);
-
-    n = 0;
-    for (int i = 0; i < match->n; i++) {
-        pmAstromMatch *pair = match->data[i];
-        pmAstromObj *raw = rawstars->data[pair->raw];
-        pmAstromObj *ref = refstars->data[pair->ref];
-
-        if (!isfinite(raw->Mag)) continue;
-        if (raw->Mag < iMagMin) continue;
-        if (raw->Mag > iMagMax) continue;
-        if (ref->Mag < rMagMin) continue;
-        if (ref->Mag > rMagMax) continue;
-
-        xVec->data.F32[n] = raw->chip->y;
-        yVec->data.F32[n] = raw->chip->y - ref->chip->y;
-        zVec->data.F32[n] = raw->Mag;
-        n++;
-    }
-    xVec->n = yVec->n = zVec->n = n;
-
-    KapaSendLabel (kapa, "Y", KAPA_LABEL_XM);
-    KapaSendLabel (kapa, "dY", KAPA_LABEL_YM);
-    pmKapaPlotVectorTriple_AutoLimits_OpenGraph (kapa, &graphdata, xVec, yVec, zVec, false);
-
-    section.x = 0.0;
-    section.y = 0.0;
-    section.dx = 0.95;
-    section.dy = 0.95;
-    section.name = NULL;
-    psStringAppend (&section.name, "a5");
-    KapaSetSection (kapa, &section);
-    KapaSendLabel (kapa, title, KAPA_LABEL_XP);
-    psFree (section.name);
-
-
-    // X vs Y plot (different window)
-    if (!psastroVisualInitWindow( &kapa2, "psastro:plots"))
-        return false;
-
-    KapaInitGraph (&graphdata);
-    KapaClearPlots (kapa2);
-
-    graphdata.color = KapaColorByName ("black");
-    graphdata.ptype = 2;
-    graphdata.style = 2;
-
-    psFree (xVec);
-    psFree (yVec);
-    psFree (zVec);
-
-    xVec = psVectorAlloc (rawstars->n, PS_TYPE_F32);
-    yVec = psVectorAlloc (rawstars->n, PS_TYPE_F32);
-    zVec = psVectorAlloc (rawstars->n, PS_TYPE_F32);
-
-    // X vs Y by mag (raw)
-    n = 0;
-    for (int i = 0; i < rawstars->n; i++) {
-        pmAstromObj *raw = rawstars->data[i];
-        if (!isfinite(raw->Mag)) continue;
-        if (raw->Mag < iMagMin) continue;
-        if (raw->Mag > iMagMax) continue;
-
-        xVec->data.F32[n] = raw->chip->x;
-        yVec->data.F32[n] = raw->chip->y;
-        zVec->data.F32[n] = raw->Mag;
-        n++;
-    }
-    xVec->n = yVec->n = zVec->n = n;
-
-    KapaSendLabel (kapa2, "X", KAPA_LABEL_XM);
-    KapaSendLabel (kapa2, "Y", KAPA_LABEL_YM);
-    KapaSendLabel (kapa2,
-                   "Chip Coordinates. Black = Raw Stars. Red = Ref Stars. Blue = Matched Stars"
-                   , KAPA_LABEL_XP);
-    psastroVisualTriplePlot (kapa2, &graphdata, xVec, yVec, zVec, false);
-
-    // X vs Y by mag (ref)
-    psFree (xVec);
-    psFree (yVec);
-    psFree (zVec);
-
-    xVec = psVectorAlloc (refstars->n, PS_TYPE_F32);
-    yVec = psVectorAlloc (refstars->n, PS_TYPE_F32);
-    zVec = psVectorAlloc (refstars->n, PS_TYPE_F32);
-
-    graphdata.color = KapaColorByName ("red");
-    graphdata.ptype = 7;
-    graphdata.style = 2;
-
-    n = 0;
-    for (int i = 0; i < refstars->n; i++) {
-        pmAstromObj *ref = refstars->data[i];
-        if (!isfinite(ref->Mag)) continue;
-        if (ref->Mag < rMagMin) continue;
-        if (ref->Mag > rMagMax) continue;
-
-        xVec->data.F32[n] = ref->chip->x;
-        yVec->data.F32[n] = ref->chip->y;
-        zVec->data.F32[n] = ref->Mag;
-        n++;
-    }
-    xVec->n = yVec->n = zVec->n = n;
-    psastroVisualTripleOverplot (kapa2, &graphdata, xVec, yVec, zVec, false);
-
-    //rescale the graph to include all points
-    float xmin = graphdata.xmin;
-    float ymin = graphdata.ymin;
-    float xmax = graphdata.xmax;
-    float ymax = graphdata.ymax;
-    psastroVisualScaleGraphdata(&graphdata, xVec, yVec, true);
-    graphdata.xmin = PS_MIN(xmin, graphdata.xmin);
-    graphdata.ymin = PS_MIN(ymin, graphdata.ymin);
-    graphdata.xmax = PS_MAX(xmax, graphdata.xmax);
-    graphdata.ymax = PS_MAX(ymax, graphdata.ymax);
-    KapaSetLimits (kapa2, &graphdata);
-
-    //overplot matched stars in blue
-    psFree (xVec);
-    psFree (yVec);
-    psFree (zVec);
-
-    xVec = psVectorAlloc (match->n, PS_TYPE_F32);
-    yVec = psVectorAlloc (match->n, PS_TYPE_F32);
-    zVec = psVectorAlloc (match->n, PS_TYPE_F32);
-
-    graphdata.color = KapaColorByName ("blue");
-    n = 0;
-    for (int i = 0; i < match->n; i++) {
-        pmAstromMatch *pair = match->data[i];
-        pmAstromObj *raw = rawstars->data[pair->raw];
-        pmAstromObj *ref = refstars->data[pair->ref];
-        if (raw->Mag < iMagMin) continue;
-        if (raw->Mag > iMagMax) continue;
-        if (ref->Mag < rMagMin) continue;
-        if (ref->Mag > rMagMax) continue;
-
-        xVec->data.F32[n] = raw->chip->x;
-        yVec->data.F32[n] = raw->chip->y;
-        zVec->data.F32[n] = iMagMin;
-        n++;
-    }
-    xVec->n = yVec->n = zVec->n = n;
-    psastroVisualTripleOverplot (kapa2, &graphdata, xVec, yVec, zVec, false);
-
-    psFree (xVec);
-    psFree (yVec);
-    psFree (zVec);
-    return true;
-}
-
-// END OF PROGRAM
-#else
-
-bool psastroSetVisual (bool mode) {return true};
-bool psastroVisualClose() {return true};
-bool psastroVisualPlotLuminosityFunction (psVector *lnMag, psVector *Mag, pmLumFunc *lumFunc, pmLumFunc *rawFunc) {return true};
-bool psastroVisualPlotRawStars (psArray *rawstars, pmFPA *fpa, pmChip *chip, psMetadata *recipe) {return true};
-bool psastroVisualPlotRefStars (psArray *refstars, psMetadata *recipe) {return true};
-bool psastroVisualPlotRemoveClumps (psArray *input, psImage *count, int scale, float limit) {return true};
-bool psastroVisualPlotFixChips (pmFPAfile *input, psVector *xOld, psVector *yOld) {return true};
-bool psastroVisualPlotOneChipFit (psArray *rawstars, psArray *refstars, psArray *match, psMetadata *recipe) {return true};
-bool psastroVisualPlotAstromGuessCheck (psVector *cornerPo, psVector *cornerQo, psVector *cornerPn, psVector *cornerQn, psVector *cornerPd, psVector *cornerQd) {return true};
-bool psastroVisualPlotMosaicOneChip (psArray *rawstars, psArray *refstars, psArray *match, psMetadata *recipe) {return true};
-bool psastroVisualPlotCommonScale (pmFPA *fpa, psVector *oldScale) {return true};
-bool psastroVisualPlotMosaicMatches (psArray *rawstars, psArray *refstars, psArray *match, int iteration, psMetadata *recipe) {return true};
-
-# endif
-
Index: /branches/cnb_branch_20090215/psconfig/tagsets/ipp-2.7.perl
===================================================================
--- /branches/cnb_branch_20090215/psconfig/tagsets/ipp-2.7.perl	(revision 21535)
+++ /branches/cnb_branch_20090215/psconfig/tagsets/ipp-2.7.perl	(revision 21536)
@@ -3,5 +3,5 @@
   00    Module::Build                  Module-Build-0.2806.tar.gz               0.2806         
   01    ExtUtils::MakeMaker            ExtUtils-MakeMaker-6.31.tar.gz           0         
-  02    Params::Validate               Params-Validate-0.87-eam.tar.gz          0.77         
+  02    Params::Validate               Params-Validate-0.87-eam-v1.tar.gz       0.77         
 #  02    Apache::Test                   Apache-Test-1.29.tar.gz                  1.29
   03    DateTime::TimeZone             DateTime-TimeZone-0.59.tar.gz            0         
Index: /branches/cnb_branch_20090215/psphot/src/psphot.h
===================================================================
--- /branches/cnb_branch_20090215/psphot/src/psphot.h	(revision 21535)
+++ /branches/cnb_branch_20090215/psphot/src/psphot.h	(revision 21536)
@@ -167,5 +167,4 @@
 
 // psphotVisual functions
-bool psphotSetVisual (bool mode);
 bool psphotVisualShowImage (pmReadout *readout);
 bool psphotVisualShowBackground (pmConfig *config, const pmFPAview *view, pmReadout *readout);
Index: /branches/cnb_branch_20090215/psphot/src/psphotAddNoise.c
===================================================================
--- /branches/cnb_branch_20090215/psphot/src/psphotAddNoise.c	(revision 21535)
+++ /branches/cnb_branch_20090215/psphot/src/psphotAddNoise.c	(revision 21536)
@@ -50,5 +50,5 @@
 
         // skip sources which were not subtracted
-        if (!(source->mode & PM_SOURCE_MODE_SUBTRACTED)) continue;
+        if (!(source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED)) continue;
 
         // select appropriate model
Index: /branches/cnb_branch_20090215/psphot/src/psphotApResid.c
===================================================================
--- /branches/cnb_branch_20090215/psphot/src/psphotApResid.c	(revision 21535)
+++ /branches/cnb_branch_20090215/psphot/src/psphotApResid.c	(revision 21536)
@@ -1,5 +1,3 @@
 # include "psphotInternal.h"
-
-bool psphotApResidMags_Unthreaded (int *nskip, int *nfail, psArray *sources, pmPSF *psf, pmSourcePhotometryMode photMode, psImageMaskType maskVal);
 
 # define SKIPSTAR(MSG) { psTrace ("psphot", 3, "invalid : %s", MSG); continue; }
@@ -95,23 +93,23 @@
 	for (int j = 0; j < cells->n; j++) {
 
-	    if (nThreads) {
-		// allocate a job -- if threads are not defined, this just runs the job
-		psThreadJob *job = psThreadJobAlloc ("PSPHOT_APRESID_MAGS");
-
-		psArrayAdd(job->args, 1, cells->data[j]); // sources
-		psArrayAdd(job->args, 1, psf);
-		PS_ARRAY_ADD_SCALAR(job->args, photMode, PS_TYPE_S32);
-		PS_ARRAY_ADD_SCALAR(job->args, maskVal,  PS_TYPE_IMAGE_MASK);
-
-		PS_ARRAY_ADD_SCALAR(job->args, 0,        PS_TYPE_S32); // this is used as a return value for Nskip
-		PS_ARRAY_ADD_SCALAR(job->args, 0,        PS_TYPE_S32); // this is used as a return value for Nfail
-
-		if (!psThreadJobAddPending(job)) {
-		    psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
-		    psFree (job);
-		    return false;
-		}
-		psFree(job);
-	    } else {
+	    // allocate a job -- if threads are not defined, this just runs the job
+	    psThreadJob *job = psThreadJobAlloc ("PSPHOT_APRESID_MAGS");
+
+	    psArrayAdd(job->args, 1, cells->data[j]); // sources
+	    psArrayAdd(job->args, 1, psf);
+	    PS_ARRAY_ADD_SCALAR(job->args, photMode, PS_TYPE_S32);
+	    PS_ARRAY_ADD_SCALAR(job->args, maskVal,  PS_TYPE_IMAGE_MASK);
+
+	    PS_ARRAY_ADD_SCALAR(job->args, 0,        PS_TYPE_S32); // this is used as a return value for Nskip
+	    PS_ARRAY_ADD_SCALAR(job->args, 0,        PS_TYPE_S32); // this is used as a return value for Nfail
+
+	    if (!psThreadJobAddPending(job)) {
+		psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
+		psFree (job);
+		return false;
+	    }
+	    psFree(job);
+
+# if (0)
 		int nskip = 0;
 		int nfail = 0;
@@ -123,29 +121,27 @@
 		Nskip += nskip;
 		Nfail += nfail;
-	    }		
+# endif
 
 	}
 
-	if (nThreads) {
-	    // wait for the threads to finish and manage results
-	    if (!psThreadPoolWait (false)) {
-		psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
-		return false;
+	// wait for the threads to finish and manage results
+	if (!psThreadPoolWait (false)) {
+	    psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
+	    return false;
+	}
+
+	// we have only supplied one type of job, so we can assume the types here
+	psThreadJob *job = NULL;
+	while ((job = psThreadJobGetDone()) != NULL) {
+	    if (job->args->n < 1) {
+		fprintf (stderr, "error with job\n");
+	    } else {
+		psScalar *scalar = NULL;
+		scalar = job->args->data[4];
+		Nskip += scalar->data.S32;
+		scalar = job->args->data[5];
+		Nfail += scalar->data.S32;
 	    }
-
-	    // we have only supplied one type of job, so we can assume the types here
-	    psThreadJob *job = NULL;
-	    while ((job = psThreadJobGetDone()) != NULL) {
-		if (job->args->n < 1) {
-		    fprintf (stderr, "error with job\n");
-		} else {
-		    psScalar *scalar = NULL;
-		    scalar = job->args->data[4];
-		    Nskip += scalar->data.S32;
-		    scalar = job->args->data[5];
-		    Nfail += scalar->data.S32;
-		}
-		psFree(job);
-	    }
+	    psFree(job);
 	}
     }
@@ -497,4 +493,5 @@
             continue;
         }
+        source->mode |= PM_SOURCE_MODE_AP_MAGS;
     }
 
@@ -509,4 +506,5 @@
 }
 
+# if (0)
 bool psphotApResidMags_Unthreaded (int *nskip, int *nfail, psArray *sources, pmPSF *psf, pmSourcePhotometryMode photMode, psImageMaskType maskVal) {
 
@@ -542,2 +540,3 @@
     return true;
 }
+# endif
Index: /branches/cnb_branch_20090215/psphot/src/psphotArguments.c
===================================================================
--- /branches/cnb_branch_20090215/psphot/src/psphotArguments.c	(revision 21535)
+++ /branches/cnb_branch_20090215/psphot/src/psphotArguments.c	(revision 21536)
@@ -82,6 +82,5 @@
     if ((N = psArgumentGet (argc, argv, "-visual"))) {
         psArgumentRemove (N, &argc, argv);
-        psphotSetVisual (true);
-        // pmSourceSetVisual (true);
+        pmVisualSetVisual(true);
     }
 
Index: /branches/cnb_branch_20090215/psphot/src/psphotBlendFit.c
===================================================================
--- /branches/cnb_branch_20090215/psphot/src/psphotBlendFit.c	(revision 21535)
+++ /branches/cnb_branch_20090215/psphot/src/psphotBlendFit.c	(revision 21536)
@@ -1,5 +1,3 @@
 # include "psphotInternal.h"
-
-bool psphotBlendFit_Unthreaded (int *nfit, int *npsf, int *next, int *nfail, pmReadout *readout, psMetadata *recipe, psArray *sources, pmPSF *psf, psArray *newSources);
 
 // XXX I don't like this name
@@ -62,28 +60,29 @@
         for (int j = 0; j < cells->n; j++) {
 
-            if (nThreads) {
-                // allocate a job -- if threads are not defined, this just runs the job
-                psThreadJob *job = psThreadJobAlloc ("PSPHOT_BLEND_FIT");
-                psArray *newSources = psArrayAllocEmpty(16);
-
-                psArrayAdd(job->args, 1, readout);
-                psArrayAdd(job->args, 1, recipe);
-                psArrayAdd(job->args, 1, cells->data[j]); // sources
-                psArrayAdd(job->args, 1, psf);
-                psArrayAdd(job->args, 1, newSources); // return for new sources
-                psFree (newSources);
-
-                PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Nfit
-                PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Npsf
-                PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Next
-                PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Nfail
-
-                if (!psThreadJobAddPending(job)) {
-                    psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
-                    psFree (job);
-                    return NULL;
-                }
-                psFree(job);
-            } else {
+	    // allocate a job -- if threads are not defined, this just runs the job
+	    psThreadJob *job = psThreadJobAlloc ("PSPHOT_BLEND_FIT");
+	    psArray *newSources = psArrayAllocEmpty(16);
+
+	    psArrayAdd(job->args, 1, readout);
+	    psArrayAdd(job->args, 1, recipe);
+	    psArrayAdd(job->args, 1, cells->data[j]); // sources
+	    psArrayAdd(job->args, 1, psf);
+	    psArrayAdd(job->args, 1, newSources); // return for new sources
+	    psFree (newSources);
+
+	    PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Nfit
+	    PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Npsf
+	    PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Next
+	    PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Nfail
+
+	    if (!psThreadJobAddPending(job)) {
+		psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
+		psFree (job);
+		return NULL;
+	    }
+	    psFree(job);
+
+# if (0)
+            {
                 int nfit = 0;
                 int npsf = 0;
@@ -107,38 +106,37 @@
                 psFree (newSources);
             }
-        }
-
-        if (nThreads) {
-            // wait for the threads to finish and manage results
-            if (!psThreadPoolWait (false)) {
-                psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
-                return NULL;
-            }
-
-            // we have only supplied one type of job, so we can assume the types here
-            psThreadJob *job = NULL;
-            while ((job = psThreadJobGetDone()) != NULL) {
-                if (job->args->n < 1) {
-                    fprintf (stderr, "error with job\n");
-                } else {
-                    psScalar *scalar = NULL;
-                    scalar = job->args->data[5];
-                    Nfit += scalar->data.S32;
-                    scalar = job->args->data[6];
-                    Npsf += scalar->data.S32;
-                    scalar = job->args->data[7];
-                    Next += scalar->data.S32;
-                    scalar = job->args->data[8];
-                    Nfail += scalar->data.S32;
-
-                    // add these back onto sources
-                    psArray *newSources = job->args->data[4];
-                    for (int j = 0; j < newSources->n; j++) {
-                        psArrayAdd (sources, 16, newSources->data[j]);
-                    }
-                }
-                psFree(job);
-            }
-        }
+# endif
+        }
+
+	// wait for the threads to finish and manage results
+	if (!psThreadPoolWait (false)) {
+	    psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
+	    return NULL;
+	}
+
+	// we have only supplied one type of job, so we can assume the types here
+	psThreadJob *job = NULL;
+	while ((job = psThreadJobGetDone()) != NULL) {
+	    if (job->args->n < 1) {
+		fprintf (stderr, "error with job\n");
+	    } else {
+		psScalar *scalar = NULL;
+		scalar = job->args->data[5];
+		Nfit += scalar->data.S32;
+		scalar = job->args->data[6];
+		Npsf += scalar->data.S32;
+		scalar = job->args->data[7];
+		Next += scalar->data.S32;
+		scalar = job->args->data[8];
+		Nfail += scalar->data.S32;
+
+		// add these back onto sources
+		psArray *newSources = job->args->data[4];
+		for (int j = 0; j < newSources->n; j++) {
+		    psArrayAdd (sources, 16, newSources->data[j]);
+		}
+	    }
+	    psFree(job);
+            }
     }
     psFree (cellGroups);
@@ -225,5 +223,118 @@
 
         // replace object in image
-        if (source->mode & PM_SOURCE_MODE_SUBTRACTED) {
+        if (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED) {
+            pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
+        }
+        Nfit ++;
+
+        // try fitting PSFs or extended sources depending on source->mode
+        // these functions subtract the resulting fitted source
+        if (source->mode & PM_SOURCE_MODE_EXT_LIMIT) {
+            if (psphotFitBlob (readout, source, newSources, psf, maskVal, markVal)) {
+                source->type = PM_SOURCE_TYPE_EXTENDED;
+                psTrace ("psphot", 5, "source at %7.1f, %7.1f is ext", source->peak->xf, source->peak->yf);
+                Next ++;
+		source->mode |= PM_SOURCE_MODE_NONLINEAR_FIT;
+                continue;
+            }
+        } else {
+            if (psphotFitBlend (readout, source, psf, maskVal, markVal)) {
+                source->type = PM_SOURCE_TYPE_STAR;
+                psTrace ("psphot", 5, "source at %7.1f, %7.1f is psf", source->peak->xf, source->peak->yf);
+                Npsf ++;
+		source->mode |= PM_SOURCE_MODE_NONLINEAR_FIT;
+                continue;
+            }
+        }
+
+        psTrace ("psphot", 5, "source at %7.1f, %7.1f failed", source->peak->xf, source->peak->yf);
+        Nfail ++;
+
+        // re-subtract the object, leave local sky
+        pmSourceCacheModel (source, maskVal);
+        pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
+        source->tmpFlags |= PM_SOURCE_TMPF_SUBTRACTED;
+    }
+
+    // change the value of a scalar on the array (wrap this and put it in psArray.h)
+    scalar = job->args->data[5];
+    scalar->data.S32 = Nfit;
+
+    scalar = job->args->data[6];
+    scalar->data.S32 = Npsf;
+
+    scalar = job->args->data[7];
+    scalar->data.S32 = Next;
+
+    scalar = job->args->data[8];
+    scalar->data.S32 = Nfail;
+
+    return true;
+}
+
+# if (0)
+bool psphotBlendFit_Unthreaded (int *nfit, int *npsf, int *next, int *nfail, pmReadout *readout, psMetadata *recipe, psArray *sources, pmPSF *psf, psArray *newSources) {
+
+    bool status = false;
+    int Nfit = 0;
+    int Npsf = 0;
+    int Next = 0;
+    int Nfail = 0;
+
+    // bit-masks to test for good/bad pixels
+    psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT");
+    assert (maskVal);
+
+    // bit-mask to mark pixels not used in analysis
+    psImageMaskType markVal = psMetadataLookupImageMask(&status, recipe, "MARK.PSPHOT");
+    assert (markVal);
+
+    // maskVal is used to test for rejected pixels, and must include markVal
+    maskVal |= markVal;
+
+    // S/N limit to perform full non-linear fits
+    float FIT_SN_LIM = psMetadataLookupF32 (&status, recipe, "FULL_FIT_SN_LIM");
+
+    // option to limit analysis to a specific region
+    char *region = psMetadataLookupStr (&status, recipe, "ANALYSIS_REGION");
+    psRegion AnalysisRegion = psRegionForImage (readout->image, psRegionFromString (region));
+    if (psRegionIsNaN (AnalysisRegion)) psAbort("analysis region mis-defined");
+
+    for (int i = 0; i < sources->n; i++) {
+        pmSource *source = sources->data[i];
+
+        // skip non-astronomical objects (very likely defects)
+        if (source->mode &  PM_SOURCE_MODE_BLEND) continue;
+        if (source->mode &  PM_SOURCE_MODE_CR_LIMIT) continue;
+        if (source->type == PM_SOURCE_TYPE_DEFECT) continue;
+        if (source->type == PM_SOURCE_TYPE_SATURATED) continue;
+
+        // skip DBL second sources (ie, added by psphotFitBlob)
+        if (source->mode &  PM_SOURCE_MODE_PAIR) continue;
+
+        // limit selection to some SN limit
+        if (source->peak->SN < FIT_SN_LIM) continue;
+
+        // exclude sources outside optional analysis region
+        if (source->peak->xf < AnalysisRegion.x0) continue;
+        if (source->peak->yf < AnalysisRegion.y0) continue;
+        if (source->peak->xf > AnalysisRegion.x1) continue;
+        if (source->peak->yf > AnalysisRegion.y1) continue;
+
+        // if model is NULL, we don't have a starting guess
+        if (source->modelPSF == NULL) continue;
+
+        // skip sources which are insignificant flux?
+        // XXX this is somewhat ad-hoc
+        if (source->modelPSF->params->data.F32[1] < 0.1) {
+            psTrace ("psphot", 5, "skipping near-zero source: %f, %f : %f\n",
+                     source->modelPSF->params->data.F32[1],
+                     source->modelPSF->params->data.F32[2],
+                     source->modelPSF->params->data.F32[3]);
+            continue;
+        }
+
+        // replace object in image
+        if (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED) {
             pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
         }
@@ -254,115 +365,5 @@
         pmSourceCacheModel (source, maskVal);
         pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
-        source->mode |= PM_SOURCE_MODE_SUBTRACTED;
-    }
-
-    // change the value of a scalar on the array (wrap this and put it in psArray.h)
-    scalar = job->args->data[5];
-    scalar->data.S32 = Nfit;
-
-    scalar = job->args->data[6];
-    scalar->data.S32 = Npsf;
-
-    scalar = job->args->data[7];
-    scalar->data.S32 = Next;
-
-    scalar = job->args->data[8];
-    scalar->data.S32 = Nfail;
-
-    return true;
-}
-
-bool psphotBlendFit_Unthreaded (int *nfit, int *npsf, int *next, int *nfail, pmReadout *readout, psMetadata *recipe, psArray *sources, pmPSF *psf, psArray *newSources) {
-
-    bool status = false;
-    int Nfit = 0;
-    int Npsf = 0;
-    int Next = 0;
-    int Nfail = 0;
-
-    // bit-masks to test for good/bad pixels
-    psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT");
-    assert (maskVal);
-
-    // bit-mask to mark pixels not used in analysis
-    psImageMaskType markVal = psMetadataLookupImageMask(&status, recipe, "MARK.PSPHOT");
-    assert (markVal);
-
-    // maskVal is used to test for rejected pixels, and must include markVal
-    maskVal |= markVal;
-
-    // S/N limit to perform full non-linear fits
-    float FIT_SN_LIM = psMetadataLookupF32 (&status, recipe, "FULL_FIT_SN_LIM");
-
-    // option to limit analysis to a specific region
-    char *region = psMetadataLookupStr (&status, recipe, "ANALYSIS_REGION");
-    psRegion AnalysisRegion = psRegionForImage (readout->image, psRegionFromString (region));
-    if (psRegionIsNaN (AnalysisRegion)) psAbort("analysis region mis-defined");
-
-    for (int i = 0; i < sources->n; i++) {
-        pmSource *source = sources->data[i];
-
-        // skip non-astronomical objects (very likely defects)
-        if (source->mode &  PM_SOURCE_MODE_BLEND) continue;
-        if (source->mode &  PM_SOURCE_MODE_CR_LIMIT) continue;
-        if (source->type == PM_SOURCE_TYPE_DEFECT) continue;
-        if (source->type == PM_SOURCE_TYPE_SATURATED) continue;
-
-        // skip DBL second sources (ie, added by psphotFitBlob)
-        if (source->mode &  PM_SOURCE_MODE_PAIR) continue;
-
-        // limit selection to some SN limit
-        if (source->peak->SN < FIT_SN_LIM) continue;
-
-        // exclude sources outside optional analysis region
-        if (source->peak->xf < AnalysisRegion.x0) continue;
-        if (source->peak->yf < AnalysisRegion.y0) continue;
-        if (source->peak->xf > AnalysisRegion.x1) continue;
-        if (source->peak->yf > AnalysisRegion.y1) continue;
-
-        // if model is NULL, we don't have a starting guess
-        if (source->modelPSF == NULL) continue;
-
-        // skip sources which are insignificant flux?
-        // XXX this is somewhat ad-hoc
-        if (source->modelPSF->params->data.F32[1] < 0.1) {
-            psTrace ("psphot", 5, "skipping near-zero source: %f, %f : %f\n",
-                     source->modelPSF->params->data.F32[1],
-                     source->modelPSF->params->data.F32[2],
-                     source->modelPSF->params->data.F32[3]);
-            continue;
-        }
-
-        // replace object in image
-        if (source->mode & PM_SOURCE_MODE_SUBTRACTED) {
-            pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
-        }
-        Nfit ++;
-
-        // try fitting PSFs or extended sources depending on source->mode
-        // these functions subtract the resulting fitted source
-        if (source->mode & PM_SOURCE_MODE_EXT_LIMIT) {
-            if (psphotFitBlob (readout, source, newSources, psf, maskVal, markVal)) {
-                source->type = PM_SOURCE_TYPE_EXTENDED;
-                psTrace ("psphot", 5, "source at %7.1f, %7.1f is ext", source->peak->xf, source->peak->yf);
-                Next ++;
-                continue;
-            }
-        } else {
-            if (psphotFitBlend (readout, source, psf, maskVal, markVal)) {
-                source->type = PM_SOURCE_TYPE_STAR;
-                psTrace ("psphot", 5, "source at %7.1f, %7.1f is psf", source->peak->xf, source->peak->yf);
-                Npsf ++;
-                continue;
-            }
-        }
-
-        psTrace ("psphot", 5, "source at %7.1f, %7.1f failed", source->peak->xf, source->peak->yf);
-        Nfail ++;
-
-        // re-subtract the object, leave local sky
-        pmSourceCacheModel (source, maskVal);
-        pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
-        source->mode |= PM_SOURCE_MODE_SUBTRACTED;
+        source->tmpFlags |= PM_SOURCE_TMPF_SUBTRACTED;
     }
 
@@ -375,2 +376,3 @@
     return true;
 }
+# endif
Index: /branches/cnb_branch_20090215/psphot/src/psphotDeblendSatstars.c
===================================================================
--- /branches/cnb_branch_20090215/psphot/src/psphotDeblendSatstars.c	(revision 21535)
+++ /branches/cnb_branch_20090215/psphot/src/psphotDeblendSatstars.c	(revision 21536)
@@ -111,5 +111,5 @@
 	
 	// any peaks within this contour should be dropped (mark as blend, drop after loop is done)
-	// also drop any peaks which are too close to this peal
+	// also drop any peaks which are too close to this peak
         psVector *xv = contour->data[0];
         psVector *yv = contour->data[1];
Index: /branches/cnb_branch_20090215/psphot/src/psphotDetectReadout.c
===================================================================
--- /branches/cnb_branch_20090215/psphot/src/psphotDetectReadout.c	(revision 21535)
+++ /branches/cnb_branch_20090215/psphot/src/psphotDetectReadout.c	(revision 21536)
@@ -22,7 +22,4 @@
     // Generate the mask and weight images, including the user-defined analysis region of interest
     psphotSetMaskAndWeight (config, readout, recipe);
-    if (!strcasecmp (breakPt, "NOTHING")) {
-        return psphotReadoutCleanup(config, readout, recipe, NULL, NULL, NULL);
-    }
 
     // load the psf model, if suppled.  FWHM_X,FWHM_Y,etc are saved in the recipe
@@ -38,22 +35,5 @@
 
     // include externally-supplied sources (supplied as PSPHOT.INPUT.CMF)
-    pmDetections *detections = psphotDetectionsFromSources (config, inSources);
-    if (!detections || !detections->peaks) {
-        psError(PSPHOT_ERR_ARGUMENTS, true, "Can't find PSF stars");
-        return psphotReadoutCleanup(config, readout, recipe, detections, NULL, NULL);
-    }
-
-    // construct sources and measure basic stats
-    psArray *sources = psphotSourceStats (config, readout, detections);
-    if (!sources) return false;
-    if (!strcasecmp (breakPt, "PEAKS")) {
-        return psphotReadoutCleanup(config, readout, recipe, detections, psf, sources);
-    }
-
-    // classify sources based on moments, brightness
-    if (!psphotRoughClass (readout, sources, recipe, havePSF)) {
-        psLogMsg ("psphot", 3, "failed to find a valid PSF clump for image");
-        return psphotReadoutCleanup (config, readout, recipe, detections, psf, sources);
-    }
+    psphotSetSourceParams (config, sources, psf);
 
     // calculate source magnitudes
@@ -63,2 +43,12 @@
     return psphotReadoutCleanup(config, readout, recipe, detections, psf, sources);
 }
+
+// deep in pmSourcePixelWeight, we need the following items for each location of interest:
+// pmModel *model (should be a realized version of the PSF, can have unity normalization)
+// psImage *mask  (local subimage of mask for source)
+// psImageMaskType maskVal (from recipe & mask header)
+
+{ 
+    pmModel *model = pmModelFromPSFforXY (psf, x, y, 1.0);
+}
+
Index: /branches/cnb_branch_20090215/psphot/src/psphotExtendedSourceAnalysis.c
===================================================================
--- /branches/cnb_branch_20090215/psphot/src/psphotExtendedSourceAnalysis.c	(revision 21535)
+++ /branches/cnb_branch_20090215/psphot/src/psphotExtendedSourceAnalysis.c	(revision 21536)
@@ -61,5 +61,5 @@
 
 	// replace object in image
-	if (source->mode & PM_SOURCE_MODE_SUBTRACTED) {
+	if (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED) {
 	    pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
 	}
@@ -73,7 +73,8 @@
 		psTrace ("psphot", 5, "failed to extract radial profile for source at %7.1f, %7.1f", source->moments->Mx, source->moments->My);
 		pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
-		source->mode |= PM_SOURCE_MODE_SUBTRACTED;
+		source->tmpFlags |= PM_SOURCE_TMPF_SUBTRACTED;
 		continue;
 	    }
+	    source->mode |= PM_SOURCE_MODE_RADIAL_FLUX;
 	}
 
@@ -85,4 +86,5 @@
 		psTrace ("psphot", 5, "measured isophotal mags for source at %7.1f, %7.1f", source->moments->Mx, source->moments->My);
 		Nisophot ++;
+		source->mode |= PM_SOURCE_MODE_EXTENDED_STATS;
 	    }
 	}
@@ -95,4 +97,5 @@
 		psTrace ("psphot", 5, "measured petrosian flux & radius for source at %7.1f, %7.1f", source->moments->Mx, source->moments->My);
 		Npetro ++;
+		source->mode |= PM_SOURCE_MODE_EXTENDED_STATS;
 	    }
 	}
@@ -105,4 +108,5 @@
 		psTrace ("psphot", 5, "measure kron mags for source at %7.1f, %7.1f", source->moments->Mx, source->moments->My);
 		Nkron ++;
+		source->mode |= PM_SOURCE_MODE_EXTENDED_STATS;
 	    }
 	}
@@ -116,9 +120,10 @@
 	    psTrace ("psphot", 5, "measured annuli for source at %7.1f, %7.1f", source->moments->Mx, source->moments->My);
 	    Nannuli ++;
+	    source->mode |= PM_SOURCE_MODE_EXTENDED_STATS;
 	}
 
 	// re-subtract the object, leave local sky
 	pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
-	source->mode |= PM_SOURCE_MODE_SUBTRACTED;
+	source->tmpFlags |= PM_SOURCE_TMPF_SUBTRACTED;
     }
 
Index: /branches/cnb_branch_20090215/psphot/src/psphotExtendedSourceFits.c
===================================================================
--- /branches/cnb_branch_20090215/psphot/src/psphotExtendedSourceFits.c	(revision 21535)
+++ /branches/cnb_branch_20090215/psphot/src/psphotExtendedSourceFits.c	(revision 21536)
@@ -110,5 +110,5 @@
 
         // replace object in image
-        if (source->mode & PM_SOURCE_MODE_SUBTRACTED) {
+        if (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED) {
             pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
         }
@@ -170,4 +170,5 @@
               if (!(modelFit->flags & (PM_MODEL_STATUS_BADARGS | PM_MODEL_STATUS_NONCONVERGE | PM_MODEL_STATUS_OFFIMAGE))) {
                   NconvolvePass ++;
+		  source->mode |= PM_SOURCE_MODE_EXTENDED_FIT;
               }
           } else {
@@ -184,4 +185,5 @@
               if (!(modelFit->flags & (PM_MODEL_STATUS_BADARGS | PM_MODEL_STATUS_NONCONVERGE | PM_MODEL_STATUS_OFFIMAGE))) {
                   NplainPass ++;
+		  source->mode |= PM_SOURCE_MODE_EXTENDED_FIT;
               }
           }
@@ -224,5 +226,5 @@
 
           pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
-          source->mode |= PM_SOURCE_MODE_SUBTRACTED;
+          source->tmpFlags |= PM_SOURCE_TMPF_SUBTRACTED;
 
           psFree (modelFluxes);
@@ -251,5 +253,5 @@
         // subtract the best fit from the object, leave local sky
         pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
-        source->mode |= PM_SOURCE_MODE_SUBTRACTED;
+        source->tmpFlags |= PM_SOURCE_TMPF_SUBTRACTED;
 
         // the initial model flux is no longer needed
Index: anches/cnb_branch_20090215/psphot/src/psphotExtendedSources.c
===================================================================
--- /branches/cnb_branch_20090215/psphot/src/psphotExtendedSources.c	(revision 21535)
+++ 	(revision )
@@ -1,137 +1,0 @@
-# include "psphot.h"
-
-bool psphotExtendedSources (pmReadout *readout, psArray *sources, psMetadata *recipe) {
-
-    bool status;
-    int Next = 0;
-    int Nconvolve = 0;
-    int Npetro = 0;
-    int Nisophot = 0;
-    int Nannuli = 0;
-    int Nkron = 0;
-
-    // user-defined masks to test for good/bad pixels (build from recipe list if not yet set)
-    psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT"); // Mask value for bad pixels
-    assert (maskVal);
-
-    // perform full non-linear fits / extended source analysis?
-    if (!psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_FITS")) {
-	psLogMsg ("psphot", PS_LOG_INFO, "skipping extended source measurements\n");
-	return true;
-    }
-
-    // option to limit analysis to a specific region
-    char *region = psMetadataLookupStr (&status, recipe, "ANALYSIS_REGION");
-    psRegion AnalysisRegion = psRegionForImage (readout->image, psRegionFromString (region));
-    if (psRegionIsNaN (AnalysisRegion)) psAbort("analysis region mis-defined");
-
-    // S/N limit to perform full non-linear fits
-    float SN_LIM = psMetadataLookupF32 (&status, recipe, "EXTENDED_SOURCE_SN_LIM");
-
-    // which extended source analyses should we perform?
-    bool doPSFConvModel = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_PSF_CONVOLVED_MODEL");
-    bool doPetrosian    = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_PETROSIAN");
-    bool doIsophotal    = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_ISOPHOTAL");
-    bool doAnnuli       = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_ANNULI");
-    bool doKron         = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_KRON");
-
-    // source analysis is done in S/N order (brightest first)
-    sources = psArraySort (sources, pmSourceSortBySN);
-
-    // XXX some init functions for the extended source recipe options?
-
-    // choose the sources of interest
-    for (int i = 0; i < sources->n; i++) {
-
-        pmSource *source = sources->data[i];
-
-        // skip PSF-like and non-astronomical objects
-        if (source->type == PM_SOURCE_TYPE_STAR) continue;
-        if (source->type == PM_SOURCE_TYPE_DEFECT) continue;
-        if (source->type == PM_SOURCE_TYPE_SATURATED) continue;
-
-        // limit selection to some SN limit
-        assert (source->peak); // how can a source not have a peak?
-        if (source->peak->SN < SN_LIM) continue;
-
-        // XXX this should use peak?
-        if (source->peak->x < AnalysisRegion.x0) continue;
-        if (source->peak->y < AnalysisRegion.y0) continue;
-        if (source->peak->x > AnalysisRegion.x1) continue;
-        if (source->peak->y > AnalysisRegion.y1) continue;
-
-        // if model is NULL, we don't have a starting guess
-	// XXX this is probably not needed for objects where we only measure aperture-like terms
-        if (source->modelEXT == NULL) continue;
-
-        // replace object in image
-        if (source->mode & PM_SOURCE_MODE_SUBTRACTED) {
-            pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
-        }
-        Next ++;
-
-	if (doPSFConvModel && !psphotPSFConvModel (source, recipe, maskVal)) {
-	    psError(PSPHOT_ERR_UNKNOWN, false, "failure in PSF Convolved Model fit");
-	    return false;
-	} else {
-	  // XXX why am I caching the model?
-	    pmSourceCacheModel (source, maskVal); // XXX put this in the source model function?
-	    psTrace ("psphot", 5, "psf-convolved model for source at %7.1f, %7.1f", source->moments->x, source->moments->y);
-            Nconvolve ++;
-	}
-
-	// all of these below require the radial profile
-	// XXX push this as a test and call in each of the functions below?
-	// XXX this constructs a pmSourceExtendedParameters element
-	if (doPetrosian || doIsophotal || doAnnuli || doKron) {
-	  if (!psphotRadialProfile (source, recipe, maskVal)) {
-	    psError(PSPHOT_ERR_UNKNOWN, false, "failure to generate radial profile");
-	    return false;
-	  }
-	}
-
-	if (doPetrosian && !psphotPetrosian (source, recipe, maskVal)) {
-	    psError(PSPHOT_ERR_UNKNOWN, false, "failure in Petrosian analysis");
-	    return false;
-	} else {
-	    psTrace ("psphot", 5, "measured petrosian flux & radius for source at %7.1f, %7.1f", source->moments->x, source->moments->y);
-            Npetro ++;
-	}
-
-	if (doIsophotal && !psphotIsophotal (source, recipe, maskVal)) {
-	    psError(PSPHOT_ERR_UNKNOWN, false, "failure in Isophotal analysis");
-	    return false;
-	} else {
-	    psTrace ("psphot", 5, "psf-convolved model for source at %7.1f, %7.1f", source->moments->x, source->moments->y);
-            Nisophot ++;
-	}
-
-	if (doAnnuli && !psphotAnnuli (source, recipe, maskVal)) {
-	    psError(PSPHOT_ERR_UNKNOWN, false, "failure in Annuli analysis");
-	    return false;
-	} else {
-	    psTrace ("psphot", 5, "psf-convolved model for source at %7.1f, %7.1f", source->moments->x, source->moments->y);
-            Nannuli ++;
-	}
-
-	if (doKron && !psphotKron (source, recipe, maskVal)) {
-	    psError(PSPHOT_ERR_UNKNOWN, false, "failure in Kron analysis");
-	    return false;
-	} else {
-	    psTrace ("psphot", 5, "psf-convolved model for source at %7.1f, %7.1f", source->moments->x, source->moments->y);
-            Nkron ++;
-	}
-
-        // re-subtract the object, leave local sky
-        pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
-        source->mode |= PM_SOURCE_MODE_SUBTRACTED;
-    }
-
-    psLogMsg ("psphot", PS_LOG_INFO, "extended source analysis: %f sec for %d objects\n", psTimerMark ("psphot"), Next);
-    psLogMsg ("psphot", PS_LOG_INFO, "  %d convolved models\n", Nconvolve);
-    psLogMsg ("psphot", PS_LOG_INFO, "  %d petrosian\n", Npetro);
-    psLogMsg ("psphot", PS_LOG_INFO, "  %d isophotal\n", Nisophot);
-    psLogMsg ("psphot", PS_LOG_INFO, "  %d annuli\n", Nannuli);
-    psLogMsg ("psphot", PS_LOG_INFO, "  %d kron\n", Nkron);
-    return true;
-}
Index: /branches/cnb_branch_20090215/psphot/src/psphotFindPeaks.c
===================================================================
--- /branches/cnb_branch_20090215/psphot/src/psphotFindPeaks.c	(revision 21535)
+++ /branches/cnb_branch_20090215/psphot/src/psphotFindPeaks.c	(revision 21536)
@@ -21,7 +21,8 @@
     }
 
-    // correct the peak values to S/N = sqrt(significance)
-    // get the peak flux from the unsmoothed image
-    // the peak pixel coords are guaranteed to be on the image
+    // Convert the peak values to S/N = sqrt(significance).
+    // Get the peak flux from the unsmoothed image.
+    // Rescale the peak position errors using the peak variance
+    // The peak pixel coords are guaranteed to be on the image
     int row0 = readout->image->row0;
     int col0 = readout->image->col0;
@@ -30,4 +31,10 @@
         peak->SN = sqrt(peak->value);
         peak->flux = readout->image->data.F32[peak->y-row0][peak->x-col0];
+	if (readout->variance && isfinite (peak->dx)) {
+	    peak->dx *= sqrt(readout->variance->data.F32[peak->y-row0][peak->x-col0]);
+	}
+	if (readout->variance && isfinite (peak->dy)) {
+	    peak->dy *= sqrt(readout->variance->data.F32[peak->y-row0][peak->x-col0]);
+	}
     }
 
Index: /branches/cnb_branch_20090215/psphot/src/psphotFitSourcesLinear.c
===================================================================
--- /branches/cnb_branch_20090215/psphot/src/psphotFitSourcesLinear.c	(revision 21535)
+++ /branches/cnb_branch_20090215/psphot/src/psphotFitSourcesLinear.c	(revision 21536)
@@ -63,15 +63,18 @@
         pmSource *source = sources->data[i];
 
+	// turn this bit off and turn it on again if we pass this test
+	source->mode &= ~PM_SOURCE_MODE_LINEAR_FIT;
+
         // skip non-astronomical objects (very likely defects)
         if (source->type == PM_SOURCE_TYPE_DEFECT) continue;
         if (source->type == PM_SOURCE_TYPE_SATURATED) continue;
 
-        // if (source->type == PM_SOURCE_TYPE_STAR &&
+	// do not include CRs in the full ensemble fit
         if (source->mode & PM_SOURCE_MODE_CR_LIMIT) continue;
 
         if (final) {
-            if (source->mode &  PM_SOURCE_MODE_SUBTRACTED) continue;
+            if (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED) continue;
         } else {
-            if (source->mode &  PM_SOURCE_MODE_BLEND) continue;
+            if (source->mode & PM_SOURCE_MODE_BLEND) continue;
         }
 
@@ -91,4 +94,5 @@
         if (y > AnalysisRegion.y1) continue;
 
+	source->mode |= PM_SOURCE_MODE_LINEAR_FIT;
         psArrayAdd (fitSources, 100, source);
     }
@@ -185,4 +189,10 @@
     psLogMsg ("psphot.ensemble", PS_LOG_MINUTIA, "solve matrix: %f sec (%d elements)\n", psTimerMark ("psphot.linear"), sparse->Nelem);
 
+    // XXXX **** philosophical question: 
+    // we measure bright objects in three passes: 1) linear fit; 2) non-linear fit; 3) linear fit:
+    // should retain the chisq and errors from the intermediate non-linear fit? 
+    // the non-linear fit provides better values for the position errors, and for 
+    // extended sources, the shape errors
+
     // adjust I0 for fitSources and subtract
     for (int i = 0; i < fitSources->n; i++) {
@@ -194,4 +204,5 @@
             psAbort("linear fitted source is nan");
         }
+
         model->params->data.F32[PM_PAR_I0] = norm->data.F32[i];
         model->dparams->data.F32[PM_PAR_I0] = errors->data.F32[i];
@@ -200,5 +211,5 @@
         // subtract object
         pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
-        source->mode |= PM_SOURCE_MODE_SUBTRACTED;
+        source->tmpFlags |= PM_SOURCE_TMPF_SUBTRACTED;
     }
     psLogMsg ("psphot.ensemble", PS_LOG_MINUTIA, "sub models: %f sec (%d elements)\n", psTimerMark ("psphot.linear"), sparse->Nelem);
@@ -207,4 +218,5 @@
     for (int i = 0; final && (i < fitSources->n); i++) {
         pmSource *source = fitSources->data[i];
+	if (source->mode & PM_SOURCE_MODE_NONLINEAR_FIT) continue;
         pmModel *model = pmSourceGetModel (NULL, source);
         pmSourceChisq (model, source->pixels, source->maskObj, source->variance, maskVal);
Index: /branches/cnb_branch_20090215/psphot/src/psphotGuessModels.c
===================================================================
--- /branches/cnb_branch_20090215/psphot/src/psphotGuessModels.c	(revision 21535)
+++ /branches/cnb_branch_20090215/psphot/src/psphotGuessModels.c	(revision 21536)
@@ -22,6 +22,4 @@
 }
 
-bool psphotGuessModel_Unthreaded (pmReadout *readout, psArray *sources, pmPSF *psf, psImageMaskType maskVal, psImageMaskType markVal);
-
 // construct an initial PSF model for each object
 bool psphotGuessModels (pmConfig *config, pmReadout *readout, psArray *sources, pmPSF *psf) {
@@ -67,47 +65,45 @@
 	for (int j = 0; j < cells->n; j++) {
 
-	    if (nThreads) {
-		// allocate a job -- if threads are not defined, this just runs the job
-		psThreadJob *job = psThreadJobAlloc ("PSPHOT_GUESS_MODEL");
-		psArrayAdd(job->args, 1, readout);
-		psArrayAdd(job->args, 1, cells->data[j]); // sources
-		psArrayAdd(job->args, 1, psf);
-
-		// XXX change these to use abstract mask type info
-		PS_ARRAY_ADD_SCALAR(job->args, maskVal,  PS_TYPE_IMAGE_MASK);
-		PS_ARRAY_ADD_SCALAR(job->args, markVal,  PS_TYPE_IMAGE_MASK);
-
-		if (!psThreadJobAddPending(job)) {
-		    psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
-		    psFree (job);
-		    return false;
-		}
-		psFree(job);
-	    } else {
+	    // allocate a job -- if threads are not defined, this just runs the job
+	    psThreadJob *job = psThreadJobAlloc ("PSPHOT_GUESS_MODEL");
+	    psArrayAdd(job->args, 1, readout);
+	    psArrayAdd(job->args, 1, cells->data[j]); // sources
+	    psArrayAdd(job->args, 1, psf);
+
+	    // XXX change these to use abstract mask type info
+	    PS_ARRAY_ADD_SCALAR(job->args, maskVal,  PS_TYPE_IMAGE_MASK);
+	    PS_ARRAY_ADD_SCALAR(job->args, markVal,  PS_TYPE_IMAGE_MASK);
+
+	    if (!psThreadJobAddPending(job)) {
+		psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
+		psFree (job);
+		return false;
+	    }
+	    psFree(job);
+
+# if (0)		
 		if (!psphotGuessModel_Unthreaded (readout, cells->data[j], psf, maskVal, markVal)) {
 		    psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
 		    return false;
 		}
-	    }
-	}
-
-	if (nThreads) {
-	    // wait for the threads to finish and manage results
-	    // wait here for the threaded jobs to finish
-	    // fprintf (stderr, "wait for threads (%d, %d)\n", jx, jy);
-	    if (!psThreadPoolWait (false)) {
-		psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
-		return false;
-	    }
-
-	    // we have only supplied one type of job, so we can assume the types here
-	    psThreadJob *job = NULL;
-	    while ((job = psThreadJobGetDone()) != NULL) {
-		// we have no returned data from this operation
-		if (job->args->n < 1) {
-		    fprintf (stderr, "error with job\n");
-		}
-		psFree(job);
-	    }
+# endif
+	}
+
+	// wait for the threads to finish and manage results
+	// wait here for the threaded jobs to finish
+	// fprintf (stderr, "wait for threads (%d, %d)\n", jx, jy);
+	if (!psThreadPoolWait (false)) {
+	    psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
+	    return false;
+	}
+
+	// we have only supplied one type of job, so we can assume the types here
+	psThreadJob *job = NULL;
+	while ((job = psThreadJobGetDone()) != NULL) {
+	    // we have no returned data from this operation
+	    if (job->args->n < 1) {
+		fprintf (stderr, "error with job\n");
+	    }
+	    psFree(job);
 	}
     }
@@ -116,14 +112,11 @@
     int nMiss = 0;
     for (int i = 0; i < sources->n; i++) {
-
 	pmSource *source = sources->data[i];
-	if (source->mode & PM_SOURCE_MODE_EXT_LIMIT) {
-	    source->mode &= ~PM_SOURCE_MODE_EXT_LIMIT;
+	if (source->tmpFlags & PM_SOURCE_TMPF_MODEL_GUESS) {
 	    continue;
 	}
-
 	nMiss ++;
     }
-    psLogMsg ("psphot.models", 4, "failed to build models for %d objects\n", nMiss);
+    psAssert (nMiss == 0, "failed to attempt to build models for %d objects\n", nMiss);
 
     psFree (cellGroups);
@@ -148,7 +141,7 @@
 	pmSource *source = sources->data[i];
 
-	// XXXX this is just for a test: use this to mark sources for which the model is measured
-	// check later that all are used.
-	source->mode |= PM_SOURCE_MODE_EXT_LIMIT;
+	// this is used to mark sources for which the model is measured. We check later that
+	// all are used.
+	source->tmpFlags |= PM_SOURCE_TMPF_MODEL_GUESS;
 
 	// skip non-astronomical objects (very likely defects)
@@ -185,20 +178,16 @@
 	pmModel *modelPSF = pmModelFromPSF (modelEXT, psf); // ALLOC X5
 	if (modelPSF == NULL) {
-	    psError(PSPHOT_ERR_PSF, false,
-		    "Failed to determine PSF model at r,c = (%d,%d); trying centre of image",
+	    psWarning ("Failed to determine PSF model at r,c = (%d,%d); trying centre of image",
 		    source->peak->y, source->peak->x);
-	    //
-	    // Try the centre of the image
-	    //
+
+	    // Try the center of the image
 	    modelEXT->params->data.F32[PM_PAR_XPOS] = 0.5*readout->image->numCols;
 	    modelEXT->params->data.F32[PM_PAR_YPOS] = 0.5*readout->image->numRows;
 	    modelPSF = pmModelFromPSF (modelEXT, psf);
 	    if (modelPSF == NULL) {
-		psError(PSPHOT_ERR_PSF, false,
-			"Failed to determine PSF model at centre of image");
+		psError(PSPHOT_ERR_PSF, false, "Failed to determine PSF model at center of image");
 		psFree(modelEXT);
 		return false;
 	    }
-
 	    source->mode |= PM_SOURCE_MODE_BADPSF;
 	}
@@ -221,4 +210,5 @@
 }
 
+# if (0)
 // construct models only for sources in the specified region
 bool psphotGuessModel_Unthreaded (pmReadout *readout, psArray *sources, pmPSF *psf, psImageMaskType maskVal, psImageMaskType markVal) {
@@ -301,2 +291,3 @@
     return true;
 }
+# endif
Index: /branches/cnb_branch_20090215/psphot/src/psphotMagnitudes.c
===================================================================
--- /branches/cnb_branch_20090215/psphot/src/psphotMagnitudes.c	(revision 21535)
+++ /branches/cnb_branch_20090215/psphot/src/psphotMagnitudes.c	(revision 21536)
@@ -1,5 +1,3 @@
 # include "psphotInternal.h"
-
-bool psphotMagnitudes_Unthreaded (int *nap, psArray *sources, pmPSF *psf, psImageBinning *binning, pmReadout *backModel, pmReadout *backStdev, pmSourcePhotometryMode photMode, psImageMaskType maskVal);
 
 bool psphotMagnitudes(pmConfig *config, pmReadout *readout, const pmFPAview *view, psArray *sources, pmPSF *psf) {
@@ -59,25 +57,25 @@
 	for (int j = 0; j < cells->n; j++) {
 
-	    if (nThreads) {
-		// allocate a job -- if threads are not defined, this just runs the job
-		psThreadJob *job = psThreadJobAlloc ("PSPHOT_MAGNITUDES");
-
-		psArrayAdd(job->args, 1, cells->data[j]); // sources
-		psArrayAdd(job->args, 1, psf);
-		psArrayAdd(job->args, 1, binning);
-		psArrayAdd(job->args, 1, backModel);
-		psArrayAdd(job->args, 1, backStdev);
-
-		PS_ARRAY_ADD_SCALAR(job->args, photMode, PS_TYPE_S32);
-		PS_ARRAY_ADD_SCALAR(job->args, maskVal,  PS_TYPE_IMAGE_MASK);
-		PS_ARRAY_ADD_SCALAR(job->args, 0,        PS_TYPE_S32); // this is used as a return value for nAp
-
-		if (!psThreadJobAddPending(job)) {
-		    psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
-		    psFree (job);
-		    return false;
-		}
-		psFree(job);
-	    } else {
+	    // allocate a job -- if threads are not defined, this just runs the job
+	    psThreadJob *job = psThreadJobAlloc ("PSPHOT_MAGNITUDES");
+
+	    psArrayAdd(job->args, 1, cells->data[j]); // sources
+	    psArrayAdd(job->args, 1, psf);
+	    psArrayAdd(job->args, 1, binning);
+	    psArrayAdd(job->args, 1, backModel);
+	    psArrayAdd(job->args, 1, backStdev);
+
+	    PS_ARRAY_ADD_SCALAR(job->args, photMode, PS_TYPE_S32);
+	    PS_ARRAY_ADD_SCALAR(job->args, maskVal,  PS_TYPE_IMAGE_MASK);
+	    PS_ARRAY_ADD_SCALAR(job->args, 0,        PS_TYPE_S32); // this is used as a return value for nAp
+
+	    if (!psThreadJobAddPending(job)) {
+		psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
+		psFree (job);
+		return false;
+	    }
+	    psFree(job);
+
+# if (0)
 		int nap = 0;
 		if (!psphotMagnitudes_Unthreaded (&nap, cells->data[j], psf, binning, backModel, backStdev, photMode, maskVal)) {
@@ -86,25 +84,23 @@
 		}
 		Nap += nap;
-	    }
-	}
-
-	if (nThreads) {
-	    // wait for the threads to finish and manage results
-	    if (!psThreadPoolWait (false)) {
-		psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
-		return false;
-	    }
-
-	    // we have only supplied one type of job, so we can assume the types here
-	    psThreadJob *job = NULL;
-	    while ((job = psThreadJobGetDone()) != NULL) {
-		if (job->args->n < 1) {
-		    fprintf (stderr, "error with job\n");
-		} else {
-		    psScalar *scalar = job->args->data[7];
-		    Nap += scalar->data.S32;
-		}
-		psFree(job);
-	    }
+# endif
+	}
+
+	// wait for the threads to finish and manage results
+	if (!psThreadPoolWait (false)) {
+	    psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
+	    return false;
+	}
+
+	// we have only supplied one type of job, so we can assume the types here
+	psThreadJob *job = NULL;
+	while ((job = psThreadJobGetDone()) != NULL) {
+	    if (job->args->n < 1) {
+		fprintf (stderr, "error with job\n");
+	    } else {
+		psScalar *scalar = job->args->data[7];
+		Nap += scalar->data.S32;
+	    }
+	    psFree(job);
 	}
     }
@@ -162,4 +158,5 @@
 }
 
+# if (0)
 bool psphotMagnitudes_Unthreaded (int *nap, psArray *sources, pmPSF *psf, psImageBinning *binning, pmReadout *backModel, pmReadout *backStdev, pmSourcePhotometryMode photMode, psImageMaskType maskVal) {
 
@@ -198,4 +195,5 @@
     return true;
 }
+# endif
 
 bool psphotPSFWeights(pmConfig *config, pmReadout *readout, const pmFPAview *view, psArray *sources) {
@@ -295,5 +293,5 @@
 	}
 
-        status = pmSourcePixelWeight (&source->pixWeight, model, source->pixels, source->maskObj, maskVal);
+        status = pmSourcePixelWeight (&source->pixWeight, model, source->maskObj, maskVal);
 	if (!status) {
 	  psTrace ("psphot", 3, "fail to measure pixel weight");
Index: /branches/cnb_branch_20090215/psphot/src/psphotMergeSources.c
===================================================================
--- /branches/cnb_branch_20090215/psphot/src/psphotMergeSources.c	(revision 21535)
+++ /branches/cnb_branch_20090215/psphot/src/psphotMergeSources.c	(revision 21536)
@@ -122,2 +122,42 @@
     return detections;
 }
+
+// generate the detection structure for the supplied array of sources
+bool psphotSetSourceParams (pmConfig *config, psArray *sources, pmPSF *psf) {
+
+    psMetadata *recipe = psMetadataLookupPtr (NULL, config->recipes, PSPHOT_RECIPE);
+    if (!recipe) {
+        psError(PSPHOT_ERR_CONFIG, false, "missing recipe %s", PSPHOT_RECIPE);
+        return false;
+    }
+
+    for (int i = 0; i < sources->n; i++) {
+        pmSource *source = sources->data[i];
+        pmModel *model = source->modelPSF;
+
+        if (source->mode & PSF_SOURCE_MASK || !isfinite(source->psfMag)) {
+            continue;
+        }
+
+        float flux = powf(10.0, -0.4 * source->psfMag);
+        float xpos = model->params->data.F32[PM_PAR_XPOS];
+        float ypos = model->params->data.F32[PM_PAR_YPOS];
+
+        pmPeak *peak = pmPeakAlloc(xpos, ypos, 1.0, PM_PEAK_LONE);
+        peak->xf = xpos;
+        peak->yf = ypos;
+        peak->flux = flux; // this are being set wrong, but does it matter?
+
+	if (isfinite (source->errMag) && (source->errMag > 0.0)) {
+	  peak->SN = 1.0 / source->errMag; 
+	} else {
+	  peak->SN = 0.0;
+	}
+
+        source->peak = peak;
+    }
+
+    psLogMsg ("psphot", 3, "%ld PSF sources loaded", sources->n);
+
+    return true;
+}
Index: /branches/cnb_branch_20090215/psphot/src/psphotReplaceUnfit.c
===================================================================
--- /branches/cnb_branch_20090215/psphot/src/psphotReplaceUnfit.c	(revision 21535)
+++ /branches/cnb_branch_20090215/psphot/src/psphotReplaceUnfit.c	(revision 21536)
@@ -17,5 +17,5 @@
     replace:
         pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
-        source->mode &= ~PM_SOURCE_MODE_SUBTRACTED;
+        source->tmpFlags &= ~PM_SOURCE_TMPF_SUBTRACTED;
     }
     psLogMsg ("psphot.replace", 3, "replace unfitted models: %f sec (%ld objects)\n", psTimerMark ("psphot.replace"), sources->n);
@@ -38,8 +38,8 @@
 
       // replace other sources?
-      if (!(source->mode & PM_SOURCE_MODE_SUBTRACTED)) continue;
+      if (!(source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED)) continue;
 
       pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
-      source->mode &= ~PM_SOURCE_MODE_SUBTRACTED;
+      source->tmpFlags &= ~PM_SOURCE_TMPF_SUBTRACTED;
     }
     psLogMsg ("psphot.replace", PS_LOG_INFO, "replaced models for %ld objects: %f sec\n", sources->n, psTimerMark ("psphot.replace"));
@@ -62,8 +62,8 @@
 
       // replace other sources?
-      if (source->mode & PM_SOURCE_MODE_SUBTRACTED) continue;
+      if (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED) continue;
 
       pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
-      source->mode |= PM_SOURCE_MODE_SUBTRACTED;
+      source->tmpFlags |= PM_SOURCE_TMPF_SUBTRACTED;
     }
     psLogMsg ("psphot.replace", PS_LOG_INFO, "replaced models for %ld objects: %f sec\n", sources->n, psTimerMark ("psphot.replace"));
@@ -75,5 +75,5 @@
 
     // what is current state? (true : add; false : sub)
-    bool state = !(source->mode & PM_SOURCE_MODE_SUBTRACTED);
+    bool state = !(source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED);
     if (state && useState) return true;
 
@@ -86,5 +86,5 @@
 
     // what is current state? (true : sub; false : add)
-    bool state = (source->mode & PM_SOURCE_MODE_SUBTRACTED);
+    bool state = (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED);
     if (state && useState) return true;
 
@@ -97,5 +97,5 @@
 
     // what is desired state? (true : add; false : sub)
-    bool newState = !(source->mode & PM_SOURCE_MODE_SUBTRACTED);
+    bool newState = !(source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED);
     if (curState == newState) return true;
 
Index: /branches/cnb_branch_20090215/psphot/src/psphotSourceFits.c
===================================================================
--- /branches/cnb_branch_20090215/psphot/src/psphotSourceFits.c	(revision 21535)
+++ /branches/cnb_branch_20090215/psphot/src/psphotSourceFits.c	(revision 21536)
@@ -120,5 +120,6 @@
         pmSourceCacheModel (blend, maskVal);
         pmSourceSub (blend, PM_MODEL_OP_FULL, maskVal);
-        blend->mode |=  PM_SOURCE_MODE_SUBTRACTED;
+        blend->tmpFlags |=  PM_SOURCE_TMPF_SUBTRACTED;
+        blend->mode |=  PM_SOURCE_MODE_BLEND_FIT;
     }
     NfitBlend += modelSet->n;
@@ -143,5 +144,6 @@
     pmSourceCacheModel (source, maskVal);
     pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
-    source->mode |=  PM_SOURCE_MODE_SUBTRACTED;
+    source->tmpFlags |=  PM_SOURCE_TMPF_SUBTRACTED;
+    source->mode |=  PM_SOURCE_MODE_BLEND_FIT;
     return true;
 }
@@ -184,5 +186,5 @@
     pmSourceCacheModel (source, maskVal);
     pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
-    source->mode |=  PM_SOURCE_MODE_SUBTRACTED;
+    source->tmpFlags |=  PM_SOURCE_TMPF_SUBTRACTED;
     return true;
 }
@@ -285,5 +287,5 @@
     pmSourceCacheModel (source, maskVal);
     pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);
-    source->mode |=  PM_SOURCE_MODE_SUBTRACTED;
+    source->tmpFlags |=  PM_SOURCE_TMPF_SUBTRACTED;
     psTrace ("psphot", 5, "blob as EXT: %f %f\n", EXT->params->data.F32[PM_PAR_XPOS], EXT->params->data.F32[PM_PAR_YPOS]);
     return true;
@@ -296,6 +298,6 @@
     psFree (source->modelPSF);
     source->modelPSF = psMemIncrRefCounter (DBL->data[0]);
-    source->mode    |= PM_SOURCE_MODE_SUBTRACTED;
-    source->mode    |= PM_SOURCE_MODE_PAIR;
+    source->tmpFlags |= PM_SOURCE_TMPF_SUBTRACTED;
+    source->mode     |= PM_SOURCE_MODE_PAIR;
 
     // copy most data from the primary source (modelEXT, blends stay NULL)
Index: /branches/cnb_branch_20090215/psphot/src/psphotSourceSize.c
===================================================================
--- /branches/cnb_branch_20090215/psphot/src/psphotSourceSize.c	(revision 21535)
+++ /branches/cnb_branch_20090215/psphot/src/psphotSourceSize.c	(revision 21536)
@@ -56,5 +56,6 @@
 
         // source must have been subtracted
-        if (!(source->mode & PM_SOURCE_MODE_SUBTRACTED)) {
+        if (!(source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED)) {
+	    source->mode |= PM_SOURCE_MODE_SIZE_SKIPPED;
             psTrace("psphot", 7, "Not calculating extNsigma,crNsigma since source is not subtracted\n");
             continue;
@@ -63,5 +64,5 @@
         psF32 **resid  = source->pixels->data.F32;
         psF32 **variance = source->variance->data.F32;
-        psImageMaskType **mask    = source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA;
+        psImageMaskType **mask = source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA;
 
         // check for extendedness: measure the delta flux significance at the 1 sigma contour
@@ -82,4 +83,5 @@
         if (xPeak < 1 || xPeak > source->pixels->numCols - 2 ||
             yPeak < 1 || yPeak > source->pixels->numRows - 2) {
+	    source->mode |= PM_SOURCE_MODE_SIZE_SKIPPED;
             psTrace("psphot", 7, "Not calculating crNsigma due to edge\n");
             continue;
@@ -98,4 +100,5 @@
         if (!keep) {
             psTrace("psphot", 7, "Not calculating crNsigma due to masked pixels\n");
+	    source->mode |= PM_SOURCE_MODE_SIZE_SKIPPED;
             continue;
         }
@@ -156,5 +159,7 @@
         }
         source->crNsigma  = (nCR > 0)  ? fCR / nCR : 0.0;
-        if (!isfinite(source->crNsigma)) continue;
+        if (!isfinite(source->crNsigma)) {
+	    continue;
+	}
 
         // this source is thought to be a cosmic ray.  flag the detection and mask the pixels
@@ -264,5 +269,5 @@
     // replace the source flux
     pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);
-    source->mode &= ~PM_SOURCE_MODE_SUBTRACTED;
+    source->tmpFlags &= ~PM_SOURCE_TMPF_SUBTRACTED;
 
     // flag this as a CR
Index: /branches/cnb_branch_20090215/psphot/src/psphotSourceStats.c
===================================================================
--- /branches/cnb_branch_20090215/psphot/src/psphotSourceStats.c	(revision 21535)
+++ /branches/cnb_branch_20090215/psphot/src/psphotSourceStats.c	(revision 21536)
@@ -1,5 +1,3 @@
 # include "psphotInternal.h"
-
-bool psphotSourceStats_Unthreaded (int *nfail, int *nmoments, psArray *sources, psMetadata *recipe);
 
 psArray *psphotSourceStats (pmConfig *config, pmReadout *readout, pmDetections *detections) {
@@ -80,20 +78,20 @@
 	for (int j = 0; j < cells->n; j++) {
 
-	    if (nThreads) {
-		// allocate a job -- if threads are not defined, this just runs the job
-		psThreadJob *job = psThreadJobAlloc ("PSPHOT_SOURCE_STATS");
-
-		psArrayAdd(job->args, 1, cells->data[j]); // sources
-		psArrayAdd(job->args, 1, recipe);
-		PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Nmoments
-		PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Nfail
-
-		if (!psThreadJobAddPending(job)) {
-		    psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
-		    psFree (job);
-		    return NULL;
-		}
-		psFree(job);
-	    } else {
+	    // allocate a job -- if threads are not defined, this just runs the job
+	    psThreadJob *job = psThreadJobAlloc ("PSPHOT_SOURCE_STATS");
+
+	    psArrayAdd(job->args, 1, cells->data[j]); // sources
+	    psArrayAdd(job->args, 1, recipe);
+	    PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Nmoments
+	    PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Nfail
+
+	    if (!psThreadJobAddPending(job)) {
+		psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
+		psFree (job);
+		return NULL;
+	    }
+	    psFree(job);
+
+# if (0)
 		int nfail = 0;
 		int nmoments = 0;
@@ -104,28 +102,26 @@
 		Nfail += nfail;
 		Nmoments += nmoments;
+# endif
+	}
+
+	// wait for the threads to finish and manage results
+	if (!psThreadPoolWait (false)) {
+	    psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
+	    return NULL;
+	}
+
+	// we have only supplied one type of job, so we can assume the types here
+	psThreadJob *job = NULL;
+	while ((job = psThreadJobGetDone()) != NULL) {
+	    if (job->args->n < 1) {
+		fprintf (stderr, "error with job\n");
+	    } else {
+		psScalar *scalar = NULL;
+		scalar = job->args->data[2];
+		Nmoments += scalar->data.S32;
+		scalar = job->args->data[3];
+		Nfail += scalar->data.S32;
 	    }
-	}
-
-	if (nThreads) {
-	    // wait for the threads to finish and manage results
-	    if (!psThreadPoolWait (false)) {
-		psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
-		return NULL;
-	    }
-
-	    // we have only supplied one type of job, so we can assume the types here
-	    psThreadJob *job = NULL;
-	    while ((job = psThreadJobGetDone()) != NULL) {
-		if (job->args->n < 1) {
-		    fprintf (stderr, "error with job\n");
-		} else {
-		    psScalar *scalar = NULL;
-		    scalar = job->args->data[2];
-		    Nmoments += scalar->data.S32;
-		    scalar = job->args->data[3];
-		    Nfail += scalar->data.S32;
-		}
-		psFree(job);
-	    }
+	    psFree(job);
 	}
     }
@@ -148,4 +144,94 @@
     psArray *sources                = job->args->data[0];
     psMetadata *recipe              = job->args->data[1];
+
+    float INNER    = psMetadataLookupF32 (&status, recipe, "SKY_INNER_RADIUS");
+    if (!status) return false;
+    float MIN_SN   = psMetadataLookupF32 (&status, recipe, "MOMENTS_SN_MIN");
+    if (!status) return false;
+    float RADIUS   = psMetadataLookupF32 (&status, recipe, "PSF_MOMENTS_RADIUS");
+    if (!status) return false;
+
+    // bit-masks to test for good/bad pixels
+    psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT");
+    assert (maskVal);
+
+    // bit-mask to mark pixels not used in analysis
+    psImageMaskType markVal = psMetadataLookupImageMask(&status, recipe, "MARK.PSPHOT");
+    assert (markVal);
+
+    // maskVal is used to test for rejected pixels, and must include markVal
+    maskVal |= markVal;
+
+    // threaded measurement of the sources moments
+    int Nfail = 0;
+    int Nmoments = 0;
+    for (int i = 0; i < sources->n; i++) {
+        pmSource *source = sources->data[i];
+
+        // skip faint sources for moments measurement
+        if (source->peak->SN < MIN_SN) {
+	    source->mode |= PM_SOURCE_MODE_BELOW_MOMENTS_SN;
+            continue;
+        }
+
+        // measure a local sky value
+        // the local sky is now ignored; kept here for reference only
+        status = pmSourceLocalSky (source, PS_STAT_SAMPLE_MEDIAN, INNER, maskVal, markVal);
+        if (!status) {
+	    source->mode |= PM_SOURCE_MODE_SKY_FAILURE;
+	    psErrorClear(); // XXX re-consider the errors raised here
+	    Nfail ++;
+	    continue;
+        }
+
+        // measure the local sky variance (needed if noise is not sqrt(signal))
+        // XXX EAM : this should use ROBUST not SAMPLE median, but it is broken
+        status = pmSourceLocalSkyVariance (source, PS_STAT_SAMPLE_MEDIAN, INNER, maskVal, markVal);
+        if (!status) {
+	    source->mode |= PM_SOURCE_MODE_SKYVAR_FAILURE;
+	    Nfail ++;
+	    psErrorClear();
+	    continue;
+        }
+
+        // measure basic source moments
+        status = pmSourceMoments (source, RADIUS);
+        if (status) {
+            Nmoments ++;
+            continue;
+        }
+
+        // if no valid pixels, or massive swing, likely saturated source,
+        // try a much larger box
+        BIG_RADIUS = PS_MIN (INNER, 3*RADIUS);
+        psTrace ("psphot", 4, "retrying moments for %d, %d\n", source->peak->x, source->peak->y);
+        status = pmSourceMoments (source, BIG_RADIUS);
+        if (status) {
+	    source->mode |= PM_SOURCE_MODE_BIG_RADIUS;
+            Nmoments ++;
+            continue;
+        }
+
+	source->mode |= PM_SOURCE_MODE_MOMENTS_FAILURE;
+        Nfail ++;
+        psErrorClear();
+        continue;
+    }
+
+    // change the value of a scalar on the array (wrap this and put it in psArray.h)
+    scalar = job->args->data[2];
+    scalar->data.S32 = Nmoments;
+
+    scalar = job->args->data[3];
+    scalar->data.S32 = Nfail;
+    
+    return true;
+}
+
+# if (0)
+bool psphotSourceStats_Unthreaded (int *nfail, int *nmoments, psArray *sources, psMetadata *recipe) {
+
+    bool status = false;
+    float BIG_RADIUS;
 
     float INNER    = psMetadataLookupF32 (&status, recipe, "SKY_INNER_RADIUS");
@@ -219,88 +305,4 @@
 
     // change the value of a scalar on the array (wrap this and put it in psArray.h)
-    scalar = job->args->data[2];
-    scalar->data.S32 = Nmoments;
-
-    scalar = job->args->data[3];
-    scalar->data.S32 = Nfail;
-    
-    return true;
-}
-
-bool psphotSourceStats_Unthreaded (int *nfail, int *nmoments, psArray *sources, psMetadata *recipe) {
-
-    bool status = false;
-    float BIG_RADIUS;
-
-    float INNER    = psMetadataLookupF32 (&status, recipe, "SKY_INNER_RADIUS");
-    if (!status) return false;
-    float MIN_SN   = psMetadataLookupF32 (&status, recipe, "MOMENTS_SN_MIN");
-    if (!status) return false;
-    float RADIUS   = psMetadataLookupF32 (&status, recipe, "PSF_MOMENTS_RADIUS");
-    if (!status) return false;
-
-    // bit-masks to test for good/bad pixels
-    psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT");
-    assert (maskVal);
-
-    // bit-mask to mark pixels not used in analysis
-    psImageMaskType markVal = psMetadataLookupImageMask(&status, recipe, "MARK.PSPHOT");
-    assert (markVal);
-
-    // maskVal is used to test for rejected pixels, and must include markVal
-    maskVal |= markVal;
-
-    // threaded measurement of the sources moments
-    int Nfail = 0;
-    int Nmoments = 0;
-    for (int i = 0; i < sources->n; i++) {
-        pmSource *source = sources->data[i];
-
-        // skip faint sources for moments measurement
-        if (source->peak->SN < MIN_SN) {
-            continue;
-        }
-
-        // measure a local sky value
-        // the local sky is now ignored; kept here for reference only
-        status = pmSourceLocalSky (source, PS_STAT_SAMPLE_MEDIAN, INNER, maskVal, markVal);
-        if (!status) {
-	    psErrorClear(); // XXX re-consider the errors raised here
-	    Nfail ++;
-	    continue;
-        }
-
-        // measure the local sky variance (needed if noise is not sqrt(signal))
-        // XXX EAM : this should use ROBUST not SAMPLE median, but it is broken
-        status = pmSourceLocalSkyVariance (source, PS_STAT_SAMPLE_MEDIAN, INNER, maskVal, markVal);
-        if (!status) {
-	    Nfail ++;
-	    psErrorClear();
-	    continue;
-        }
-
-        // measure basic source moments
-        status = pmSourceMoments (source, RADIUS);
-        if (status) {
-            Nmoments ++;
-            continue;
-        }
-
-        // if no valid pixels, or massive swing, likely saturated source,
-        // try a much larger box
-        BIG_RADIUS = PS_MIN (INNER, 3*RADIUS);
-        psTrace ("psphot", 4, "retrying moments for %d, %d\n", source->peak->x, source->peak->y);
-        status = pmSourceMoments (source, BIG_RADIUS);
-        if (status) {
-            Nmoments ++;
-            continue;
-        }
-
-        Nfail ++;
-        psErrorClear();
-        continue;
-    }
-
-    // change the value of a scalar on the array (wrap this and put it in psArray.h)
     *nmoments = Nmoments;
     *nfail = Nfail;
@@ -308,2 +310,3 @@
     return true;
 }
+# endif 
Index: /branches/cnb_branch_20090215/psphot/src/psphotVisual.c
===================================================================
--- /branches/cnb_branch_20090215/psphot/src/psphotVisual.c	(revision 21535)
+++ /branches/cnb_branch_20090215/psphot/src/psphotVisual.c	(revision 21536)
@@ -18,14 +18,8 @@
 // these are invoked by the -visual options
 
-static bool isVisual = false;
 static int kapa = -1;
 static int kapa2 = -1;
 static int kapa3 = -1;
 
-bool psphotSetVisual (bool mode) {
-
-    isVisual = mode;
-    return true;
-}
 
 bool psphotVisualShowMask (int kapaFD, psImage *inImage, const char *name, int channel) {
@@ -135,5 +129,5 @@
 bool psphotVisualShowImage (pmReadout *readout) {
 
-    if (!isVisual) return true;
+    if (!pmVisualIsVisual()) return true;
 
     if (kapa == -1) {
@@ -141,5 +135,5 @@
         if (kapa == -1) {
             fprintf (stderr, "failure to open kapa; visual mode disabled\n");
-            isVisual = false;
+            pmVisualSetVisual(false);
             return false;
         }
@@ -164,5 +158,5 @@
     pmReadout *backgnd;
 
-    if (!isVisual) return true;
+    if (!pmVisualIsVisual()) return true;
 
     if (kapa == -1) {
@@ -170,5 +164,5 @@
         if (kapa == -1) {
             fprintf (stderr, "failure to open kapa; visual mode disabled\n");
-            isVisual = false;
+            pmVisualSetVisual(false);
             return false;
         }
@@ -199,5 +193,5 @@
 bool psphotVisualShowSignificance (psImage *image) {
 
-    if (!isVisual) return true;
+    if (!pmVisualIsVisual()) return true;
 
     if (kapa == -1) {
@@ -205,5 +199,5 @@
         if (kapa == -1) {
             fprintf (stderr, "failure to open kapa; visual mode disabled\n");
-            isVisual = false;
+            pmVisualSetVisual(false);
             return false;
         }
@@ -228,5 +222,5 @@
     KiiOverlay *overlay;
 
-    if (!isVisual) return true;
+    if (!pmVisualIsVisual()) return true;
 
     if (kapa == -1) {
@@ -306,5 +300,5 @@
     KiiOverlay *overlay;
 
-    if (!isVisual) return true;
+    if (!pmVisualIsVisual()) return true;
 
     if (kapa == -1) {
@@ -423,5 +417,5 @@
     psEllipseAxes axes;
 
-    if (!isVisual) return true;
+    if (!pmVisualIsVisual()) return true;
 
     if (kapa == -1) {
@@ -478,5 +472,5 @@
     Graphdata graphdata;
 
-    if (!isVisual) return true;
+    if (!pmVisualIsVisual()) return true;
 
     if (kapa3 == -1) {
@@ -484,5 +478,5 @@
         if (kapa3 == -1) {
             fprintf (stderr, "failure to open kapa; visual mode disabled\n");
-            isVisual = false;
+            pmVisualSetVisual(false);
             return false;
         }
@@ -694,5 +688,5 @@
 bool psphotVisualShowRoughClass (psArray *sources) {
 
-    if (!isVisual) return true;
+    if (!pmVisualIsVisual()) return true;
 
     if (kapa == -1) {
@@ -723,5 +717,5 @@
 bool psphotVisualShowPSFModel (pmReadout *readout, pmPSF *psf) {
 
-    if (!isVisual) return true;
+    if (!pmVisualIsVisual()) return true;
 
     if (kapa2 == -1) {
@@ -729,5 +723,5 @@
         if (kapa2 == -1) {
             fprintf (stderr, "failure to open kapa; visual mode disabled\n");
-            isVisual = false;
+            pmVisualSetVisual(false);
             return false;
         }
@@ -801,5 +795,5 @@
     bool status;
 
-    if (!isVisual) return true;
+    if (!pmVisualIsVisual()) return true;
 
     if (kapa2 == -1) {
@@ -807,5 +801,5 @@
         if (kapa2 == -1) {
             fprintf (stderr, "failure to open kapa; visual mode disabled\n");
-            isVisual = false;
+            pmVisualSetVisual(false);
             return false;
         }
@@ -961,5 +955,5 @@
     bool status;
 
-    if (!isVisual) return true;
+    if (!pmVisualIsVisual()) return true;
 
     if (kapa2 == -1) {
@@ -967,5 +961,5 @@
         if (kapa2 == -1) {
             fprintf (stderr, "failure to open kapa; visual mode disabled\n");
-            isVisual = false;
+            pmVisualSetVisual(false);
             return false;
         }
@@ -1101,5 +1095,5 @@
     Graphdata graphdata;
 
-    bool state = !(source->mode & PM_SOURCE_MODE_SUBTRACTED);
+    bool state = !(source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED);
     psphotAddWithTest (source, true, maskVal); // replace source if subtracted
 
@@ -1214,5 +1208,5 @@
     KapaSection section;  // put the positive profile in one and the residuals in another?
 
-    if (!isVisual) return true;
+    if (!pmVisualIsVisual()) return true;
 
     if (kapa3 == -1) {
@@ -1220,5 +1214,5 @@
         if (kapa3 == -1) {
             fprintf (stderr, "failure to open kapa; visual mode disabled\n");
-            isVisual = false;
+            pmVisualSetVisual(false);
             return false;
         }
@@ -1286,5 +1280,5 @@
     psEllipseAxes axes;
 
-    if (!isVisual) return true;
+    if (!pmVisualIsVisual()) return true;
 
     if (kapa == -1) {
@@ -1387,5 +1381,5 @@
     KiiOverlay *overlay;
 
-    if (!isVisual) return true;
+    if (!pmVisualIsVisual()) return true;
 
     if (kapa == -1) {
@@ -1464,5 +1458,5 @@
     KapaSection section;
 
-    if (!isVisual) return true;
+    if (!pmVisualIsVisual()) return true;
 
     if (kapa3 == -1) {
@@ -1470,5 +1464,5 @@
         if (kapa3 == -1) {
             fprintf (stderr, "failure to open kapa; visual mode disabled\n");
-            isVisual = false;
+            pmVisualSetVisual(false);
             return false;
         }
@@ -1604,5 +1598,5 @@
 bool psphotVisualShowResidualImage (pmReadout *readout) {
 
-    if (!isVisual) return true;
+    if (!pmVisualIsVisual()) return true;
 
     if (kapa == -1) {
@@ -1610,5 +1604,5 @@
         if (kapa == -1) {
             fprintf (stderr, "failure to open kapa; visual mode disabled\n");
-            isVisual = false;
+            pmVisualSetVisual(false);
             return false;
         }
@@ -1631,5 +1625,5 @@
     Graphdata graphdata;
 
-    if (!isVisual) return true;
+    if (!pmVisualIsVisual()) return true;
 
     if (kapa3 == -1) {
@@ -1637,5 +1631,5 @@
         if (kapa3 == -1) {
             fprintf (stderr, "failure to open kapa; visual mode disabled\n");
-            isVisual = false;
+            pmVisualSetVisual(false);
             return false;
         }
@@ -1712,5 +1706,4 @@
 # else
 
-bool psphotSetVisual (bool mode){}
 bool psphotVisualShowImage (pmConfig *config, pmReadout *readout) { return true; }
 bool psphotVisualShowBackground (pmConfig *config, const pmFPAview *view, pmReadout *readout) { return true; }
Index: /branches/cnb_branch_20090215/pswarp/src/pswarpArguments.c
===================================================================
--- /branches/cnb_branch_20090215/pswarp/src/pswarpArguments.c	(revision 21535)
+++ /branches/cnb_branch_20090215/pswarp/src/pswarpArguments.c	(revision 21536)
@@ -6,6 +6,6 @@
  *
  *  @author IfA
- *  @version $Revision: 1.24 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2009-02-06 03:10:36 $
+ *  @version $Revision: 1.24.2.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-19 17:59:50 $
  *  Copyright 2009 Institute for Astronomy, University of Hawaii
  */
@@ -39,7 +39,7 @@
     {
         int arg;                        ///< Argument Number
-        if ((arg = psArgumentGet(argc, argv, "-psphot-visual"))) {
+        if ((arg = psArgumentGet(argc, argv, "-visual"))) {
             psArgumentRemove(arg, &argc, argv);
-            psphotSetVisual(true);
+            pmVisualSetVisual(true);
         }
     }
