Index: /trunk/Ohana/src/addstar/Makefile
===================================================================
--- /trunk/Ohana/src/addstar/Makefile	(revision 16809)
+++ /trunk/Ohana/src/addstar/Makefile	(revision 16810)
@@ -13,5 +13,5 @@
 
 # programs may add their own internal requirements here
-FULL_CFLAGS   = $(BASE_CFLAGS)
+FULL_CFLAGS   = $(BASE_CFLAGS) -Wall -Werror
 FULL_CPPFLAGS = $(BASE_CPPFLAGS)
 FULL_LDFLAGS  = -lkapa -ldvo -lFITS -lohana $(BASE_LDFLAGS)
@@ -59,4 +59,8 @@
 $(SRC)/grefstars.$(ARCH).o \
 $(SRC)/LoadStars.$(ARCH).o \
+$(SRC)/LoadHeaders.$(ARCH).o \
+$(SRC)/MatchHeaders.$(ARCH).o \
+$(SRC)/LoadData.$(ARCH).o \
+$(SRC)/LoadDataSDSS.$(ARCH).o \
 $(SRC)/in_image.$(ARCH).o \
 $(SRC)/load_subpix.$(ARCH).o \
@@ -67,8 +71,10 @@
 $(SRC)/ReadStarsFITS.$(ARCH).o \
 $(SRC)/ReadStarsTEXT.$(ARCH).o \
+$(SRC)/ReadStarsSDSS.$(ARCH).o \
 $(SRC)/FilterStars.$(ARCH).o \
 $(SRC)/ImageOptions.$(ARCH).o \
 $(SRC)/GetFileMode.$(ARCH).o \
 $(SRC)/ReadImageHeader.$(ARCH).o \
+$(SRC)/UpdateImageIDs.$(ARCH).o \
 $(SRC)/update_coords.$(ARCH).o
 
@@ -165,4 +171,8 @@
 $(SRC)/ConfigInit.$(ARCH).o \
 $(SRC)/LoadStars.$(ARCH).o \
+$(SRC)/LoadHeaders.$(ARCH).o \
+$(SRC)/MatchHeaders.$(ARCH).o \
+$(SRC)/LoadData.$(ARCH).o \
+$(SRC)/LoadDataSDSS.$(ARCH).o \
 $(SRC)/grefstars.$(ARCH).o \
 $(SRC)/load_subpix.$(ARCH).o \
@@ -172,4 +182,6 @@
 $(SRC)/ReadImageHeader.$(ARCH).o \
 $(SRC)/ReadStarsTEXT.$(ARCH).o \
+$(SRC)/ReadStarsSDSS.$(ARCH).o \
+$(SRC)/UpdateImageIDs.$(ARCH).o \
 $(SRC)/FilterStars.$(ARCH).o \
 $(SRC)/Shutdown.$(ARCH).o \
@@ -189,4 +201,5 @@
 $(SRC)/load2mass_catalog.$(ARCH).o \
 $(SRC)/get2mass_ops.$(ARCH).o \
+$(SRC)/get2mass_full.$(ARCH).o \
 $(SRC)/find_matches_refstars.$(ARCH).o \
 $(SRC)/args_load2mass.$(ARCH).o \
Index: /trunk/Ohana/src/addstar/doc/2mass.txt
===================================================================
--- /trunk/Ohana/src/addstar/doc/2mass.txt	(revision 16810)
+++ /trunk/Ohana/src/addstar/doc/2mass.txt	(revision 16810)
@@ -0,0 +1,115 @@
+
+2MASS PSC fields:
+
+ra, dec : obvious
+
+err_maj, err_min, err_ang : I only have ra_err and dec_err.  should I upgrade my tables?
+(put these in FHx, FWy, theta)
+
+designation (2mass ID) : ignore this?  potentially derivable from position
+
+j_m -> M
+j_cmsig -> dM
+j_msigcom : I don't yet have a systematic error term; add this in
+j_snr : another way of representing the error : the implied error is the MODE of dM for the scan
+
+(repeat for h, k)
+
+ph_qual[j] : using letters to represent 8 states: (3bit needed)
+
+0x0000 * "X" - There is a detection at this location, but no valid brightness estimate can be extracted using any algorithm. rd_flg="9" and default magnitude is null.
+0x0001 * "U" - Upper limit on magnitude. Source is not detected in this band (rd_flg="0"), or it is detected, but not resolved in a consistent fashion with other bands (rd_flg="6"). A value of ph_qual="U" does not necessarily mean that there is no flux detected in this band at the location. Whether or not flux has been detected can be determined from the value of rd_flg. When rd_flg="0", no flux has been detected. When rd_flg="6", flux has been detected at the location where the images were not deblended consistently in all three bands (JHKs).
+0x0002 * "F" - This category includes rd_flg="1" or rd_flg="3" sources where a reliable estimate of the photometric error, [jhk]_cmsig, could not be determined. The uncertainties reported for these sources in [jhk]_cmsig and [jhk]_msigcom are flags and have numeric values >8.0.
+0x0003 * "E" - This category includes detections where the goodness-of-fit quality of the profile-fit photometry was very poor (rd_flg=2 and [jhk]psf_chi>10.0), or detections where psf fit photometry did not converge and an aperture magnitude is reported (rd_flg=4), or detections where the number of frames was too small in relation to the number of frames in which a detection was geometrically possible (rd_flg="1" or rd_flg="2").
+0x0004 * "A" - Detections in any brightness regime where valid measurements were made (rd_flg="1","2" or "3") with [jhk]_snr>10 AND [jhk]_cmsig<0.10857.
+0x0005 * "B" - Detections in any brightness regime where valid measurements were made (rd_flg="1","2" or "3") with [jhk]_snr>7 AND [jhk]_cmsig<0.15510.
+0x0006 * "C" - Detections in any brightness regime where valid measurements were made (rd_flg="1","2" or "3") with [jhk]_snr>5 AND [jhk]_cmsig<0.21714.
+0x0007 * "D" - Detections in any brightness regime where valid measurements were made (rd_flg="1","2" or "3") with no [jhk]_snr or [jhk]_cmsig requirement.
+
+rd_flag[j] : using numbers to represent 7 states:
+
+0x0000 * "0" - Source is not detected in this band. The default magnitude is the 95% confidence upper limit derived from a 4" radius aperture measurement taken at the position of the source on the Atlas Image. The sky background is estimated in an annular region with inner radius of 14" and outer radius of 20".
+0x0010 * "1" - The default magnitude is derived from aperture photometry measurements on the 51 ms "Read_1" exposures. The aperture radius is 4", with the sky background measured in an annulus with an inner radius of 14" and an outer radius of 20". Used for sources that saturate one or more of the 1.3s "Read_2" exposures, but are not saturated on at least one of the 51 ms "Read_1" frames.
+0x0020 * "2" - The default magnitude is derived from a profile-fitting measurement made on the 1.3 sec "Read_2" exposures. The profile-fit magnitudes are normalized to curve-of-growth-corrected aperture magnitudes. This is the most common type in the PSC, and is used for sources that have no saturated pixels in any of the 1.3 sec exposures.
+0x0030 * "3" - The default magnitude is derived from a 1-d radial profile fitting measurement made on the 51 ms "Read_1" exposures. Used for very bright sources that saturate all of the 51 ms "Read 1" exposures.
+0x0040 * "4" - The default magnitude is derived from curve-of-growth-corrected 4" radius aperture photometry measurements on the 1.3 s "Read_2" exposures. This is used for sources that are not saturated in any of the Read_2 frames, but where the profile-fitting measurements fail to converge to a solution. These magnitudes are the same as the standard aperture magnitudes (j_m_stdap, h_m_stdap, k_m_stdap), but when they are the default magnitudes, it generally implies that they are low quality measurements.
+0x0050 * "6" - The default magnitude is the 95% confidence upper limit derived from a 4" radius aperture measurement taken at the position of the source on the Atlas Image. The sky background is estimated in an annular region with inner radius of 14" and outer radius of 20". This is used for pairs of sources which are detected and resolved in another band, but are detected and not resolved in this band. This differs from a rd_flg="0" because in this case there is a detection of the source in this band, but it is not consistently resolved across all bands.
+0x0060 * "9" - The default magnitude is the 95% confidence upper limit derived from a 4" radius aperture measurement taken at the position of the source on the Atlas Image. The sky background is estimated in an annular region with inner radius of 14" and outer radius of 20". This is used for sources that were nominally detected in this band, but which could not have a useful brightness measurement from either profile fitting or aperture photometry. This often occurs in highly confused regions, or very near Tile edges where a significant fraction of the measurement aperture of sky annulus falls off the focal plane.
+
+bl_flag[j] : 3 states:
+
+    * "0" - Source is not detected, or is inconsistently deblended in that band.
+    * "1" - One component was fit to the source in R_2 profile-fitting photometry (rd_flg="2"), or default magnitudes are from aperture photometry (rd_flg="1" or "4") or saturated star 1-d radial profile-fitting (rd_flg="3").
+    * ">1" - More than one component was fit simultaneously during R2 profile-fit photometry, where the value of the field is the number of components simultaneously fit. The maximum number of components is 7 in any band for the PSC, so this bl_flg is always a three character flag. Multi-component fitting occurs only for profile-fitting, and only when more than one detection is found within ~5". Single detections that are not well-fit by a single PSF are not split.
+
+cc_flag[j] : 6 states:
+
+    * "p" = Persistence. Source may be contaminated by a latent image left by a nearby bright star.
+    * "c" = Photometric Confusion. Source photometry is biased by a nearby star that has contaminated the background estimation. This is very common in high source density regions.
+    * "d" = Diffraction spike confusion. Source may be contaminated by a diffraction spike from a nearby star.
+    * "s" = Electronic stripe. Source measurement may be contaminated by a stripe from a nearby bright star.
+    * "b" = Bandmerge confusion. In the process of merging detections in the different bands for this source, there was more than one possible match between the different band components. This occurs in regions of very high source density, or when multiple sources were split in one band but not another.
+    * "0" = Source is unaffected by known artifacts, or is not detected in the band.
+
+ndet : number of frames detected, number of frames available (carry this somehow?)
+
+prox : distance to nearest neighbor (unneeded)
+pxpa : direction to nearest neighbor (unneeded)
+pxcntr : id of nearest neighbor
+
+gal_contam : is source close to or part of an extended source? (3 states)
+
+mp_flg : associated with know Solar System object
+
+pts_key/cntr : 2MASS internal object ID
+
+hemis : (which observatory -- replace with a photcode?)
+
+date -> ignore (not accurate)
+
+scan : scan in which it was detected (unneeded)
+
+glon, glat : derivable
+
+x_scan : pixel location in x direction -> Xccd
+
+jdate : time stamp with ~30 sec accuracy
+
+j_psfchi : fit chi sqare -> psfProb (needs to be changed in measure.d anyway)
+
+j_m_stdap : aperture magnitude -> Mgal (change to Map anyway)
+
+j_msig_stdap : aperture magnitude error (keep ??)
+
+dist_edge_ns, ew, flg : information about distance to scan edge (ns or ew)
+
+dup_src : duplicate scan 
+use_src : ??
+
+(ignore the fields for cross-correlation with other surveys)
+
+counting the flag bits (no attempt to account for any duplicate info; ignoring dist_edge info):
+
+ph_qual	   : 3 bits
+rd_flag	   : 3 bits
+bl_flag	   : 2 bits 
+cc_flag	   : 3 bits
+gal_contam : 2 bits
+mp_flag	   : 1 bit
+dup_src	   : 1 bit
+use_src	   : 1 bit
+
+total      : 17 bit (1 too many...)
+
+counting the flag bits (trying to minimize duplicate info; ignoring dist_edge info):
+
+ph_qual	   : 3 bits 0x0001 - 0x0007
+bl_flag	   : 1 bit  0x0008 (bl_flag = 0 or 1 -> 0; bl_flag > 1 -> 1)
+rd_flag	   : 3 bits 0x0010 - 0x0070
+gal_contam : 1 bit  0x0080 (gal_contam = 0 or 1 -> 0; gal_contam = 2 -> 1) (set extNsigma to a high value if gal_contam = 1) 
+cc_flag	   : 3 bits 0x0100 - 0x0700
+mp_flag	   : 1 bit  0x0800
+dup_src	   : 1 bit  0x1000 (0 or 1 -> 0; > 1 -> 1)
+use_src	   : 1 bit  0x2000 
+
+total      : 14 bits
Index: /trunk/Ohana/src/addstar/doc/notes.txt
===================================================================
--- /trunk/Ohana/src/addstar/doc/notes.txt	(revision 16809)
+++ /trunk/Ohana/src/addstar/doc/notes.txt	(revision 16810)
@@ -1,2 +1,32 @@
+
+2008.02.23
+
+  features I need to add / finish in dvo:
+
+  * detID / objID / imageID
+
+    some questions:
+
+      db_id
+      table_id (chip / warp / stack / diff)
+      chip_id / warp_id / stack_id / diff_id
+      
+      detections from stand-alone analysis would require an alternate sequence?
+      detections without an associated image get image_id = 0
+      
+    * imageID : we will define a new, unique running ID within dvo
+      against which joins are performed.  in addition, I will keep the
+      externally supplied ids as a reference (32bit id + 16bit source)
+
+    * detID : the detection (measure) should carry the imageID + detID as a
+      unique value. 
+
+    * objID : objects will get a unique ID when they are created
+      (sequence in table + table ID? or use the same bits as Maria?)
+
+  * extended measurement tables
+  * SDSS ingest
+  * 2MASS flags
+  
 
 2008.01.31
Index: /trunk/Ohana/src/addstar/doc/sdss-tsObj.txt
===================================================================
--- /trunk/Ohana/src/addstar/doc/sdss-tsObj.txt	(revision 16810)
+++ /trunk/Ohana/src/addstar/doc/sdss-tsObj.txt	(revision 16810)
@@ -0,0 +1,686 @@
+.
+  Calibrated Objects
+
+*File Format:* FITS binary table
+
+*Name:* /tsObj-rrrrrr-c-v-ffff.fit/, where /rrrrrr/ is the imaging run
+number, /c/ is the camera column (1-6), and /v/ is the rerun number and
+ffff is the first field number of the segment.
+
+*Produced by:* ts
+
+*Used by:* ts, sx
+
+*Size:* 7 * 2880 + (2240 * Nstars) {rounded up to nearest multiple of
+2880) * Nfields. For a single pipeline run with 1000 fields, 400 objects
+per field, 887.06 Mb.
+
+*Archived?* Yes, by sx.
+
+
+    Description
+
+Calibrated version of the object lists put out by the /frames/ pipeline.
+
+
+    Primary Header
+
+SIMPLE  =                    T
+BITPIX  =                    8
+NAXIS   =                    0
+EXTEND  =                    T
+RUN     =                  XXX / Imaging run number.
+CAMCOL  =                  XXX / Column in the imaging camera.
+RERUN   =                  XXX / Rerun number
+FIELD0  =                  XXX / First field reduced.
+NFIELDS =                  XXX / Number of fields reduced.
+STRIPE  =                  XXX / Stripe number
+STRIP   = 'X       '           / N - north, S - south
+EQUINOX =          XXXX.XXXXXX / Equinox of great circle scanned (Julian years)
+NODE    =           XXX.XXXXXX / Ascending node of great circle scanned (deg)
+INCL    =           XXX.XXXXXX / Inclincation of great circle scanned (deg)
+C_OBS   =            XXXXX.XXX / CCD clock rate (usec/unbinned-row)
+TRACKING=            XXXXX.XXX / Tracking rate (arcsec/TAI-sec)
+PHOTO_ID= 'XXX     '           / Photometric pipeline run id.
+TASTR_ID= 'XXX     '           / Astrometric pipeline run id for target.
+EASTR_ID= 'XXX     '           / Astrometric pipeline run id for export.
+TFCAL_ID= 'XXX     '           / Photometric calibration run id for target.
+EFCAL_ID= 'XXX     '           / Photometric calibration run id for export.
+PHOT_VER= 'XXX     '           / Version of frames pipeline used.
+TAST_VER= 'XXX     '           / Version of astrometric pipeline for target.
+EAST_VER= 'XXX     '           / Version of astrometric pipeline for export.
+TFCA_VER= 'XXX     '           / Version of fcalib for target.
+EFCA_VER= 'XXX     '           / Version of fcalib for export.
+TARG_VER= 'XXX     '           / Version of target pipeline used.
+EXPO_VER= 'XXX     '           / Version of export pipeline used.
+FILTERS = 'XXX XXX ...'        / Filter order in array fields
+OBJ_SRC = 'XXX     '           / Source of objects:
+COMMENT                        /    OPDB_PRELIM = OPDB, preliminary data
+COMMENT                        /    OPDB_EXPORT = OPDB, exported to SX
+COMMENT                        /    SX          = Science Database
+COMMENT                        /    FLATFILES   = Flat files
+TARG_SRC= 'XXX     '           / Source of target info:
+COMMENT                        /    OPDB_PRELIM = OPDB, preliminary data
+COMMENT                        /    OPDB_EXPORT = OPDB, exported to SX
+COMMENT                        /    SX          = Science Database
+COMMENT                        /    FLATFILES   = Flat files
+RESOLVED=                    T / Data from a resolved segment
+EXPORTED=                  XXX / Type of objects exported in this file:
+COMMENT                        /    1 = spectroscopic targets only
+COMMENT                        /    2 = primaries only
+COMMENT                        /    3 = primaries and secondaries
+COMMENT                        /    4 = all objects
+FAMILIES=                    T / Contains family members of included objects
+REF_BAND=                    2 / band used for canonical centre
+DARK_VAR= '4 4 4 4 4'          / Per-pixel variances at zero DN (DN^2)
+GAIN    = '3.5 3.5 3.5 3.5 3.5' / Mean gains of amplifiers (e/DN)
+END                         
+
+
+    Table Header
+
+There is one HDU of this type in the file for each field, ordered by
+field number. The "QUALITY" keyword records the quality of data in the
+field, in terms of its acceptance for the survey, and can take the
+following meanings:
+
+  'BAD      '   /* Not acceptable for the survey */
+  'ACCEPTABLE'  /* Acceptable for the survey, but we'd better data */
+  'GOOD     '   /* Fully acceptable --- no desire for better data */
+  'MISSING  '   /* No objects in this field, because data is missing, but we
+                 * accept the field into the survey as a hole in the survey */
+  'HOLE     '   /* Data in this field is not acceptable, but we will accept the
+                 * field into the survey as a hole in the survey, meaning none
+                 * of the objects in the field are part of the survey */
+
+The "STATUS_X" keywords record the status of the PSF fit for that field
+in that filter, and can take the following meanings:
+
+  'UNKNOWN  '    /* ??? */
+  'OK       '    /* PSF fitted by 2nd order parabolas */
+  'PSF22    '    /* PSF fitted by linear functions */
+  'PSF11    '    /* PSF fitted by a constant */
+  'NOPSF    '    /* PSF fit from previous frame used*/
+  'ABORTED  '    /* ??? */
+  'MISSING  '    /* ??? */
+
+PSP_STAT is the maximum value of STATUS_X over all 5 filters.
+
+The /objc_type/, /objc_flags/, /objc_flags2/, /flags/, /flags2/, and
+/type/ fields are enumerated types or bit masks, with the same set of
+legal values as found for the same fields in the fpObjc <fpObjc.html> file.
+
+The /status/ field is a bit mask specifying the status of the object in
+the survey. The bits are defined as:
+
+  AR_OBJECT_STATUS_SET        = 0x1,    /* This object's status has been set */
+					/* in reference to its own run.      */
+  AR_OBJECT_STATUS_GOOD       = 0x2,    /* Good as determined by its         */
+					/* object flags.  Absence implies    */
+                                        /* bad.  This flag is set by         */
+                                        /* "setObjectStatus".                */
+  AR_OBJECT_STATUS_DUPLICATE  = 0x4,    /* This object has one or more       */
+					/* duplicate detections in an        */
+					/* adjacent field of the same Frames */
+					/* Pipeline Run.  This is set by     */
+					/* "setObjectStatus".                */
+  AR_OBJECT_STATUS_OK_RUN     = 0x10,   /* Located within the primary range  */
+					/* of rows for this field.  This is  */
+                                        /* usable object.  This flag is set  */
+                                        /* by "setObjectStatus".             */
+  AR_OBJECT_STATUS_RESOLVED   = 0x20,   /* This object has been resolved     */
+					/* against other runs.               */
+  AR_OBJECT_STATUS_PSEGMENT   = 0x40,   /* Belongs to a PRIMARY segment.     */
+					/* This does not imply that this is a*/
+					/* primary object.                   */
+  AR_OBJECT_STATUS_FIRST_FIELD= 0x100,  /* Belongs to the first field in its */
+					/* segment.  Used to distinguish     */
+					/* objects in fields shared by two   */
+					/* segments.                         */
+  AR_OBJECT_STATUS_OK_SCANLINE= 0x200,  /* Lies within valid nu range        */
+					/* for its scanline.                 */
+  AR_OBJECT_STATUS_OK_STRIPE  = 0x400,  /* Lies within valid eta range for   */
+					/* its stripe.                       */
+  AR_OBJECT_STATUS_SECONDARY  = 0x1000, /* This is a secondary survey object.*/
+  AR_OBJECT_STATUS_PRIMARY    = 0x2000, /* This is a primary survey object.  */
+  AR_OBJECT_STATUS_TARGET     = 0x4000  /* This is a spectroscopic target.   */
+
+The /primTarget/ field is a bit mask specifying which primary target
+catagories the object was selected in. The bits are defined as:
+
+  AR_TARGET_QSO_HIZ           = 0x1,
+  AR_TARGET_QSO_CAP           = 0x2,
+  AR_TARGET_QSO_SKIRT         = 0x4,
+  AR_TARGET_QSO_FIRST_CAP     = 0x8,
+  AR_TARGET_QSO_FIRST_SKIRT   = 0x10,
+  AR_TARGET_QSO_MAG_OUTLIER  = 0x2000000,
+  AR_TARGET_QSO_REJECT	      = 0x20000000,
+  AR_TARGET_GALAXY_RED        = 0x20,
+  AR_TARGET_GALAXY_RED_II     = 0x4000000,
+  AR_TARGET_GALAXY            = 0x40,
+  AR_TARGET_GALAXY_BIG        = 0x80,
+  AR_TARGET_GALAXY_BRIGHT_CORE= 0x100,
+  AR_TARGET_ROSAT_A           = 0x200,
+  AR_TARGET_ROSAT_B           = 0x400,
+  AR_TARGET_ROSAT_C           = 0x800,
+  AR_TARGET_ROSAT_D           = 0x1000,
+  AR_TARGET_ROSAT_E           = 0x8000000,
+  AR_TARGET_STAR_BHB          = 0x2000,
+  AR_TARGET_STAR_CARBON       = 0x4000,
+  AR_TARGET_STAR_BROWN_DWARF  = 0x8000,
+  AR_TARGET_STAR_SUB_DWARF    = 0x10000,
+  AR_TARGET_STAR_CATY_VAR     = 0x20000,
+  AR_TARGET_STAR_RED_DWARF    = 0x40000,
+  AR_TARGET_STAR_WHITE_DWARF  = 0x80000,
+  AR_TARGET_STAR_PN           = 0x10000000,
+  AR_TARGET_SERENDIP_BLUE     = 0x100000,
+  AR_TARGET_SERENDIP_FIRST    = 0x200000,
+  AR_TARGET_SERENDIP_RED      = 0x400000,
+  AR_TARGET_SERENDIP_DISTANT  = 0x800000,
+  AR_TARGET_SERENDIP_MANUAL   = 0x1000000
+
+The /secTarget/ field is a bit mask specifying which secondary target
+catagories the object was selected in. The bits are defined as:
+
+  TAR_TARGET_LIGHT_TRAP        = 0x1,
+  TAR_TARGET_REDDEN_STD        = 0x2,
+  TAR_TARGET_TEST_TARGET       = 0x4,
+  TAR_TARGET_QA                = 0x8,
+  TAR_TARGET_SKY               = 0x10,
+  TAR_TARGET_SPECTROPHOTO_STD  = 0x20,
+  TAR_TARGET_GUIDE_STAR        = 0x40,
+  TAR_TARGET_BUNDLE_HOLE       = 0x80,
+  TAR_TARGET_QUALITY_HOLE      = 0x100,
+  TAR_TARGET_HOT_STD           = 0x200
+
+The /CULLED/ keyword is a bit mask with the same bit values as the
+/primTarget/ field. If a bit is set, then all targets of that target
+type were culled during target selection, and thus this field is
+excluded from that science sample.
+
+XTENSION= 'BINTABLE'          
+BITPIX  =                    8
+NAXIS   =                    2
+NAXIS1  =                 2732
+NAXIS2  =                  XXX
+PCOUNT  =                    0
+GCOUNT  =                    1
+TFIELDS =                  146
+FIELD   =                  XXX / Field sequence number within the run.
+QUALITY = 'XXX     '           / Quality of field in terms of survey acceptance
+CULLED  =                  XXX / Culling bit mask
+MJD_U   =         XXXXX.XXXXXX / MJD(TAI) when row 0 of u' frame was read
+MJD_G   =         XXXXX.XXXXXX / MJD(TAI) when row 0 of g' frame was read
+MJD_R   =         XXXXX.XXXXXX / MJD(TAI) when row 0 of r' frame was read
+MJD_I   =         XXXXX.XXXXXX / MJD(TAI) when row 0 of i' frame was read
+MJD_Z   =         XXXXX.XXXXXX / MJD(TAI) when row 0 of z' frame was read
+SEEING_U=                 XX.X / Seeing on the u' frame (FWHM, arcsecs)
+SEEING_G=                 XX.X / Seeing on the g' frame (FWHM, arcsecs)
+SEEING_R=                 XX.X / Seeing on the r' frame (FWHM, arcsecs)
+SEEING_I=                 XX.X / Seeing on the i' frame (FWHM, arcsecs)
+SEEING_Z=                 XX.X / Seeing on the z' frame (FWHM, arcsecs)
+STATUS_U= 'XXX     '           / PSF fit status on u' frame
+STATUS_G= 'XXX     '           / PSF fit status on g' frame
+STATUS_R= 'XXX     '           / PSF fit status on r' frame
+STATUS_I= 'XXX     '           / PSF fit status on i' frame
+STATUS_Z= 'XXX     '           / PSF fit status on z' frame
+PSP_STAT= 'XXX     '           / Maximum of STATUS value on all 5 frames
+PSFERR_U=               XXX.XX / Photometric err due to imperfect PSF model(mag)
+PSFERR_G=               XXX.XX / Photometric err due to imperfect PSF model(mag)
+PSFERR_R=               XXX.XX / Photometric err due to imperfect PSF model(mag)
+PSFERR_I=               XXX.XX / Photometric err due to imperfect PSF model(mag)
+PSFERR_Z=               XXX.XX / Photometric err due to imperfect PSF model(mag)
+SKY_U   =               XXX.XX / Global sky value after obj sub (mag/arcsec^2)
+SKY_G   =               XXX.XX / Global sky value after obj sub (mag/arcsec^2)
+SKY_R   =               XXX.XX / Global sky value after obj sub (mag/arcsec^2)
+SKY_I   =               XXX.XX / Global sky value after obj sub (mag/arcsec^2)
+SKY_Z   =               XXX.XX / Global sky value after obj sub (mag/arcsec^2)
+TFORM1  = '1J      '          
+TTYPE1  = 'run     '           / Run ID
+TUNIT1  = 'unitless'          
+TFORM2  = '1J      '          
+TTYPE2  = 'camCol  '           / Camera column
+TUNIT2  = 'unitless'          
+TFORM3  = '1J      '          
+TTYPE3  = 'rerun   '           / Rerun number
+TUNIT3  = 'unitless'          
+TFORM4  = '1J      '          
+TTYPE4  = 'field   '           / Field ID
+TUNIT4  = 'unitless'          
+TFORM5  = '1J      '          
+TTYPE5  = 'parent  '           / Parent
+TUNIT5  = 'unitless'          
+TFORM6  = '1J      '          
+TTYPE6  = 'id      '           / Object ID, unique within its field (1 indexed)
+TUNIT6  = 'unitless'          
+TFORM7  = '1J      '          
+TTYPE7  = 'nchild  '           / Number of Children
+TUNIT7  = 'unitless'          
+TFORM8  = '1J      '          
+TTYPE8  = 'objc_type'          / Classification
+TUNIT8  = 'unitless'          
+TFORM9  = '1E      '
+TTYPE9  = 'objc_prob_psf'      / Probablity object is a star
+TUNIT9  = 'unitless'          
+TFORM10 = '1J      '          
+TTYPE10 = 'catID   '           / Catalog ID
+TUNIT10 = 'unitless'          
+TFORM11 = '1J      '          
+TTYPE11 = 'objc_flags'         / Object flags
+TUNIT11 = 'unitless'          
+TFORM12 = '1J      '          
+TTYPE12 = 'objc_flags2'        / More object flags
+TUNIT12 = 'unitless'          
+TFORM13 = '1E      '          
+TTYPE13*= 'objc_rowc'          / Nominal row position (r' coordinates)
+TUNIT13 = 'pixels  '          
+TFORM14 = '1E      '          
+TTYPE14*= 'objc_rowcErr'       / Nominal row position (r' coordinates) error
+COMMENT                        / This is the centroiding error only.  It does
+COMMENT                        / not include errors from the TRANS structures.
+TUNIT14 = 'pixels  '          
+TFORM15 = '1E      '          
+TTYPE15*= 'objc_colc'          / Nominal column position (r' coordinates)
+TUNIT15 = 'pixels  '          
+TFORM16 = '1E      '          
+TTYPE16*= 'objc_colcErr'       / Nominal column position (r' coordinates) error
+COMMENT                        / This is the centroiding error only.  It does
+COMMENT                        / not include errors from the TRANS structures.
+TUNIT16 = 'pixels  '          
+TFORM17 = '1E      '          
+TTYPE17 = 'rowv    '           / Row-component of object's velocity
+TUNIT17 = 'deg/day '          
+TFORM18 = '1E      '          
+TTYPE18 = 'rowvErr '           / Row-component of object's velocity error
+TUNIT18 = 'deg/day '          
+TFORM19 = '1E      '          
+TTYPE19 = 'colv'               / Column-component of object's velocity 
+TUNIT19 = 'deg/day'          
+TFORM20 = '1E      '          
+TTYPE20 = 'colvErr'            / Column-component of obejct's velocity error
+TUNIT20 = 'deg/day'          
+TFORM21 = '5E      '          
+TTYPE21 = 'rowc    '           / Row center
+TUNIT21 = 'pixels  '          
+TFORM22 = '5E      '          
+TTYPE22 = 'rowcErr '           / Row center error
+TUNIT22 = 'pixels  '          
+TFORM23 = '5E      '          
+TTYPE23 = 'colc    '           / Center colum 
+TUNIT23 = 'pixels  '          
+TFORM24 = '5E      '          
+TTYPE24 = 'colcErr '           / Center column error
+TUNIT24 = 'pixels  '          
+TFORM25 = '5E      '          
+TTYPE25 = 'sky     '           / Sky flux
+TUNIT25 = 'asinh mag/arcsec^2'         
+TFORM26 = '5E      '          
+TTYPE26 = 'skyErr  '           / Sky flux error
+TUNIT26 = 'asinh mag/arcsec^2'         
+TFORM27 = '5E      '          
+TTYPE27 = 'psfCounts'          / PSF flux
+TUNIT27 = 'asinh mag     '          
+TFORM28 = '5E      '          
+TTYPE28 = 'psfCountsErr'       / PSF flux error
+TUNIT28 = 'asinh mag     '          
+TFORM29 = '5E      '          
+TTYPE29 = 'fiberCounts'        / Flux in 3 arcsec diameter fiber radius
+TUNIT29 = 'asinh mag     '          
+TFORM30 = '5E      '          
+TTYPE30 = 'fiberCountsErr'     / Flux in 3 arcsec diameter fiber radius error
+TUNIT30 = 'asinh mag     '          
+TFORM31 = '5E      '          
+TTYPE31 = 'petroCounts'        / Petrosian flux
+TUNIT31 = 'asinh mag     '          
+TFORM32 = '5E      '          
+TTYPE32 = 'petroCountsErr'     / Petrosian flux error
+TUNIT32 = 'asinh mag     '          
+TFORM33 = 5E      '          
+TTYPE33 = 'petroRad'           / Petrosian radius
+TUNIT33 = 'arcsec '          
+TFORM34 = '5E      '          
+TTYPE34 = 'petroRadErr'        / Petrosian radius error
+TUNIT34 = 'arcsec '          
+TFORM35 = '5E      '          
+TTYPE35 = 'petroR50'           / Radius with 50 percent of Petrosian light
+TUNIT35 = 'arcsec '          
+TFORM36 = '5E      '          
+TTYPE36 = 'petroR50Err'        / Radius with 50 percent of Petrosian light error
+TUNIT36 = 'arcsec '          
+TFORM37 = '5E      '          
+TTYPE37 = 'petroR90'           / Radius with 90 percent of Petrosian light
+TUNIT37 = 'arcsec '          
+TFORM38 = '5E      '          
+TTYPE38 = 'petroR90Err'        / Radius with 90 percent of Petrosian light error
+TUNIT38 = 'arcsec  '          
+TFORM39 = '5E      '          
+TTYPE39 = 'Q       '           / Stokes Q parameter
+TUNIT39 = 'unitless'          
+TFORM40 = '5E      '          
+TTYPE40 = 'QErr    '           / Stokes Q parameter error
+TUNIT40 = 'unitless'          
+TFORM41 = '5E      '          
+TTYPE41 = 'U       '           / Stokes U parameter
+TUNIT41 = 'unitless'          
+TFORM42 = '5E      '          
+TTYPE42 = 'UErr    '           / Stokes U parameter error
+TUNIT42 = 'unitless'          
+TFORM43 = '5E      '
+TTYPE43 = 'M_e1    '           / Adaptive E1 shape measure
+TUNIT43 = 'unitless'          
+TFORM44 = '5E      '
+TTYPE44 = 'M_e2    '           / Adaptive E2 shape measure
+TUNIT44 = 'unitless'          
+TFORM45 = '5E      '
+TTYPE45 = 'M_e1e1Err'          / Covariance in E1-E1 shape measure
+TUNIT45 = 'unitless'          
+TFORM46 = '5E      '
+TTYPE46 = 'M_e1e2Err'          / Covariance in E1-E2 shape measure
+TUNIT46 = 'unitless'          
+TFORM47 = '5E      '
+TTYPE47 = 'M_e2e2Err'          / Covariance in E2-E2 shape measure
+TUNIT47 = 'unitless'          
+TFORM48 = '5E      '
+TTYPE48 = 'M_rr_cc '           / Adaptive ( + )
+TUNIT48 = 'unitless'          
+TFORM49 = '5E      '
+TTYPE49 = 'M_rr_ccErr'         / Error in adaptive ( + )
+TUNIT49 = 'unitless'          
+TFORM50 = '5E      '
+TTYPE50 = 'M_cr4   '           / Adaptive fourth moment
+TUNIT50 = 'unitless'          
+TFORM51 = '5E      '
+TTYPE51 = 'M_e1_psf'           / Adaptive E1 for PSF
+TUNIT51 = 'unitless'          
+TFORM52 = '5E      '
+TTYPE52 = 'M_e2_psf'           / Adaptive E2 for PSF
+TUNIT52 = 'unitless'          
+TFORM53 = '5E      '
+TTYPE53 = 'M_rr_cc_psf'        / Adaptive () for PSF
+TUNIT53 = 'unitless'          
+TFORM54 = '5E      '
+TTYPE54 = 'M_cr4_psf'          / Adaptive fourth moment for PSF
+TUNIT54 = 'unitless'          
+TFORM55 = '5E      '          
+TTYPE55 = 'iso_rowc'           / Isophotal row centroid
+TUNIT55 = 'pixels  '          
+TFORM56 = '5E      '          
+TTYPE56 = 'iso_rowcErr'        / Isophotal row centroid error
+TUNIT56 = 'pixels  '          
+TFORM57 = '5E      '          
+TTYPE57 = 'iso_rowcGrad'       / Gradient in row centroid with isophote
+TUNIT57 = 'pixels/mag/arcsec^2'
+TFORM58 = '5E      '          
+TTYPE58 = 'iso_colc'           / Isophotal column centroid
+TUNIT58 = 'pixels  '          
+TFORM59 = '5E      '          
+TTYPE59 = 'iso_colcErr'        / Isophotal column centroid error
+TUNIT59 = 'pixels  '          
+TFORM60 = '5E      '          
+TTYPE60 = 'iso_colcGrad'       / Gradient in column centroid with isophote
+TUNIT60 = 'pixels/mag/arcsec^2'
+TFORM61 = '5E      '          
+TTYPE61 = 'iso_a   '           / Isophotal major axis
+TUNIT61 = 'arcsec  '          
+TFORM62 = '5E      '          
+TTYPE62 = 'iso_aErr'           / Isophotal major axis error
+TUNIT62 = 'arcsec  '          
+TFORM63 = '5E      '          
+TTYPE63 = 'iso_aGrad'          / Gradient in major axis with isophote
+TUNIT63 = 'arcsec/mag/arcsec^2'
+TFORM64 = '5E      '          
+TTYPE64 = 'iso_b   '           / Isophotal minor axis
+TUNIT64 = 'arcsec  '          
+TFORM65 = '5E      '          
+TTYPE65 = 'iso_bErr'           / Isophotal minor axis error
+TUNIT65 = 'arcsec  '          
+TFORM66 = '5E      '          
+TTYPE66 = 'iso_bGrad'          / Gradient in minor axis with isophote
+TUNIT66 = 'arcsec/mag/arcsec^2'
+TFORM67 = '5E      '          
+TTYPE67 = 'iso_phi '           / Isophotal position angle
+TUNIT67 = 'degrees (+N thru E)'          
+TFORM68 = '5E      '          
+TTYPE68 = 'iso_phiErr'         / Isophotal position angle error
+TUNIT68 = 'degrees '          
+TFORM69 = '5E      '          
+TTYPE69 = 'iso_phiGrad'        / Gradient in positional angle with isophote
+TUNIT69 = 'degrees/mag/arcsec^2'
+TFORM70 = '5E      '          
+TTYPE70 = 'r_deV   '           / De Vaucouleurs fit scale radius
+TUNIT70 = 'arcsec  '          
+TFORM71 = '5E      '          
+TTYPE71 = 'r_deVErr'           / De Vaucouleurs fit scale radius error
+TUNIT71 = 'arcsec  '          
+TFORM72 = '5E      '          
+TTYPE72 = 'ab_deV  '           / De Vaucouleurs fit a/b
+TUNIT72 = 'unitless'          
+TFORM73 = '5E      '          
+TTYPE73 = 'ab_deVErr'          / De Vaucouleurs fit a/b error
+TUNIT73 = 'unitless'          
+TFORM74 = '5E      '          
+TTYPE74 = 'phi_deV '           / De Vaucouleurs fit position angle
+TUNIT74 = 'degrees (+N thru E)'          
+TFORM75 = '5E      '          
+TTYPE75 = 'phi_deVErr'         / De Vaucouleurs fit position angle error
+TUNIT75 = 'degrees '          
+TFORM76 = '5E      '          
+TTYPE76 = 'counts_deV'         / De Vaucouleurs magnitude fit
+TUNIT76 = 'asinh mag '          
+TFORM77 = '5E      '          
+TTYPE77 = 'counts_deVErr'      / De Vaucouleurs magnitude fit error
+TUNIT77 = 'asinh mag '          
+TFORM78 = '5E      '          
+TTYPE78 = 'r_exp   '           / Exponetial fit scale radius
+TUNIT78 = 'arcsec  '          
+TFORM79 = '5E      '          
+TTYPE79 = 'r_expErr'           / Exponetial fit scale radius error
+TUNIT79 = 'arcsec '          
+TFORM80 = '5E      '          
+TTYPE80 = 'ab_exp  '           / Exponential fit a/b
+TUNIT80 = 'unitless'          
+TFORM81 = '5E      '          
+TTYPE81 = 'ab_expErr'          / Exponential fit a/b error
+TUNIT81 = 'unitless'          
+TFORM82 = '5E      '          
+TTYPE82 = 'phi_exp '           / Exponential fit position angle
+TUNIT82 = 'degrees (+N thru E)'          
+TFORM83 = '5E      '          
+TTYPE83 = 'phi_expErr'         / Exponential fit position angle error
+TUNIT83 = 'degrees '          
+TFORM84 = '5E      '          
+TTYPE84 = 'counts_exp'         / Exponential fit
+TUNIT84 = 'asinh mag '          
+TFORM85 = '5E      '          
+TTYPE85 = 'counts_expErr'      / Exponential fit error
+TUNIT85 = 'asinh mag '          
+TFORM86 = '5E      '          
+TTYPE86 = 'counts_model'       / Better of DeV/Exp magnitude fit
+TUNIT86 = 'asinh mag '          
+TFORM87 = '5E      '          
+TTYPE87 = 'counts_modelErr'    / Better of DeV/Exp magnitude fit error
+TUNIT87 = 'asinh mag '          
+TFORM88 = '5E      '          
+TTYPE88 = 'texture '           / Texture parameter
+TUNIT88 = 'unitless'          
+TFORM89 = '5E      '          
+TTYPE89 = 'star_L  '           / Star likelihood
+TUNIT89 = 'unitless'          
+TFORM90 = '5E      '          
+TTYPE90 = 'star_lnL'           / Star ln(likelihood)
+TUNIT90 = 'unitless'          
+TFORM91 = '5E      '          
+TTYPE91 = 'exp_L   '           / Exponential disk fit likelihood
+TUNIT91 = 'unitless'          
+TFORM92 = '5E      '          
+TTYPE92 = 'exp_lnL '           / Exponential disk fit ln(likelihood)
+TUNIT92 = 'unitless'          
+TFORM93 = '5E      '          
+TTYPE93 = 'deV_L   '           / De Vaucouleurs fit likelihood
+TUNIT93 = 'unitless'          
+TFORM94 = '5E      '          
+TTYPE94 = 'deV_lnL '           / De Vaucouleurs fit ln(likelihood)
+TUNIT94 = 'unitless'          
+TFORM95 = '5E      '          
+TTYPE95 = 'fracPSF '           / Fraction of light in PSF
+TUNIT95 = 'unitless'          
+TFORM96 = '5J      '          
+TTYPE96 = 'flags   '           / Object flags
+TUNIT96 = 'unitless'          
+TFORM97 = '5J      '          
+TTYPE97 = 'flags2  '           / More object flags
+TUNIT97 = 'unitless'          
+TFORM98 = '5J      '          
+TTYPE98 = 'type    '           / Object type
+TUNIT98 = 'unitless'          
+TFORM99 = '5E      '
+TTYPE99 = 'prob_psf'           / Probablity object is a star in each filter
+TUNIT99 = 'unitless'          
+TFORM100= '5J      '          
+TTYPE100= 'nprof   '           / Number of radial bins
+TUNIT100= 'unitless'          
+TFORM101= '75E     '          
+TTYPE101= 'profMean'           / Mean pixel flux in annulus
+TUNIT101= 'maggies/arcsec^2'         
+TDIM101 = '(15,5)  '          
+TFORM102= '75E     '          
+TTYPE102= 'profErr '           / Standard deviation of profMean
+TUNIT102= 'maggies/arcsec^2'        
+TDIM102 = '(15,5)  '          
+TFORM103= '1J      '          
+TTYPE103= 'status  '           / Survey status
+TUNIT103= 'unitless'          
+TFORM104= '1D      '          
+TTYPE104= 'ra      '           / J2000 right ascension (r')
+TUNIT104= 'degrees '          
+TFORM105= '1D      '          
+TTYPE105= 'dec     '           / J2000 declination (r')
+TUNIT105= 'degrees '          
+TFORM106= '1D      '          
+TTYPE106= 'lambda  '           / Survey longitude (r')
+TUNIT106= 'degrees '          
+TFORM107= '1D      '          
+TTYPE107= 'eta     '           / Survey latitude (r')
+TUNIT107= 'degrees '          
+TFORM108= '1D      '          
+TTYPE108= 'l       '           / Galactic longitude (lII, r')
+TUNIT108= 'degrees '          
+TFORM109= '1D      '          
+TTYPE109= 'b       '           / Galactic latitude (bII, r')
+TUNIT109= 'degrees '          
+TFORM110= '5E      '          
+TTYPE110= 'offsetRa'           / Filter position ra minus final ra (* cos(dec))
+TUNIT110= 'arcsec  '          
+TFORM111= '5E      '          
+TTYPE111= 'offsetDec'          / Filter position dec minus final dec
+TUNIT111= 'arcsec  '          
+TFORM112= '1J      '
+TTYPE112= 'primTarget'         / Target selection flags
+TUNIT112= 'unitless'          
+TFORM113= '1J      '
+TTYPE113= 'secTarget'          / Additional Target selection flags
+TUNIT113= 'unitless'          
+TFORM114= '5E      '
+TTYPE114= 'reddening'          / Reddening in each filter
+TUNIT114= 'mag   '
+TFORM115= '1J      '
+TTYPE115= 'propermotionmatch'  / 1= match to USNO catatalog
+TUNIT115= 'unitless'          
+TFORM116= '1E      '
+TTYPE116= 'propermotiondelta'  / Difference in positions between USNO and
+COMMENT                        / photo object (r' band)
+TUNIT116= 'arcsec'
+TFORM117= '1E      '
+TTYPE117= 'propermotion'       / Proper motion of object
+TUNIT117= 'arcsec/century'
+TFORM118= '1E      '
+TTYPE118= 'propermotionangle'  / Direction of proper motion
+TUNIT118= 'degrees (+N thru E)'
+TFORM119= '1E      '
+TTYPE119= 'usnoBlue'           / Blue magntiude of matching USNO object
+TUNIT119= 'mag     '
+TFORM120= '1E      '
+TTYPE120= 'usnoRed '           / Red magntiude of matching USNO object
+TUNIT120= 'mag     '
+TFORM121= '1J      '
+TTYPE121= 'firstMatch'         / Number of FIRST sources matched (0=no match)
+TUNIT121= 'unitless'          
+TFORM122= '1J      '
+TTYPE122= 'firstId '           / FIRST catalog id of one matching source
+TUNIT122= 'unitless'          
+TFORM123= '1D      '
+TTYPE123= 'firstLambda'        / Composite radio source survey longitude
+TUNIT123= 'degrees '
+TFORM124= '1D      '
+TTYPE124= 'firstEta'           / Composite radio source survey latitude
+TUNIT124= 'degrees '
+TFORM125= '1E      '
+TTYPE125= 'firstDelta'         / Position difference between first and photo object (r' band)
+TUNIT125= 'arcsec'
+TFORM126= '1E      '
+TTYPE126= 'firstPeak'          / Peak first radio flux
+TUNIT126= 'mJy'
+TFORM127= '1E      '
+TTYPE127= 'firstInt'           / Integrated first radio flux
+TUNIT127= 'mJy'
+TFORM128= '1E      '
+TTYPE128= 'firstRms'           / Rms error in flux
+TUNIT128= 'mJy'
+TFORM129= '1E      '
+TTYPE129= 'firstMajor'         / Major axis (deconvolved)
+TUNIT129= 'arcsec'
+TFORM130= '1E      '
+TTYPE130= 'firstMinor'         / Minor axis (deconvolved)
+TUNIT130= 'arcsec'
+TFORM131= '1E      '
+TTYPE131= 'firstPa'            / Position angle (east of north)
+TUNIT131= 'degrees'
+TFORM132= '1J      '
+TTYPE132= 'rosatMatch'         / ID of matching ROSAT source (0 = no match)
+TUNIT132= 'unitless'          
+TFORM133= '1E      '
+TTYPE133= 'rosatDelta'         / Position difference between ROSAT and photo object (r' band)
+TUNIT133= 'arcsec'
+TFORM134= '1E      '                                                           
+TTYPE134= 'rosatPosErr'        / Error in ROSAT position
+TUNIT134= 'arcsec '
+TFORM135= '1E      '
+TTYPE135= 'rosatCps'           / Integrated ROSAT counts
+TUNIT135= 'counts/sec'
+TFORM136= '1E      '
+TTYPE136= 'rosatCpsErr'        / Error in integrated ROSAT counts
+TUNIT136= 'counts/sec'
+TFORM137= '1E      '
+TTYPE137= 'rosatHr1'           / ROSAT hardness ratio 1
+TUNIT137= 'unitless'          
+TFORM138= '1E      '
+TTYPE138= 'rosatHr1Err'        / Error in ROSAT hardness ratio 1
+TUNIT138= 'unitless'          
+TFORM139= '1E      '
+TTYPE139= 'rosatHr2'           / ROSAT hardness ratio 2
+TUNIT139= 'unitless'          
+TFORM140= '1E      '
+TTYPE140= 'rosatHr2Err'        / Error in ROSAT hardness ratio 2
+TUNIT140= 'unitless'          
+TFORM141= '1E      '
+TTYPE141= 'rosatExt'           / ROSAT extent parameter
+TUNIT141= 'arcsec'
+TFORM142= '1E      '
+TTYPE142= 'rosatExtLike'       / ROSAT extent parameter likelihood
+TUNIT142= 'unitless'          
+TFORM143= '1E      '
+TTYPE143= 'rosatDetectLike'    / ROSAT detection likelihood
+TUNIT143= 'unitless'          
+TFORM144= '1E      '
+TTYPE144= 'rosatExposure'      / ROSAT exposure time
+TUNIT144= 'seconds '
+TFORM145= '1J      '
+TTYPE145= 'priority'           / Priority bits
+TSCAL145= 1.00000000000000E+00
+TZERO145= 2.14748364800000E+09
+TUNIT145= 'unitless'          
+TFORM146= '50J     '
+TTYPE146= 'matchid '           / Link ids (run,camCol,rerun,field,id)
+TUNIT146= 'unitless'          
+TDIM146 = '(5,10)  '
+
Index: /trunk/Ohana/src/addstar/doc/sdss.txt
===================================================================
--- /trunk/Ohana/src/addstar/doc/sdss.txt	(revision 16810)
+++ /trunk/Ohana/src/addstar/doc/sdss.txt	(revision 16810)
@@ -0,0 +1,60 @@
+
+adding SDSS object tables:
+
+* autodetect the SDSS files from the header?
+* do I need to read multiple files for a single data set?
+* how are we going to determine photcodes?
+  * do we need to set the photcode on a per-object basis in LoadData or equivalent?
+
+* some re-org might be needed for LoadStars
+
+
+** fields to keep:
+
+name          sdss 
+ X            'objc_colc' (or colc)
+ Y            'objc_rowc' (or rowc)
+ dX           'objc_colcErr' (or colcErr)
+ dY           'objc_rowcErr' (or rowcErr)
+ R            ra  + offset Ra (get cos des right)
+ D            dec + offset Dec
+ dR           (calculate from dX * plate scale?)
+ dD           (calculate from dX * plate scale?)
+ uR           (from 'propermotion' and 'propermotionangle')
+ uD           (from 'propermotion' and 'propermotionangle')
+ duR          ?
+ duD          ?
+ P            X
+ dP           X
+ M            psfCounts (is already a mag?)
+ dM           psfCountsErr (is already a mag?)
+ sky          sky (convert to flux?)
+ dsky         skyErr (convert to flux?)
+ fx           ?
+ fy           ?
+ df           ?
+ Mgal         X
+ Map          X
+ Mpeak        X
+ detID        X
+ found        -1
+ t            MJD_U + Y*rate
+ dt           fixed? NY*rate
+ psfChisq     
+ crNsigma     
+ extNsigma    
+ psfQual      
+ Mcal         
+ airmass      
+ az            
+ code         
+ nFrames      
+ flags        
+ dophot       
+ dummy        
+
+we can use these header fields to get the exp times, and I suppose alt, az, airmass, etc:
+NODE    =           XXX.XXXXXX / Ascending node of great circle scanned (deg)
+INCL    =           XXX.XXXXXX / Inclincation of great circle scanned (deg)
+C_OBS   =            XXXXX.XXX / CCD clock rate (usec/unbinned-row)
+TRACKING=            XXXXX.XXX / Tracking rate (arcsec/TAI-sec)
Index: /trunk/Ohana/src/addstar/include/2mass.h
===================================================================
--- /trunk/Ohana/src/addstar/include/2mass.h	(revision 16809)
+++ /trunk/Ohana/src/addstar/include/2mass.h	(revision 16810)
@@ -42,2 +42,13 @@
 int       get2mass_star (Stars *star, char *line, int Nmax);
 int       get2mass_3star (Stars *star, char *line, int Nmax);
+
+int get2mass_3star_full (Stars *star, char *line, int Nmax);
+char *next2MASSfield (char *line);
+int set2MASS_ph_qual (Stars *star, char qual);
+int set2MASS_rd_flag (Stars *star, char qual);
+int set2MASS_cc_flag (Stars *star, char qual);
+int set2MASS_bl_flag (Stars *star, char qual);
+int set2MASS_gal_flag (Stars *star, char qual);
+int set2MASS_mp_flag (Stars *star, char qual);
+int set2MASS_dup_flag (Stars *star, char qual);
+int set2MASS_use_flag (Stars *star, char qual);
Index: /trunk/Ohana/src/addstar/include/addstar.h
===================================================================
--- /trunk/Ohana/src/addstar/include/addstar.h	(revision 16809)
+++ /trunk/Ohana/src/addstar/include/addstar.h	(revision 16810)
@@ -51,5 +51,5 @@
 
 enum {M_IMAGE, M_REFLIST, M_REFCAT, M_FAKEIMAGE, M_RESORT};
-enum {NONE, SIMPLE_CMP, SIMPLE_CMF, SIMPLE_MEF, MOSAIC_CMP, MOSAIC_CMF, MOSAIC_MEF, MOSAIC_PHU};
+enum {NONE, SIMPLE_CMP, SIMPLE_CMF, SIMPLE_MEF, MOSAIC_CMP, MOSAIC_CMF, MOSAIC_MEF, MOSAIC_PHU, SDSS_OBJ};
 /* note: MEF implies CMF */
 
@@ -163,5 +163,5 @@
 Stars     *grefstars              PROTO((char *file, int photcode, int *Nstars));
 
-Stars     *LoadStars              PROTO((char *file, int *Nstars, Image **images, int *Nimages, int photcode));
+Stars     *LoadStars              PROTO((char *file, int *Nstars, Image **images, int *Nimages, AddstarClientOptions *options));
 Header   **LoadHeaders            PROTO((FILE *f, int *mode, int *Nheader));
 HeaderSet *MatchHeaders           PROTO((int **extsize, int *nimage, int mode, Header **headers, int Nheaders));
@@ -185,6 +185,7 @@
 Stars     *ReadStarsFITS          PROTO((FILE *f, Header *header, Header *in_theader, unsigned int *nstars));
 Stars     *ReadStarsTEXT          PROTO((FILE *f, unsigned int *nstars));
+Stars     *ReadStarsSDSS          PROTO((FILE *f, char *name, Header *header, Header *in_theader, Image *images, int *nimages, unsigned int *nstars));
 int        ReadImageHeader        PROTO((Header *header, Image *image, int photcode));
-Stars     *FilterStars            PROTO((Stars *instars, Image *image));
+Stars     *FilterStars            PROTO((Stars *instars, Image *image, unsigned int imageID));
 Stars     *MergeStars             PROTO((Stars *stars, int *Nstars, Stars *instars, int Ninstars));
 void       save_pt_catalog        PROTO((Catalog *catalog));  /*** choose new name ***/
@@ -245,4 +246,7 @@
 int args_skycells (int argc, char **argv);
 int ConfigInit_skycells (int *argc, char **argv);
+int UpdateImageIDs (Stars *stars, int Nstars, Image *images, int Nimages);
+int LoadDataSDSS (FILE *f, char *file, Image **images, int *nvalid, Stars **stars, int *Nstars, Header **headers, int *extsize, HeaderSet *headerSets, int Nimages);
+int altaz (double *alt, double *az, double ha, double dec, double latitude);
 
 // this is a gnu extension?? caution!
Index: /trunk/Ohana/src/addstar/src/FilterStars.c
===================================================================
--- /trunk/Ohana/src/addstar/src/FilterStars.c	(revision 16809)
+++ /trunk/Ohana/src/addstar/src/FilterStars.c	(revision 16810)
@@ -1,5 +1,5 @@
 # include "addstar.h"
 
-Stars *FilterStars (Stars *instars, Image *image) {
+Stars *FilterStars (Stars *instars, Image *image, unsigned int imageID) {
 
   int j, N;
@@ -65,11 +65,13 @@
       stars[N].M += MTIME - dMs;
     }
-    if (!isnan(stars[N].Mgal)) {
-      stars[N].Mgal += MTIME - dMs;
-    }
     if (!isnan(stars[N].Map)) {
       stars[N].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?
+
     N ++;
   }
Index: /trunk/Ohana/src/addstar/src/GetFileMode.c
===================================================================
--- /trunk/Ohana/src/addstar/src/GetFileMode.c	(revision 16809)
+++ /trunk/Ohana/src/addstar/src/GetFileMode.c	(revision 16810)
@@ -16,4 +16,13 @@
   gfits_scan (header, "EXTEND", "%t", 1, &extend);
     
+  { 
+    int tmp, haveCAMCOL, haveSTRIPE;
+    
+    // SDSS tsObj files have CAMCOL & STRIP keywords present in the header
+    haveCAMCOL = gfits_scan (header, "CAMCOL",  "%d", 1, &tmp);
+    haveSTRIPE = gfits_scan (header, "STRIPE",  "%d", 1, &tmp);
+    if (haveCAMCOL && haveSTRIPE) return SDSS_OBJ;
+  }
+
   if ((Naxis == 2) || TEXTMODE || !simple) {
     if (!strcmp (&ctype[4], "-WRP")) {
Index: /trunk/Ohana/src/addstar/src/ImageOptions.c
===================================================================
--- /trunk/Ohana/src/addstar/src/ImageOptions.c	(revision 16809)
+++ /trunk/Ohana/src/addstar/src/ImageOptions.c	(revision 16810)
@@ -4,5 +4,5 @@
 int ImageOptions (AddstarClientOptions *options, Image *images, int Nimages) {
 
-  int i, equivPhotcode;
+  int i, equivPhotcode, consistent;
   float maxError;
   PhotCode *photcode;
@@ -18,5 +18,9 @@
 
   // check that all images have the same equiv photcode and save it
+  // XXX this is only used to allow use to calculate an average mag
+  // if we have mis-matched photcodes, leave this as 0;
+  options[0].photcode = 0;
   equivPhotcode = 0;
+  consistent = TRUE;
 
   for (i = 0; i < Nimages; i++) {
@@ -28,6 +32,6 @@
     if (equivPhotcode) {
       if (equivPhotcode != photcode[0].equiv) {
-	fprintf (stderr, "ERROR: mismatch in equiv photcode values\n");
-	exit (2);
+	consistent = FALSE;
+	break;
       }
     } else {
@@ -35,5 +39,7 @@
     }
   }
-  options[0].photcode = equivPhotcode;
+  if (consistent) {
+    options[0].photcode = equivPhotcode;
+  }
 
   options[0].imageID = 0;
Index: /trunk/Ohana/src/addstar/src/LoadData.c
===================================================================
--- /trunk/Ohana/src/addstar/src/LoadData.c	(revision 16810)
+++ /trunk/Ohana/src/addstar/src/LoadData.c	(revision 16810)
@@ -0,0 +1,77 @@
+# include "addstar.h"
+
+// XXX this function is somewhat specific to the elixir format output files 
+// it is capable of distinguishing several format versions defined for elixir/psphot
+
+// examine the header sets and set the Image entries for the the valid images
+int LoadData (FILE *f, char *file, Image **images, int *nvalid, Stars **stars, int *Nstars, Header **headers, int *extsize, HeaderSet *headerSets, int Nimages) {
+
+  char *name;
+  int i, j, Nvalid, Nhead, Ndata, Nskip;
+  Stars *inStars;
+
+  if (images[0] == NULL) {
+    Nvalid = 0;
+    NVALID = 10;
+    ALLOCATE (images[0], Image, NVALID);
+  } else {
+    Nvalid = *nvalid;
+    NVALID = Nvalid + 10;
+    REALLOCATE (images[0], Image, NVALID);
+  }    
+
+  // find image rootname
+  name = filebasename (file);
+
+  // now run through the images, interpret the headers and read the stars
+  for (i = 0; i < Nimages; i++) {
+    Nhead = headerSets[i].extnum_head;
+
+    if (VERBOSE) fprintf (stderr, "reading header for %s (%s)\n", headerSets[i].exthead, headerSets[i].extdata);
+    if (!ReadImageHeader (headers[Nhead], &images[0][Nvalid], 0)) {
+      fprintf (stderr, "skipping %s\n", headerSets[i].exthead);
+      continue;
+    }
+    images[0][Nvalid].imageID = Nvalid;
+    images[0][Nvalid].externID = 0;
+    images[0][Nvalid].sourceID = 0;
+
+    // XXX EAM : I seemed to have dropped the ability to support TEXT (old-style cmp format files).
+    // I need to detect them here and load them with ReadStarsTEXT instead of calling the code
+    // below.
+
+    // XXX use something to set the chip name? EXTNAME?
+    if (!strcmp(headerSets[i].exthead, "PHU") && (Nimages == 1)) {
+      snprintf (images[0][Nvalid].name, 64, "%s", name);
+    } else {
+      snprintf (images[0][Nvalid].name, 64, "%s[%s]", name, headerSets[i].exthead);
+    }
+
+    // skip the table if there is no data segment (eg, mosaic WRP image)
+    if (!strcmp(headerSets[i].extdata, "NONE")) {
+      Nvalid++;
+      if (Nvalid == NVALID) {
+	NVALID += 10;
+	REALLOCATE (images[0], Image, NVALID);
+      }
+      continue;
+    }
+
+    // advance the pointer to the start of the corresponding table block
+    Ndata = headerSets[i].extnum_data;
+    Nskip = 0;
+    for (j = 0; j < Ndata; j++) {
+      Nskip += extsize[j];
+    }
+    fseek (f, Nskip, SEEK_SET); 
+	 
+    inStars = ReadStarsFITS (f, headers[Nhead], headers[Ndata], &images[0][Nvalid].nstar);
+    inStars = FilterStars (inStars, &images[0][Nvalid], Nvalid);
+    *stars = MergeStars (*stars, Nstars, inStars, images[0][Nvalid].nstar);
+    Nvalid++;
+  }
+  free (name);
+  *nvalid = Nvalid;
+  return (TRUE);
+}
+
Index: /trunk/Ohana/src/addstar/src/LoadDataSDSS.c
===================================================================
--- /trunk/Ohana/src/addstar/src/LoadDataSDSS.c	(revision 16810)
+++ /trunk/Ohana/src/addstar/src/LoadDataSDSS.c	(revision 16810)
@@ -0,0 +1,47 @@
+# include "addstar.h"
+
+// examine the header sets and set the Image entries for the the valid images
+// there should only be a single data set (phu + table) in this file
+// each SDSS data set corresponds to 5 images (ugriz)
+int LoadDataSDSS (FILE *f, char *file, Image **images, int *nvalid, Stars **stars, int *Nstars, Header **headers, int *extsize, HeaderSet *headerSets, int Nimages) {
+
+  char *name;
+  int j, Nvalid, Nhead, Ndata, Nskip;
+  unsigned int Ninstars;
+  Stars *inStars;
+
+  if (images[0] == NULL) {
+    Nvalid = 0;
+    NVALID = 5;
+    ALLOCATE (images[0], Image, NVALID);
+  } else {
+    Nvalid = *nvalid;
+    NVALID = Nvalid + 5;
+    REALLOCATE (images[0], Image, NVALID);
+  }    
+
+  // find image rootname
+  name = filebasename (file);
+
+  // there is only one SDSS image per file (TRUE?)
+  Nhead = headerSets[0].extnum_head;
+
+  // XXX parse the information needed from the PHU header
+  if (VERBOSE) fprintf (stderr, "reading header for %s (%s)\n", headerSets[0].exthead, headerSets[0].extdata);
+
+  // advance the pointer to the start of the corresponding table block
+  Ndata = headerSets[0].extnum_data;
+  Nskip = 0;
+  for (j = 0; j < Ndata; j++) {
+    Nskip += extsize[j];
+  }
+  fseek (f, Nskip, SEEK_SET); 
+	 
+  inStars = ReadStarsSDSS (f, name, headers[Nhead], headers[Ndata], images[0], &Nvalid, &Ninstars);
+  *stars = MergeStars (*stars, Nstars, inStars, Ninstars);
+
+  free (name);
+  *nvalid = Nvalid;
+  return (TRUE);
+}
+
Index: /trunk/Ohana/src/addstar/src/LoadHeaders.c
===================================================================
--- /trunk/Ohana/src/addstar/src/LoadHeaders.c	(revision 16810)
+++ /trunk/Ohana/src/addstar/src/LoadHeaders.c	(revision 16810)
@@ -0,0 +1,40 @@
+# include "addstar.h"
+
+// load all of the headers, jump in file to skip data segments
+Header **LoadHeaders (FILE *f, int *mode, int *Nheaders) {
+
+  int i, status, Nskip, NHEADERS;
+  Header **headers;
+
+  /* we need to examine the extensions to determine the headers and the data */
+  NHEADERS = 10;
+  ALLOCATE (headers, Header *, NHEADERS);
+
+  // load all headers into memory
+  for (i = 0;; i++) {
+    ALLOCATE (headers[i], Header, 1);
+    status = gfits_fread_header (f, headers[i]);
+    if (!status) { 
+      *Nheaders = i;
+      return (headers);
+    }
+
+    // check the mode for this file
+    if (i == 0) {
+      *mode = GetFileMode (headers[0]);
+      if ((*mode == SIMPLE_CMP) || (*mode == MOSAIC_CMP)) {
+	*Nheaders = i;
+	return (headers);
+      }
+    }
+
+    // advance to the next header
+    Nskip = gfits_data_size (headers[i]);
+    fseek (f, Nskip, SEEK_CUR); 
+    if (i == NHEADERS - 1) {
+      NHEADERS += 10;
+      REALLOCATE (headers, Header *, NHEADERS);
+    }
+  }
+}
+
Index: /trunk/Ohana/src/addstar/src/LoadStars.c
===================================================================
--- /trunk/Ohana/src/addstar/src/LoadStars.c	(revision 16809)
+++ /trunk/Ohana/src/addstar/src/LoadStars.c	(revision 16810)
@@ -1,8 +1,8 @@
 # include "addstar.h"
 
-Stars *LoadStars (char *filename, int *Nstars, Image **images, int *Nimages, int photcode) {
+Stars *LoadStars (char *filename, int *Nstars, Image **images, int *Nimages, AddstarClientOptions *options) {
 
-  int i, Nfile, Nheaders, NheaderSets, mode, *extsize;
-  char **file;
+  int i, Nfile, NFILE, Nheaders, NheaderSets, mode, *extsize;
+  char **file, line[1024];
   FILE *f;
   glob_t globList;
@@ -11,19 +11,41 @@
   HeaderSet *headerSets;
 
-  // parse the filename as a glob
-  globList.gl_offs = 0;
-  glob (filename, 0, NULL, &globList);
+  if (options[0].filelist) {
+    // read the list of input files from the supplied file
+    f = fopen (filename, "r");
+    if (f == NULL) {
+      fprintf (stderr, "can't read input list %s, giving up\n", filename);
+      exit (1);
+    }
 
-  // if the glob does not match, save the literal word:
-  // otherwise save all glob matches
-  if (globList.gl_pathc == 0) {
-    Nfile = 1;
-    ALLOCATE (file, char *, Nfile);
-    file[0] = strcreate (filename);
+    NFILE = 10;
+    ALLOCATE (file, char *, NFILE);
+    for (i = 0; (fscanf (f, "%s", line) != EOF); i++) {
+      // filename limited to 1024 chars
+      fprintf (stderr, "file: %s\n", line);
+      file[i] = strcreate (line);
+      if (i == NFILE - 1) {
+	NFILE += 10;
+	REALLOCATE (file, char *, NFILE);
+      }
+    }
+    Nfile = i;
   } else {
-    Nfile = globList.gl_pathc;
-    ALLOCATE (file, char *, Nfile);
-    for (i = 0; i < Nfile; i++) {
-      file[i] = strcreate (globList.gl_pathv[i]);
+    // parse the filename as a glob
+    globList.gl_offs = 0;
+    glob (filename, 0, NULL, &globList);
+
+    // if the glob does not match, save the literal word:
+    // otherwise save all glob matches
+    if (globList.gl_pathc == 0) {
+      Nfile = 1;
+      ALLOCATE (file, char *, Nfile);
+      file[0] = strcreate (filename);
+    } else {
+      Nfile = globList.gl_pathc;
+      ALLOCATE (file, char *, Nfile);
+      for (i = 0; i < Nfile; i++) {
+	file[i] = strcreate (globList.gl_pathv[i]);
+      }
     }
   }
@@ -54,10 +76,27 @@
 
     /* supplied photcode is incompatible with multi-chip images */
-    if ((NheaderSets > 1) && photcode) {
+    if ((NheaderSets > 1) && options[0].photcode) {
       fprintf (stderr, "ERROR: photcode cannot be supplied to multi-chip images -- manually adjust the headers\n");
       exit (1);
     }
 
+    if (headerSets[0].exttype && !strcmp (headerSets[0].exttype, "SDSS_OBJ")) {
+      LoadDataSDSS (f, file[i], images, Nimages, &stars, Nstars, headers, extsize, headerSets, NheaderSets);
+      continue;
+    }
+
     LoadData (f, file[i], images, Nimages, &stars, Nstars, headers, extsize, headerSets, NheaderSets);
+
+    // XXX add a function to (optionally) load the extended source measurements
+    # if (0)
+    if (extSources) {
+      // not sure how to link the measurements here to the psf measurements above (though there is an ID in the det list)
+      LoadDataXSRC (f, file[i], images, Nimages, &stars, Nstars, headers, extsize, headerSets, NheaderSets);
+    }
+    if (extFits) {
+      LoadDataXFIT (f, file[i], images, Nimages, &stars, Nstars, headers, extsize, headerSets, NheaderSets);
+    }
+    # endif
+
   }
 
@@ -73,192 +112,2 @@
 }
 
-// load all of the headers, jump in file to skip data segments
-Header **LoadHeaders (FILE *f, int *mode, int *Nheaders) {
-
-  int i, status, Nskip, NHEADERS;
-  Header **headers;
-
-  /* we need to examine the extensions to determine the headers and the data */
-  NHEADERS = 10;
-  ALLOCATE (headers, Header *, NHEADERS);
-
-  // load all headers into memory
-  for (i = 0;; i++) {
-    ALLOCATE (headers[i], Header, 1);
-    status = gfits_fread_header (f, headers[i]);
-    if (!status) { 
-      *Nheaders = i;
-      return (headers);
-    }
-
-    // check the mode for this file
-    if (i == 0) {
-      *mode = GetFileMode (headers[0]);
-      if ((*mode == SIMPLE_CMP) || (*mode == MOSAIC_CMP)) {
-	*Nheaders = i;
-	return (headers);
-      }
-    }
-
-    // advance to the next header
-    Nskip = gfits_data_size (headers[i]);
-    fseek (f, Nskip, SEEK_CUR); 
-    if (i == NHEADERS - 1) {
-      NHEADERS += 10;
-      REALLOCATE (headers, Header *, NHEADERS);
-    }
-  }
-}
-
-HeaderSet *MatchHeaders (int **extsize, int *nimage, int mode, Header **headers, int Nheaders) {
-
-  int i, j, Nimage, NIMAGE;
-  char extname[80], exttype[80], exthead[80];
-  HeaderSet *headerSets;
-
-  ALLOCATE (extsize[0], int, Nheaders);
-
-  Nimage = 0;
-  NIMAGE = 10;
-  ALLOCATE (headerSets, HeaderSet, NIMAGE);
-
-  // what is the mode of the first header (ie, do we have a PHU DIS image?)
-  mode = GetFileMode (headers[0]);
-
-  if (mode == MOSAIC_MEF) {
-    headerSets[Nimage].exthead     = strcreate ("PHU");
-    headerSets[Nimage].extdata     = strcreate ("NONE");
-    headerSets[Nimage].extnum_data = -1;
-    headerSets[Nimage].extnum_head =  0;
-    Nimage ++;
-  }
-
-  // now examine the headers, count the table entries, find corresponding headers
-  for (i = 0; i < Nheaders; i++) {
-    if (mode == SIMPLE_CMP) {
-      extsize[0][i] = headers[i][0].size;
-    } else {
-      extsize[0][i] = headers[i][0].size + gfits_data_size (headers[i]);
-    }
-    gfits_scan (headers[i], "EXTTYPE", "%s", 1, exttype);
-
-    if (!strcmp (exttype, "SMPDATA")) goto keep;
-    if (!strcmp (exttype, "PS1_DEV_0")) goto keep;
-    if (!strcmp (exttype, "PS1_DEV_1")) goto keep;
-    continue;
-
-  keep:
-    headerSets[Nimage].exttype = strcreate (exttype);
-
-    gfits_scan (headers[i], ExtnameKeyword, "%s", 1, extname);
-    gfits_scan (headers[i], "EXTHEAD", "%s", 1, exthead);
-
-    headerSets[Nimage].extdata     = strcreate (extname);
-    headerSets[Nimage].exthead     = strcreate (exthead);
-    headerSets[Nimage].extnum_data = i;
-    headerSets[Nimage].extnum_head = -1;
-
-    // find the matching exthead entry
-    for (j = 0; j < Nheaders; j++) {
-      if (!gfits_scan (headers[j], ExtnameKeyword, "%s", 1, extname)) continue;
-      if (strcmp (extname, headerSets[Nimage].exthead)) continue;
-      headerSets[Nimage].extnum_head = j;
-      break;
-    }
-
-    // skip or crash on table with missing matching header?
-    if (headerSets[Nimage].extnum_head == -1) {
-      return NULL;
-    }
-    Nimage ++;
-    if (Nimage == NIMAGE) {
-      NIMAGE += 10;
-      REALLOCATE (headerSets, HeaderSet, NIMAGE);
-    }
-  }
-
-  // some old format files did not write EXTTYPE.  they have a single table in the first
-  // extension matched to the header in the PHU
-  if (Nimage == 0) {
-    extsize[0][0] = headers[0][0].size + gfits_data_size (headers[0]);
-    extsize[0][1] = headers[1][0].size + gfits_data_size (headers[1]);
-    gfits_scan (headers[1], ExtnameKeyword, "%s", 1, extname);
-    if (!strcmp (extname, "SMPFILE")) {
-      headerSets[Nimage].extdata     = strcreate (extname);
-      headerSets[Nimage].exttype     = strcreate ("SMPDATA");
-      headerSets[Nimage].exthead     = strcreate ("PHU");
-      headerSets[Nimage].extnum_head = 0;
-      headerSets[Nimage].extnum_data = 1;
-      Nimage = 1;
-    }
-  }
-  
-  *nimage = Nimage;
-  return (headerSets);
-}
-
-// examine the header sets and set the Image entries for the the valid images
-int LoadData (FILE *f, char *file, Image **images, int *nvalid, Stars **stars, int *Nstars, Header **headers, int *extsize, HeaderSet *headerSets, int Nimages) {
-
-  char *name;
-  int i, j, Nvalid, Nhead, Ndata, Nskip;
-  Stars *inStars;
-
-  if (images[0] == NULL) {
-    Nvalid = 0;
-    NVALID = 10;
-    ALLOCATE (images[0], Image, NVALID);
-  } else {
-    Nvalid = *nvalid;
-    NVALID = Nvalid + 10;
-    REALLOCATE (images[0], Image, NVALID);
-  }    
-
-  // find image rootname
-  name = filebasename (file);
-
-  // now run through the images, interpret the headers and read the stars
-  for (i = 0; i < Nimages; i++) {
-    Nhead = headerSets[i].extnum_head;
-
-    if (VERBOSE) fprintf (stderr, "reading header for %s (%s)\n", headerSets[i].exthead, headerSets[i].extdata);
-    if (!ReadImageHeader (headers[Nhead], &images[0][Nvalid], 0)) {
-      fprintf (stderr, "skipping %s\n", headerSets[i].exthead);
-      continue;
-    }
-
-    // XXX use something to set the chip name? EXTNAME?
-    if (!strcmp(headerSets[i].exthead, "PHU") && (Nimages == 1)) {
-      snprintf (images[0][Nvalid].name, 64, "%s", name);
-    } else {
-      snprintf (images[0][Nvalid].name, 64, "%s[%s]", name, headerSets[i].exthead);
-    }
-
-    // skip the table if there is no data segment (eg, mosaic WRP image)
-    if (!strcmp(headerSets[i].extdata, "NONE")) {
-      Nvalid++;
-      if (Nvalid == NVALID) {
-	NVALID += 10;
-	REALLOCATE (images[0], Image, NVALID);
-      }
-      continue;
-    }
-
-    // advance the pointer to the start of the corresponding table block
-    Ndata = headerSets[i].extnum_data;
-    Nskip = 0;
-    for (j = 0; j < Ndata; j++) {
-      Nskip += extsize[j];
-    }
-    fseek (f, Nskip, SEEK_SET); 
-	 
-    inStars = ReadStarsFITS (f, headers[Nhead], headers[Ndata], &images[0][Nvalid].nstar);
-    inStars = FilterStars (inStars, &images[0][Nvalid]);
-    *stars = MergeStars (*stars, Nstars, inStars, images[0][Nvalid].nstar);
-    Nvalid++;
-  }
-  free (name);
-  *nvalid = Nvalid;
-  return (TRUE);
-}
-
Index: /trunk/Ohana/src/addstar/src/MatchHeaders.c
===================================================================
--- /trunk/Ohana/src/addstar/src/MatchHeaders.c	(revision 16810)
+++ /trunk/Ohana/src/addstar/src/MatchHeaders.c	(revision 16810)
@@ -0,0 +1,104 @@
+# include "addstar.h"
+
+// XXX largely psphot specific
+
+HeaderSet *MatchHeaders (int **extsize, int *nimage, int mode, Header **headers, int Nheaders) {
+
+  int i, j, Nimage, NIMAGE;
+  char extname[80], exttype[80], exthead[80];
+  HeaderSet *headerSets;
+
+  ALLOCATE (extsize[0], int, Nheaders);
+
+  Nimage = 0;
+  NIMAGE = 10;
+  ALLOCATE (headerSets, HeaderSet, NIMAGE);
+
+  // what is the mode of the first header (ie, do we have a PHU DIS image?)
+  mode = GetFileMode (headers[0]);
+
+  if (mode == MOSAIC_MEF) {
+    headerSets[Nimage].exthead     = strcreate ("PHU");
+    headerSets[Nimage].extdata     = strcreate ("NONE");
+    headerSets[Nimage].extnum_data = -1;
+    headerSets[Nimage].extnum_head =  0;
+    Nimage ++;
+  }
+
+  if (mode == SDSS_OBJ) {
+    // XXX these should have two headers (phu + table)
+    assert (Nheaders == 2);
+    headerSets[0].extdata     = strcreate ("SDSS_OBJ");
+    headerSets[0].exttype     = strcreate ("SDSS_OBJ");
+    headerSets[0].exthead     = strcreate ("PHU");
+    headerSets[0].extnum_head = 0;
+    headerSets[0].extnum_data = 1;
+    extsize[0][0] = headers[0][0].size;
+    *nimage = 1;
+    return headerSets;
+  }
+
+  // now examine the headers, count the table entries, find corresponding headers
+  for (i = 0; i < Nheaders; i++) {
+    if (mode == SIMPLE_CMP) {
+      extsize[0][i] = headers[i][0].size;
+    } else {
+      extsize[0][i] = headers[i][0].size + gfits_data_size (headers[i]);
+    }
+
+    gfits_scan (headers[i], "EXTTYPE", "%s", 1, exttype);
+    if (!strcmp (exttype, "SMPDATA")) goto keep;
+    if (!strcmp (exttype, "PS1_DEV_0")) goto keep;
+    if (!strcmp (exttype, "PS1_DEV_1")) goto keep;
+    continue;
+
+  keep:
+    headerSets[Nimage].exttype = strcreate (exttype);
+
+    gfits_scan (headers[i], ExtnameKeyword, "%s", 1, extname);
+    gfits_scan (headers[i], "EXTHEAD", "%s", 1, exthead);
+
+    headerSets[Nimage].extdata     = strcreate (extname);
+    headerSets[Nimage].exthead     = strcreate (exthead);
+    headerSets[Nimage].extnum_data = i;
+    headerSets[Nimage].extnum_head = -1;
+
+    // find the matching exthead entry
+    for (j = 0; j < Nheaders; j++) {
+      if (!gfits_scan (headers[j], ExtnameKeyword, "%s", 1, extname)) continue;
+      if (strcmp (extname, headerSets[Nimage].exthead)) continue;
+      headerSets[Nimage].extnum_head = j;
+      break;
+    }
+
+    // skip or crash on table with missing matching header?
+    if (headerSets[Nimage].extnum_head == -1) {
+      return NULL;
+    }
+    Nimage ++;
+    if (Nimage == NIMAGE) {
+      NIMAGE += 10;
+      REALLOCATE (headerSets, HeaderSet, NIMAGE);
+    }
+  }
+
+  // some old format files did not write EXTTYPE.  they have a single table in the first
+  // extension matched to the header in the PHU
+  if (Nimage == 0) {
+    extsize[0][0] = headers[0][0].size + gfits_data_size (headers[0]);
+    extsize[0][1] = headers[1][0].size + gfits_data_size (headers[1]);
+    gfits_scan (headers[1], ExtnameKeyword, "%s", 1, extname);
+    if (!strcmp (extname, "SMPFILE")) {
+      headerSets[Nimage].extdata     = strcreate (extname);
+      headerSets[Nimage].exttype     = strcreate ("SMPDATA");
+      headerSets[Nimage].exthead     = strcreate ("PHU");
+      headerSets[Nimage].extnum_head = 0;
+      headerSets[Nimage].extnum_data = 1;
+      Nimage = 1;
+    }
+  }
+  
+  *nimage = Nimage;
+  return (headerSets);
+}
+
Index: /trunk/Ohana/src/addstar/src/ReadImageHeader.c
===================================================================
--- /trunk/Ohana/src/addstar/src/ReadImageHeader.c	(revision 16809)
+++ /trunk/Ohana/src/addstar/src/ReadImageHeader.c	(revision 16810)
@@ -8,4 +8,7 @@
   double tmp, sec, Cerror, ZeroPt;
   char *c, photname[64], line[80];
+
+  // zero out the entire image structure
+  memset (image, 0, sizeof(Image));
 
   /* get astrometry information */
@@ -132,6 +135,9 @@
 
   tmp = 0;
-  gfits_scan (header, "TRATE",   "%lf", 1, &tmp);
-  image[0].trate = 10000 * tmp;
+  if (gfits_scan (header, "TRATE",   "%lf", 1, &tmp)) {
+    image[0].trate = 10000 * tmp;
+  } else {
+    image[0].trate = 0.0;
+  }
 
   image[0].secz = NAN;
@@ -156,5 +162,4 @@
   image[0].Xm   = NAN_S_SHORT;
   image[0].code = 0;
-  memset (image[0].dummy, 0, sizeof(image[0].dummy));
 
   /* find expected number of stars */
Index: /trunk/Ohana/src/addstar/src/ReadSDSSHeader.c
===================================================================
--- /trunk/Ohana/src/addstar/src/ReadSDSSHeader.c	(revision 16810)
+++ /trunk/Ohana/src/addstar/src/ReadSDSSHeader.c	(revision 16810)
@@ -0,0 +1,58 @@
+# include "addstar.h"
+
+// determine relevant image information from the PHU header
+int ReadSDSSHeader (Header *header, Image *image, int photcode) {
+
+  int Nastro, ccdnum, hour, min, Nx, Ny;
+  double tmp, sec, Cerror, ZeroPt;
+  char *c, photname[64], line[80];
+
+  // I need to convert a single obj file into a set of 5 images
+
+  // XXX how do I define the image boundaries?
+  // image[0].coords
+  // image[0].NX, NY
+
+  // image[0].tzero : MJD_U,G,R,I,Z in table header
+
+  // test astrometry quality? 
+  // image[0].cerror : ??
+ 
+  // set photcodes for the 5 images (SDSS_U,G,R,I,Z)
+  photcode = GetPhotcodeCodebyName ("SDSS_U");
+  if (photcode == 0) {
+    fprintf (stderr, "photcode %s not found in photcode table\n", photname);
+    return (FALSE);
+  }
+  image[0].photcode = photcode;
+
+  // calculate this from : C_OBS, TRACKING, and NY
+  image[0].exptime = tmp;
+  
+  // image[0].apmifit = tmp;
+  // image[0].dapmifit = tmp;
+  // image[0].detection_limit 
+  // image[0].saturation_limit
+  // image[0].fwhm_x : SEEING_U, etc in table header
+  // image[0].fwhm_y : SEEING_U, etc in table header
+
+  // XXX longitude and latitude are known for SDSS
+  // jd = ohana_sec_to_jd (image[0].tzero);
+  // image[0].sidtime  = ohana_lst (jd, Longitude);
+  // image[0].latitude = Latitude;
+
+  // image[0].trate : from C_OBS
+  // image[0].secz : ??
+  // image[0].ccdnum : COLNUM?
+
+  // secz is in units milli-airmass
+  image[0].Mcal = 0.0;
+  image[0].Xm   = NAN_S_SHORT;
+  image[0].code = 0;
+  memset (image[0].dummy, 0, sizeof(image[0].dummy));
+
+  // NAXIS2 for table:
+  // image[0].nstar
+
+  return (TRUE);
+}
Index: /trunk/Ohana/src/addstar/src/ReadStarsFITS.c
===================================================================
--- /trunk/Ohana/src/addstar/src/ReadStarsFITS.c	(revision 16809)
+++ /trunk/Ohana/src/addstar/src/ReadStarsFITS.c	(revision 16810)
@@ -72,9 +72,7 @@
     if ((smpdata[i].M >= ZeroPt) || isnan(smpdata[i].M)) {
       stars[i].M    = NAN;
-      stars[i].Mgal = NAN;
       stars[i].Map  = NAN;
     } else {
       stars[i].M    = smpdata[i].M;
-      stars[i].Mgal = smpdata[i].M;
       stars[i].Map  = smpdata[i].M;
     }
@@ -122,6 +120,6 @@
     stars[i].df      = ps1data[i].df;
 
-    stars[i].psfProb = ps1data[i].psfProb;
-    stars[i].psfQual = ps1data[i].psfQual;
+    stars[i].psfChisq = ps1data[i].psfChisq;
+    stars[i].psfQual  = ps1data[i].psfQual;
 
     stars[i].detID   = ps1data[i].detID;
@@ -150,5 +148,4 @@
     /* these are not used */
     stars[i].Map     = NAN;
-    stars[i].Mgal    = NAN;
     stars[i].dophot  = 0;
   }    
@@ -190,5 +187,5 @@
     stars[i].df      = ps1data[i].df;
 
-    stars[i].psfProb   = ps1data[i].psfProb;
+    stars[i].psfChisq  = ps1data[i].psfChisq;
     stars[i].psfQual   = ps1data[i].psfQual;
     stars[i].crNsigma  = ps1data[i].crNsigma;
@@ -225,5 +222,4 @@
     /* these are not used */
     stars[i].Map     = NAN;
-    stars[i].Mgal    = NAN;
     stars[i].dophot  = 0;
   }    
Index: /trunk/Ohana/src/addstar/src/ReadStarsSDSS.c
===================================================================
--- /trunk/Ohana/src/addstar/src/ReadStarsSDSS.c	(revision 16810)
+++ /trunk/Ohana/src/addstar/src/ReadStarsSDSS.c	(revision 16810)
@@ -0,0 +1,285 @@
+# include "addstar.h"
+# define NFILTER 5
+# define dCOS(A)   ((double) cos ((double)RAD_DEG*A))
+# define dSIN(A)   ((double) sin ((double)RAD_DEG*A))
+
+# define GET_COLUMN_5(NAME,TYPE) \
+  TYPE *NAME; \
+  NAME = (TYPE *) gfits_get_bintable_column_data (table.header, &table, #NAME, type, &Nrow, &Ncol); \
+  assert (NAME); assert (!strcmp (type, #TYPE)); assert (Nrow == Nstars); assert (Ncol == NFILTER);
+
+# define GET_COLUMN_1(NAME,TYPE) \
+  TYPE *NAME; \
+  NAME = (TYPE *) gfits_get_bintable_column_data (table.header, &table, #NAME, type, &Nrow, &Ncol); \
+  assert (NAME); assert (!strcmp (type, #TYPE)); assert (Nrow == Nstars); assert (Ncol == 1);
+
+/* grab named photcode */
+# define NAMED_PHOTCODE_AND_ZP(CODE,ZP,NAME) { \
+  PhotCode *code; \
+  code = GetPhotcodebyName (NAME); \
+  if (code == NULL) { \
+    fprintf (stderr, "ERROR:  photcode %s not found in photcode table\n", NAME); \
+    exit (0); } \
+  CODE = code[0].code; \
+  ZP = 0.001*code[0].C; }
+
+// XXX NOTE : as of 2008.02.27, the zero point is still carried internally in millimags
+
+// given a file with the pointer at the start of the table block and the 
+// corresponding image header, load the stars from the table
+Stars *ReadStarsSDSS (FILE *f, char *name, Header *header, Header *in_theader, Image *images, int *nimages, unsigned int *nstars) {
+
+  int i, j, N, Nskip, Nstars, camcol;
+  char type[80];
+  Header theader;
+  FTable table;
+  Stars *stars;
+  double clockRate, mjd[5], jd, sidtime, alt, az;
+  float seeing[5], photErr[5], zeropt[5], ZeroPt;
+  time_t tzero[5];
+  char filtname[16][5];
+  int photcode[5];
+  int Nrow, Ncol; // used in the GET_COLUMN_1,5 macros above
+  
+  if (in_theader == NULL) {
+    table.header = &theader;
+    if (!gfits_fread_header (f, table.header)) Shutdown ("ERROR: can't read table header");
+  } else {
+    table.header = in_theader;
+    Nskip = in_theader[0].size;
+    fseek (f, Nskip, SEEK_CUR); 
+  }
+
+  /* load the table data */
+  if (!gfits_fread_ftable_data (f, &table)) {
+    fprintf (stderr, "ERROR: can't read table header\n");
+    exit (1);
+  }
+
+  strcpy (filtname[0], "u");
+  strcpy (filtname[1], "g");
+  strcpy (filtname[2], "r");
+  strcpy (filtname[3], "i");
+  strcpy (filtname[4], "z");
+
+  NAMED_PHOTCODE_AND_ZP (photcode[0], zeropt[0], "U_SDSS");
+  NAMED_PHOTCODE_AND_ZP (photcode[1], zeropt[1], "G_SDSS");
+  NAMED_PHOTCODE_AND_ZP (photcode[2], zeropt[2], "R_SDSS");
+  NAMED_PHOTCODE_AND_ZP (photcode[3], zeropt[3], "I_SDSS");
+  NAMED_PHOTCODE_AND_ZP (photcode[4], zeropt[4], "Z_SDSS");
+
+  // various header values needed to calculate per-star data below
+  gfits_scan (header, "C_OBS", "%lf", 1, &clockRate); // value in header is usec / unbinned row
+  clockRate *= 1e-6; // convert to seconds / unbinned row
+
+  gfits_scan (table.header, "MJD_U", "%lf", 1, &mjd[0]);
+  gfits_scan (table.header, "MJD_G", "%lf", 1, &mjd[1]);
+  gfits_scan (table.header, "MJD_R", "%lf", 1, &mjd[2]);
+  gfits_scan (table.header, "MJD_I", "%lf", 1, &mjd[3]);
+  gfits_scan (table.header, "MJD_Z", "%lf", 1, &mjd[4]);
+  tzero[0] = ohana_mjd_to_sec (mjd[0]);
+  tzero[1] = ohana_mjd_to_sec (mjd[1]);
+  tzero[2] = ohana_mjd_to_sec (mjd[2]);
+  tzero[3] = ohana_mjd_to_sec (mjd[3]);
+  tzero[4] = ohana_mjd_to_sec (mjd[4]);
+
+  gfits_scan (table.header, "SEEING_U", "%f", 1, &seeing[0]);
+  gfits_scan (table.header, "SEEING_G", "%f", 1, &seeing[1]);
+  gfits_scan (table.header, "SEEING_R", "%f", 1, &seeing[2]);
+  gfits_scan (table.header, "SEEING_I", "%f", 1, &seeing[3]);
+  gfits_scan (table.header, "SEEING_Z", "%f", 1, &seeing[4]);
+
+  gfits_scan (table.header, "PSFERR_U", "%f", 1, &photErr[0]);
+  gfits_scan (table.header, "PSFERR_G", "%f", 1, &photErr[1]);
+  gfits_scan (table.header, "PSFERR_R", "%f", 1, &photErr[2]);
+  gfits_scan (table.header, "PSFERR_I", "%f", 1, &photErr[3]);
+  gfits_scan (table.header, "PSFERR_Z", "%f", 1, &photErr[4]);
+
+  gfits_scan (header, "CAMCOL", "%d", 1, &camcol); // value in header is usec / unbinned row
+
+  ZeroPt = GetZeroPoint();
+
+  // create a Star entry for each filter and detection
+  Nstars = table.header[0].Naxis[1];
+  ALLOCATE (stars, Stars, NFILTER*Nstars);
+
+  GET_COLUMN_5 (rowc, float);
+  GET_COLUMN_5 (colc, float);
+  GET_COLUMN_5 (sky, float);
+  GET_COLUMN_5 (psfCounts, float);
+  GET_COLUMN_5 (fiberCounts, float);
+  GET_COLUMN_5 (offsetRa, float);
+  GET_COLUMN_5 (offsetDec, float);
+  GET_COLUMN_5 (flags, int);
+  GET_COLUMN_5 (flags2, int);
+
+  GET_COLUMN_5 (prob_psf, float);
+
+  GET_COLUMN_1 (ra, double);
+  GET_COLUMN_1 (dec, double);
+
+  GET_COLUMN_5 (rowcErr, float);
+  GET_COLUMN_5 (colcErr, float);
+  GET_COLUMN_5 (skyErr, float);
+  GET_COLUMN_5 (psfCountsErr, float);
+
+  // the value of stars[].M is supposed to be the instrumental magnitude offset by the
+  // default zero point 25.0 (-2.5*log_10(counts/sec) + ZeroPt).  The magnitude reported
+  // by SDSS is the calibrated mag: -2.5*log_10(counts/sec) + C_0.  Adjust magnitudes to
+  // compensate for the difference.
+
+  for (i = 0; i < Nstars; i++) {
+    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].flags     = flags[N] & 0x0000ffff; // XXX totally arbitrary bits
+      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 ?
+
+      // longitude and latitude for SDSS:
+      // Latitude 32° 46' 49.30" N, Longitude 105° 49' 13.50" W
+      // longitude = 105.820419312 deg = 7.05469417
+      // latitude = 32.7803611755 deg
+
+      double Longitude = 7.05469417;   // hours (+ = W)
+      double Latitude = 32.7803611755; // degrees
+
+      jd = ohana_sec_to_jd (stars[N].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;
+    }
+  }    
+
+  for (i = 0; i < NFILTER; i++) {
+
+    N = i + *nimages;
+    
+    // XXX for now, we define a totally fake coordinate system centered on the first listed star
+    strcpy (images[N].coords.ctype, "RA---TAN");
+    
+    images[N].coords.crval1 = stars[0].R;
+    images[N].coords.crval2 = stars[0].D;
+    
+    images[N].coords.crpix1 = stars[0].X;
+    images[N].coords.crpix2 = stars[0].Y;
+    images[N].coords.cdelt1 = images[N].coords.cdelt2 = 0.4 / 3600.0;
+
+    images[N].coords.pc1_1 = 0.0;
+    images[N].coords.pc1_2 = 1.0;
+    images[N].coords.pc2_1 = 1.0;
+    images[N].coords.pc2_2 = 0.0;
+
+    images[N].coords.Npolyterms = 0;
+    memset (images[N].coords.polyterms, 0, 2*7*sizeof(float));
+
+    images[N].NX = 2048;
+    images[N].NY = 1490;
+
+    images[N].tzero = tzero[i];
+    images[N].cerror = 0.0;
+ 
+    // set photcodes for the 5 images (SDSS_U,G,R,I,Z)
+    images[N].photcode = photcode[i];
+
+    // calculate this from : C_OBS, TRACKING, and NY
+    images[N].exptime = 2048*clockRate;
+  
+    images[N].apmifit = 0.0;
+    images[N].dapmifit = 0.0;
+    images[N].detection_limit = 0.0; 
+    images[N].saturation_limit = 0.0;
+    images[N].fwhm_x = seeing[i];
+    images[N].fwhm_y = seeing[i];
+
+    // XXX longitude and latitude are known for SDSS
+    // SDSS is at : Latitude 32° 46' 49.30" N, Longitude 105° 49' 13.50" W
+    // longitude = 105.820419312 deg = 7.05469417
+    // latitude = 32.7803611755 deg
+
+    double Longitude = 7.05469417;   // hours (+ = W)
+    double Latitude = 32.7803611755; // degrees
+
+    jd = ohana_sec_to_jd (images[N].tzero);
+    images[N].sidtime  = ohana_lst (jd, Longitude);
+    images[N].latitude = Latitude;
+
+    altaz (&alt, &az, 15.0*images[N].sidtime - images[N].coords.crval1, images[N].coords.crval2, Latitude);
+
+    images[N].trate = clockRate * 1e-4;
+    images[N].secz = stars[0].airmass;
+    images[N].ccdnum = camcol;
+
+    // secz is in units milli-airmass
+    images[N].Mcal = 0.0;
+    images[N].Xm   = NAN_S_SHORT;
+    images[N].code = 0;
+
+    images[N].nstar = Nstars;
+  
+    images[N].imageID = N;
+    images[N].externID = 0;
+    images[N].sourceID = 0;
+
+    // save the filename
+    snprintf (images[N].name, 64, "%s[%s]", name, filtname[i]);
+  }
+
+  *nimages += NFILTER;
+  *nstars = Nstars*NFILTER;
+  return (stars);
+}
+
+// ha/dec -> alt/az
+int altaz (double *alt, double *az, double ha, double dec, double latitude) {
+
+  double sind, sinh, cosh;
+
+  sind = dSIN (dec) * dSIN (latitude) + dCOS (dec) * dCOS (ha) * dCOS (latitude);
+  *alt  = DEG_RAD * asin (sind);
+
+  sinh = - dCOS (dec) * dSIN (ha);
+  cosh =   dSIN (dec) * dCOS (latitude) - dCOS (dec) * dCOS (ha) * dSIN (latitude);
+
+  *az = DEG_RAD * atan2 (sinh, cosh);
+
+  // I may need to use the parallactic angle to get the right plate rotation...
+  // sinh = -dCOS(az) * dSIN(alt) * dSIN(ha) * dSIN(latitude) + dSIN(az) * dSIN(alt) * dCOS(ha) - dSIN(ha) * dCOS(alt) * dCOS(latitude);
+  // cosh = -dSIN(az) * dSIN(ha) * dSIN(latitude) - dCOS(az) * dCOS(ha);
+  // rot = -DEG_RAD * atan2 (sinh, cosh);
+  return TRUE;
+}
Index: /trunk/Ohana/src/addstar/src/ReadStarsTEXT.c
===================================================================
--- /trunk/Ohana/src/addstar/src/ReadStarsTEXT.c	(revision 16809)
+++ /trunk/Ohana/src/addstar/src/ReadStarsTEXT.c	(revision 16810)
@@ -80,5 +80,11 @@
       stars[N].dophot = tmp;
 
-      dparse (&stars[N].Mgal, 7, &buffer[j*BYTES_STAR]);
+      // XXX I've removed the Mgal field from the measure.d table, and am using Map
+      // instead.  DVO has not to date been used to track and study objects which are
+      // extended, but it is about to.  Related to this, I have created the concept of two
+      // extended source attribute tables, to carry the information being measured by the
+      // IPP.
+
+      // 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]);
Index: /trunk/Ohana/src/addstar/src/SEDfit.c
===================================================================
--- /trunk/Ohana/src/addstar/src/SEDfit.c	(revision 16809)
+++ /trunk/Ohana/src/addstar/src/SEDfit.c	(revision 16810)
@@ -77,7 +77,7 @@
 
     // load the measurements for this source
-    m = incat[0].average[i].offset;
+    m = incat[0].average[i].measureOffset;
     Nphot = 0;
-    for (j = 0; j < incat[0].average[i].Nm; j++) {
+    for (j = 0; j < incat[0].average[i].Nmeasure; j++) {
       idx = table[0].hashcode[incat[0].measure[m+j].photcode];
       if (idx == -1) continue;
@@ -159,10 +159,10 @@
 
     // XXX for now, set the average mag data to NULL
-    outcat[0].average[Nave].Nm        = 0;
-    outcat[0].average[Nave].Nn        = 0;
-    outcat[0].average[Nave].Xp        = NAN_S_SHORT;
-    outcat[0].average[Nave].offset    = Nmeas;
-    outcat[0].average[Nave].missing   = -1;
-    outcat[0].average[Nave].code      = 0;
+    outcat[0].average[Nave].Nmeasure  	  = 0;
+    outcat[0].average[Nave].Nmissing  	  = 0;
+    outcat[0].average[Nave].Xp        	  = NAN_S_SHORT;
+    outcat[0].average[Nave].measureOffset = Nmeas;
+    outcat[0].average[Nave].missingOffset = -1;
+    outcat[0].average[Nave].code          = 0;
 
     for (j = 0; j < Nsec; j++) {
@@ -193,5 +193,4 @@
       outcat[0].measure[Nmeas].dt       = 0xffff;
 
-      outcat[0].measure[Nmeas].Mgal     = NAN;
       outcat[0].measure[Nmeas].airmass  = 0;
       outcat[0].measure[Nmeas].FWx      = NAN_S_SHORT;
@@ -199,5 +198,5 @@
       outcat[0].measure[Nmeas].theta    = NAN_S_SHORT;
 
-      outcat[0].average[Nave].Nm++;
+      outcat[0].average[Nave].Nmeasure++;
       Nmeas ++;
     }
Index: /trunk/Ohana/src/addstar/src/UpdateImageIDs.c
===================================================================
--- /trunk/Ohana/src/addstar/src/UpdateImageIDs.c	(revision 16810)
+++ /trunk/Ohana/src/addstar/src/UpdateImageIDs.c	(revision 16810)
@@ -0,0 +1,71 @@
+# include "addstar.h"
+
+int UpdateImageIDs (Stars *stars, int Nstars, Image *images, int Nimages) {
+
+  int i, status, isEmpty;
+  unsigned int imageID;
+  FITS_DB db;
+
+  /*** update the image table ***/
+  /* setup image table format and lock */
+  db.mode   = dvo_catalog_catmode (CATMODE);
+  db.format = dvo_catalog_catformat (CATFORMAT);
+  status    = dvo_image_lock (&db, ImageCat, 3600.0, LCK_XCLD);  // shorter timeout?
+  if (!status) Shutdown ("ERROR: failure to lock image catalog %s", db.filename);
+
+  /* load or create the image table */
+  if (db.dbstate == LCK_EMPTY) {
+    if (VERBOSE) fprintf (stderr, "can't find %s, creating a new one\n", ImageCat);
+    dvo_image_create (&db, GetZeroPoint());
+    isEmpty = TRUE;
+  } else {
+    /* position to start of file */
+    Fseek (db.f, 0, SEEK_SET);
+    if (!gfits_fread_header (db.f, &db.header)) {
+      Shutdown ("can't read image table phu %s", db.filename);
+    }
+    isEmpty = FALSE;
+  }
+
+  // note that imageID is unsigned int
+  status = gfits_scan (&db.header, "IMAGEID", "%u", 1, &imageID);
+  if (!status) {
+    status = gfits_scan (&db.header, "NIMAGES", "%u", 1, &imageID);
+  }
+
+  // XXX should the first image ID be 1, not 0?
+  if (imageID == 0) imageID = 1;
+
+  // update the image IDs already written to stars and images:
+  for (i = 0; i < Nimages; i++) {
+    images[0].imageID += imageID;
+  }
+
+  for (i = 0; i < Nstars; i++) {
+    stars[0].imageID += imageID;
+  }
+
+  imageID += Nimages;
+  status = gfits_modify (&db.header, "IMAGEID", "%u", 1, imageID);
+ 
+
+  if (isEmpty) {
+    dvo_image_addrows (&db, NULL, 0);
+    SetProtect (TRUE);
+    dvo_image_update (&db, VERBOSE);
+    SetProtect (FALSE);
+  } else {
+    // write just the PHU
+    // position to start of file
+    Fseek (db.f, 0, SEEK_SET);
+    SetProtect (TRUE);
+    if (!gfits_fwrite_header (db.f, &db.header)) {
+      Shutdown ("can't write image table phu %s", db.filename);
+    }
+    SetProtect (FALSE);
+  }
+
+  dvo_image_unlock (&db);
+
+  return TRUE;
+}
Index: /trunk/Ohana/src/addstar/src/addstar.c
===================================================================
--- /trunk/Ohana/src/addstar/src/addstar.c	(revision 16809)
+++ /trunk/Ohana/src/addstar/src/addstar.c	(revision 16810)
@@ -37,5 +37,9 @@
   switch (options.mode) {
     case M_IMAGE:
-      stars = LoadStars (argv[1], &Nstars, &images, &Nimages, options.photcode);
+      stars = LoadStars (argv[1], &Nstars, &images, &Nimages, &options);
+
+      // set and update the imageID sequence
+      UpdateImageIDs (stars, Nstars, images, Nimages);
+
       if ((DUMP != NULL) && !strcmp (DUMP, "rawstars")) dump_rawstars (stars, Nstars);
       for (i = 0; i < Nimages; i++) {
Index: /trunk/Ohana/src/addstar/src/addstarc.c
===================================================================
--- /trunk/Ohana/src/addstar/src/addstarc.c	(revision 16809)
+++ /trunk/Ohana/src/addstar/src/addstarc.c	(revision 16810)
@@ -21,5 +21,8 @@
     case M_IMAGE:
       /* load data */
-      stars = LoadStars (argv[1], &Nstars, &images, &Nimages, options.photcode);
+      stars = LoadStars (argv[1], &Nstars, &images, &Nimages, &options);
+
+      // set and update the imageID sequence
+      UpdateImageIDs (stars, Nstars, images, Nimages);
 
       /* send data to server */
Index: /trunk/Ohana/src/addstar/src/args.c
===================================================================
--- /trunk/Ohana/src/addstar/src/args.c	(revision 16809)
+++ /trunk/Ohana/src/addstar/src/args.c	(revision 16810)
@@ -37,4 +37,10 @@
   if ((N = get_argument (argc, argv, "-resort"))) {
     options.mode = M_RESORT;
+    remove_argument (N, &argc, argv);
+  }
+
+  options.filelist = FALSE;
+  if ((N = get_argument (argc, argv, "-list"))) {
+    options.filelist = TRUE;
     remove_argument (N, &argc, argv);
   }
Index: /trunk/Ohana/src/addstar/src/build_links.c
===================================================================
--- /trunk/Ohana/src/addstar/src/build_links.c	(revision 16809)
+++ /trunk/Ohana/src/addstar/src/build_links.c	(revision 16810)
@@ -2,5 +2,5 @@
 
 /* build the initial links assuming the table is sorted, 
-   not partial, and has a correct set of average[].offset,Nm values */
+   not partial, and has a correct set of average[].measureOffset,Nm values */
 int *init_measure_links (Average *average, int Naverage, Measure *measure, int Nmeasure) {
 
@@ -12,5 +12,5 @@
   ALLOCATE (next, int, Nmeasure);
   for (i = 0; i < Naverage; i++, N++) {
-    for (j = 0; j < average[i].Nm - 1; j++, N++) {
+    for (j = 0; j < average[i].Nmeasure - 1; j++, N++) {
       next[N] = N + 1;
       if (N >= Nmeasure) {
@@ -41,8 +41,8 @@
   ALLOCATE (next, int, Nmissing);
   for (i = 0; i < Naverage; i++) {
-    for (j = 0; j < average[i].Nn - 1; j++, N++) {
+    for (j = 0; j < average[i].Nmissing - 1; j++, N++) {
       next[N] = N + 1;
     }
-    if (average[i].Nn > 0) {
+    if (average[i].Nmissing > 0) {
       next[N] = -1;
       if (N >= Nmissing) {
@@ -57,5 +57,5 @@
 }
 
-/* average[].offset, average[].Nm are valid within an addstar run */
+/* average[].measureOffset, average[].Nmeasure are valid within an addstar run */
 int add_meas_link (Average *average, int *next, int Nmeasure, int NMEASURE) {
 
@@ -63,7 +63,7 @@
 
   /* if we have trouble, check validity of next[m] : m < Nmeasure */
-  m = average[0].offset;  
-
-  for (k = 0; k < average[0].Nm - 1; k++)  {
+  m = average[0].measureOffset;  
+
+  for (k = 0; k < average[0].Nmeasure - 1; k++)  {
     m = next[m];
     if (m >= NMEASURE) {
@@ -79,5 +79,5 @@
 
   if (m == -1) {
-    average[0].offset = Nmeasure;
+    average[0].measureOffset = Nmeasure;
   } else {
     next[m] = Nmeasure;
@@ -95,12 +95,12 @@
 
   /* there may be 0 Nmiss; this is not true for Nmeas */
-  if (average[0].Nn < 1) {
-    average[0].missing = Nmissing;
+  if (average[0].Nmissing < 1) {
+    average[0].missingOffset = Nmissing;
     next[Nmissing] = -1;
     return (TRUE);
   }
 
-  m = average[0].missing;  
-  for (k = 0; k < average[0].Nn - 1; k++) m = next[m];
+  m = average[0].missingOffset;  
+  for (k = 0; k < average[0].Nmissing - 1; k++) m = next[m];
   /* set up references */
   next[Nmissing] = -1;
@@ -125,16 +125,16 @@
   /* reset the Nm, offset values for average */
   for (i = 0; i < Naverage; i++) {
-    average[i].offset = -1;
-    average[i].Nm     =  0;
+    average[i].measureOffset = -1;
+    average[i].Nmeasure     =  0;
   }
 
   for (Nm = 0; Nm < Nmeasure; Nm++) {
     averef = measure[Nm].averef;
-    m = average[averef].offset;  
+    m = average[averef].measureOffset;  
     next[Nm] = -1;
 
     if (m == -1) { /* no links yet for source */
-      average[averef].offset = Nm;
-      average[averef].Nm     = 1;
+      average[averef].measureOffset = Nm;
+      average[averef].Nmeasure     = 1;
       continue;
     }
@@ -147,5 +147,5 @@
     }
 
-    average[averef].Nm = k + 2;
+    average[averef].Nmeasure = k + 2;
     next[m] = Nm;
     if (m >= Nmeasure) {
@@ -168,7 +168,7 @@
   ALLOCATE (tmpmeasure, Measure, Nmeasure);
   for (i = 0; i < Naverage; i++) {
-    n = average[i].offset;
-    average[i].offset = N;
-    for (k = 0; k < average[i].Nm; k++, N++) {
+    n = average[i].measureOffset;
+    average[i].measureOffset = N;
+    for (k = 0; k < average[i].Nmeasure; k++, N++) {
       tmpmeasure[N] = measure[n]; 
       tmpmeasure[N].averef = i;
@@ -189,7 +189,7 @@
   ALLOCATE (tmpmissing, Missing, Nmissing);
   for (i = 0; i < Naverage; i++) {
-    n = average[i].missing;
-    average[i].missing = N;
-    for (k = 0; k < average[i].Nn; k++, N++) {
+    n = average[i].missingOffset;
+    average[i].missingOffset = N;
+    for (k = 0; k < average[i].Nmissing; k++, N++) {
       tmpmissing[N] = missing[n]; 
       n = next[n];
Index: /trunk/Ohana/src/addstar/src/calibrate.c
===================================================================
--- /trunk/Ohana/src/addstar/src/calibrate.c	(revision 16809)
+++ /trunk/Ohana/src/addstar/src/calibrate.c	(revision 16810)
@@ -97,6 +97,6 @@
   }
 
-  m = average[0].offset;
-  for (i = 0; i < average[0].Nm; i++) {
+  m = average[0].measureOffset;
+  for (i = 0; i < average[0].Nmeasure; i++) {
     if (measure[m].photcode == CalC0) { 
       found0 = TRUE; 
Index: /trunk/Ohana/src/addstar/src/fakeimage.c
===================================================================
--- /trunk/Ohana/src/addstar/src/fakeimage.c	(revision 16809)
+++ /trunk/Ohana/src/addstar/src/fakeimage.c	(revision 16810)
@@ -130,5 +130,4 @@
     image[i+1].Xm   = NAN_S_SHORT;
     image[i+1].code = 0;
-    memset (image[i+1].dummy, 0, sizeof(image[i+1].dummy));
 
     image[i+1].nstar = 0;
@@ -189,7 +188,8 @@
   image[0].Xm   = NAN_S_SHORT;
   image[0].code = 0;
-  memset (image[0].dummy, 0, sizeof(image[0].dummy));
   image[0].nstar = 0;
   image[0].Myyyy = 0;
+
+  // XXX need to set the imageID here
 
   *Nimage = Nchips + 1;
Index: /trunk/Ohana/src/addstar/src/find_matches.c
===================================================================
--- /trunk/Ohana/src/addstar/src/find_matches.c	(revision 16809)
+++ /trunk/Ohana/src/addstar/src/find_matches.c	(revision 16810)
@@ -10,4 +10,5 @@
   int Nave, NAVE, Nmeas, NMEAS, Nmatch;
   int Nsecfilt, Nsec;
+  unsigned int objID, catID;
   Coords tcoords;
 
@@ -37,4 +38,8 @@
   NMEAS = Nmeas = catalog[0].Nmeasure;
   
+  // current max obj ID for this catalog
+  objID = catalog[0].objID;
+  catID = catalog[0].catID;
+
   /* project onto rectilinear grid with 1 arcsec pixels. the choice of ZEA projection has the
    * advantage that every point in R,D has a mapping to a unique X,Y.  However, note that not all
@@ -179,5 +184,5 @@
       catalog[0].measure[Nmeas].photFlags = stars[N].flags;
       catalog[0].measure[Nmeas].qPSF      = stars[N].psfQual;
-      catalog[0].measure[Nmeas].psfProb   = stars[N].psfProb;
+      catalog[0].measure[Nmeas].psfChisq  = stars[N].psfChisq;
       catalog[0].measure[Nmeas].crNsigma  = stars[N].crNsigma;
       catalog[0].measure[Nmeas].extNsigma = stars[N].extNsigma;
@@ -193,5 +198,5 @@
       catalog[0].measure[Nmeas].dYccd     = stars[N].dY;
 
-      catalog[0].measure[Nmeas].Mgal     = stars[N].Mgal;
+      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;
@@ -233,5 +238,5 @@
       /* Nm is updated, but not written out in -update mode (for existing entries)
 	 Nm is recalculated in build_meas_links if loaded table is not sorted */
-      catalog[0].average[n].Nm ++;
+      catalog[0].average[n].Nmeasure ++;
       Nmeas ++;
 
@@ -263,12 +268,12 @@
     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;
-    catalog[0].average[Nave].Nm        = 1;
-    catalog[0].average[Nave].Nn        = 0;
-    catalog[0].average[Nave].offset    = Nmeas;
-    catalog[0].average[Nave].missing   = -1;
-    catalog[0].average[Nave].code      = 0;
+    catalog[0].average[Nave].R         	   = stars[N].R;
+    catalog[0].average[Nave].D         	   = stars[N].D;
+    catalog[0].average[Nave].Xp        	   = 0;
+    catalog[0].average[Nave].Nmeasure      = 1;
+    catalog[0].average[Nave].Nmissing      = 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;
@@ -280,4 +285,8 @@
     catalog[0].average[Nave].P         = 0;
     catalog[0].average[Nave].dP        = 0;
+
+    catalog[0].average[Nave].objID     = objID;
+    catalog[0].average[Nave].catID     = catID;
+    objID ++;
 
     for (j = 0; j < Nsecfilt; j++) {
@@ -305,5 +314,5 @@
     catalog[0].measure[Nmeas].photFlags = stars[N].flags;
     catalog[0].measure[Nmeas].qPSF      = stars[N].psfQual;
-    catalog[0].measure[Nmeas].psfProb   = stars[N].psfProb;
+    catalog[0].measure[Nmeas].psfChisq  = stars[N].psfChisq;
     catalog[0].measure[Nmeas].crNsigma  = stars[N].crNsigma;
     catalog[0].measure[Nmeas].extNsigma = stars[N].extNsigma;
@@ -314,10 +323,10 @@
 
     catalog[0].measure[Nmeas].detID     = stars[N].detID;
-    catalog[0].measure[Nmeas].imageID   = options.imageID;
+    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].Mgal  	= stars[N].Mgal;
+    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;
@@ -359,4 +368,5 @@
 
   /* check if the catalog has changed?  if no change, no need to write */
+  catalog[0].objID    = objID; // new max value, save on catalog close
   catalog[0].Naverage = Nave;
   catalog[0].Nmeasure = Nmeas;
Index: /trunk/Ohana/src/addstar/src/find_matches_closest.c
===================================================================
--- /trunk/Ohana/src/addstar/src/find_matches_closest.c	(revision 16809)
+++ /trunk/Ohana/src/addstar/src/find_matches_closest.c	(revision 16810)
@@ -9,6 +9,7 @@
   int *N1, *N2,  *next_meas, *next_miss;
   int Nave, NAVE, Nmeas, NMEAS, Nmiss, NMISS, Nmatch;
+  int Nsecfilt, Nsec;
+  unsigned int objID, catID;
   Coords tcoords;
-  int Nsecfilt, Nsec;
 
   /* photcode data - must by of type DEP; options.photcode is equiv photcode for all input
@@ -37,4 +38,8 @@
   NMEAS = Nmeas = catalog[0].Nmeasure;
   NMISS = Nmiss = catalog[0].Nmissing;
+
+  // current max obj ID for this catalog
+  objID = catalog[0].objID;
+  catID = catalog[0].catID;
 
   /* project onto rectilinear grid with 1 arcsec pixels. the choice of ZEA projection has the
@@ -199,5 +204,5 @@
     catalog[0].measure[Nmeas].photFlags = stars[N].flags;
     catalog[0].measure[Nmeas].qPSF      = stars[N].psfQual;
-    catalog[0].measure[Nmeas].psfProb   = stars[N].psfProb;
+    catalog[0].measure[Nmeas].psfChisq  = stars[N].psfChisq;
     catalog[0].measure[Nmeas].crNsigma  = stars[N].crNsigma;
     catalog[0].measure[Nmeas].extNsigma = stars[N].extNsigma;
@@ -213,5 +218,5 @@
     catalog[0].measure[Nmeas].dYccd     = stars[N].dY;
 
-    catalog[0].measure[Nmeas].Mgal     = stars[N].Mgal;
+    catalog[0].measure[Nmeas].Map       = stars[N].Map;
 
     // XXX saturate range for FWx, FWy, theta
@@ -241,5 +246,5 @@
     stars[N].found = Nmeas;
     catalog[0].found[n] = Nmeas;
-    catalog[0].average[n].Nm ++;
+    catalog[0].average[n].Nmeasure ++;
     Nmeas ++;
     i++;
@@ -265,12 +270,12 @@
     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;
-    catalog[0].average[Nave].Nm        = 1;
-    catalog[0].average[Nave].Nn        = 0;
-    catalog[0].average[Nave].offset    = Nmeas;
-    catalog[0].average[Nave].missing   = -1;
-    catalog[0].average[Nave].code      = 0;
+    catalog[0].average[Nave].R         	   = stars[N].R;
+    catalog[0].average[Nave].D         	   = stars[N].D;
+    catalog[0].average[Nave].Xp        	   = 0;
+    catalog[0].average[Nave].Nmeasure  	   = 1;
+    catalog[0].average[Nave].Nmissing  	   = 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;
@@ -282,4 +287,8 @@
     catalog[0].average[Nave].P         = 0;
     catalog[0].average[Nave].dP        = 0;
+
+    catalog[0].average[Nave].objID     = objID;
+    catalog[0].average[Nave].catID     = catID;
+    objID ++;
 
     for (j = 0; j < Nsecfilt; j++) {
@@ -307,5 +316,5 @@
     catalog[0].measure[Nmeas].photFlags = stars[N].flags;
     catalog[0].measure[Nmeas].qPSF      = stars[N].psfQual;
-    catalog[0].measure[Nmeas].psfProb   = stars[N].psfProb;
+    catalog[0].measure[Nmeas].psfChisq  = stars[N].psfChisq;
     catalog[0].measure[Nmeas].crNsigma  = stars[N].crNsigma;
     catalog[0].measure[Nmeas].extNsigma = stars[N].extNsigma;
@@ -321,5 +330,5 @@
     catalog[0].measure[Nmeas].dYccd     = stars[N].dY;
 
-    catalog[0].measure[Nmeas].Mgal     = stars[N].Mgal;
+    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;
@@ -360,4 +369,5 @@
 
   /* check if the catalog has changed?  if no change, no need to write */
+  catalog[0].objID    = objID; // new max value, save on catalog close
   catalog[0].Naverage = Nave;
   catalog[0].Nmeasure = Nmeas;
Index: /trunk/Ohana/src/addstar/src/find_matches_refstars.c
===================================================================
--- /trunk/Ohana/src/addstar/src/find_matches_refstars.c	(revision 16809)
+++ /trunk/Ohana/src/addstar/src/find_matches_refstars.c	(revision 16810)
@@ -9,4 +9,5 @@
   int *N1, *N2,  *next, *next_miss, last, last_miss;
   int Nave, NAVE, Nmeas, NMEAS, Nmiss, NMISS, Nmatch;
+  unsigned int objID, catID;
   Measure *tmpmeasure;
   Missing *tmpmissing;
@@ -47,4 +48,8 @@
   REALLOCATE (catalog[0].missing, Missing, NMISS);
   
+  // current max obj ID for this catalog
+  objID = catalog[0].objID;
+  catID = catalog[0].catID;
+
   /* project onto rectilinear grid with 1 arcsec pixels, sort by X */
   /* reference for coords is catalog center */
@@ -115,5 +120,5 @@
       n = N2[J];
       N = N1[i];
-      m = catalog[0].average[n].offset;  
+      m = catalog[0].average[n].measureOffset;  
 
       /** in replace mode, search for entry and replace values M, dM, R, D */
@@ -122,5 +127,5 @@
       /** insert star in measurement list */
       /* find last measurement of this star */
-      for (k = 0; k < catalog[0].average[n].Nm - 1; k++) m = next[m];
+      for (k = 0; k < catalog[0].average[n].Nmeasure - 1; k++) m = next[m];
       /* set up references */
       next[Nmeas] = next[m];
@@ -143,5 +148,5 @@
       catalog[0].measure[Nmeas].dt       = 0xffff;
 
-      catalog[0].measure[Nmeas].Mgal     = NAN;
+      catalog[0].measure[Nmeas].Map      = NAN;
       catalog[0].measure[Nmeas].airmass  = 0;
       catalog[0].measure[Nmeas].FWx      = NAN_S_SHORT;
@@ -151,5 +156,5 @@
       catalog[0].measure[Nmeas].photFlags = 0;
       catalog[0].measure[Nmeas].qPSF      = 0;
-      catalog[0].measure[Nmeas].psfProb   = 0;
+      catalog[0].measure[Nmeas].psfChisq  = 0;
       catalog[0].measure[Nmeas].crNsigma  = 0;
       catalog[0].measure[Nmeas].extNsigma = 0;
@@ -199,5 +204,5 @@
       }
 
-      catalog[0].average[n].Nm ++;
+      catalog[0].average[n].Nmeasure ++;
       Nmeas ++;
       if (Nmeas == NMEAS) {
@@ -224,12 +229,12 @@
     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;
-    catalog[0].average[Nave].Nm        = 1;
-    catalog[0].average[Nave].Nn        = 0;
-    catalog[0].average[Nave].offset    = Nmeas;
-    catalog[0].average[Nave].missing   = -1;
-    catalog[0].average[Nave].code      = 0;
+    catalog[0].average[Nave].R         	   = stars[N][0].R;
+    catalog[0].average[Nave].D         	   = stars[N][0].D;
+    catalog[0].average[Nave].Xp        	   = 0;
+    catalog[0].average[Nave].Nmeasure      = 1;
+    catalog[0].average[Nave].Nmissing      = 0;
+    catalog[0].average[Nave].measureOffset = Nmeas;
+    catalog[0].average[Nave].missingOffset = -1;
+    catalog[0].average[Nave].code          = 0;
 
     if (ACCEPT_MOTION) {
@@ -253,4 +258,8 @@
     }
 
+    catalog[0].average[Nave].objID     = objID;
+    catalog[0].average[Nave].catID     = catID;
+    objID ++;
+
     for (j = 0; j < Nsecfilt; j++) {
       catalog[0].secfilt[Nave*Nsecfilt+j].M  = NAN;
@@ -273,5 +282,5 @@
     catalog[0].measure[Nmeas].photFlags = 0;
     catalog[0].measure[Nmeas].qPSF      = 0;
-    catalog[0].measure[Nmeas].psfProb   = 0;
+    catalog[0].measure[Nmeas].psfChisq  = 0;
     catalog[0].measure[Nmeas].crNsigma  = 0;
     catalog[0].measure[Nmeas].extNsigma = 0;
@@ -291,5 +300,5 @@
 
     catalog[0].measure[Nmeas].airmass  = 0;
-    catalog[0].measure[Nmeas].Mgal     = NAN;
+    catalog[0].measure[Nmeas].Map      = NAN;
     catalog[0].measure[Nmeas].FWx      = NAN_S_SHORT;
     catalog[0].measure[Nmeas].FWy      = NAN_S_SHORT;
@@ -324,7 +333,7 @@
   ALLOCATE (tmpmeasure, Measure, Nmeas);
   for (i = 0; i < Nave; i++) {
-    n = catalog[0].average[i].offset;
-    catalog[0].average[i].offset = N;
-    for (k = 0; k < catalog[0].average[i].Nm; k++, N++) {
+    n = catalog[0].average[i].measureOffset;
+    catalog[0].average[i].measureOffset = N;
+    for (k = 0; k < catalog[0].average[i].Nmeasure; k++, N++) {
       tmpmeasure[N] = catalog[0].measure[n]; 
       tmpmeasure[N].averef = i;
@@ -339,8 +348,8 @@
   ALLOCATE (tmpmissing, Missing, Nmiss);
   for (i = 0; i < Nave; i++) {
-    if (catalog[0].average[i].Nn > 0) {
-      n = catalog[0].average[i].missing;
-      catalog[0].average[i].missing = N;
-      for (k = 0; k < catalog[0].average[i].Nn; k++, N++) {
+    if (catalog[0].average[i].Nmissing > 0) {
+      n = catalog[0].average[i].missingOffset;
+      catalog[0].average[i].missingOffset = N;
+      for (k = 0; k < catalog[0].average[i].Nmissing; k++, N++) {
 	tmpmissing[N] = catalog[0].missing[n]; 
 	n = next_miss[n];
@@ -369,4 +378,5 @@
   free (next_miss);
 
+  catalog[0].objID    = objID; // new max value, save on catalog close
   catalog[0].Naverage = Nave;
   catalog[0].Nmeasure = Nmeas;
Index: /trunk/Ohana/src/addstar/src/get2mass_dr2.c
===================================================================
--- /trunk/Ohana/src/addstar/src/get2mass_dr2.c	(revision 16809)
+++ /trunk/Ohana/src/addstar/src/get2mass_dr2.c	(revision 16810)
@@ -62,4 +62,6 @@
       stars[Nstars].t  	  = short_date_to_sec (&buffer[NBYTE*i + 164]);
       stars[Nstars].found = -1;
+      stars[Nstars].detID   = 0;
+      stars[Nstars].imageID = 0;
 
       if (photcode == TM_J) {
Index: /trunk/Ohana/src/addstar/src/get2mass_full.c
===================================================================
--- /trunk/Ohana/src/addstar/src/get2mass_full.c	(revision 16810)
+++ /trunk/Ohana/src/addstar/src/get2mass_full.c	(revision 16810)
@@ -0,0 +1,276 @@
+# include "addstar.h"
+# include "2mass.h"
+
+// fill in the data for a JHK triplet star.  takes a pointer to the start of the line the
+// RA and DEC have already been set
+int get2mass_3star_full (Stars *star, char *line, int Nmax) {
+
+  char *ptr;
+  double dMfull;
+  double jd;
+
+  if (line == NULL) Shutdown ("format error in 2mass");
+
+  ptr = line;		      // ra  (assumed to be already set)
+  ptr = next2MASSfield (ptr); // dec (assumed to be already set)
+  ptr = next2MASSfield (ptr); // err_maj
+  star[0].fx = strtod (ptr, NULL);
+  ptr = next2MASSfield (ptr); // err_min
+  star[0].fy = strtod (ptr, NULL);
+  ptr = next2MASSfield (ptr); // err_ang
+  star[0].df = strtod (ptr, NULL);
+
+  star[2].fx = star[2].fx = star[0].fx;
+  star[2].fy = star[2].fy = star[0].fy;
+  star[2].df = star[2].df = star[0].df;
+
+  ptr = next2MASSfield (ptr); // designation (skip)
+
+  ptr = next2MASSfield (ptr); // j_m
+  star[0].M  = strtod (ptr, NULL);
+  ptr = next2MASSfield (ptr); // j_cmsig
+  star[0].dM = strtod (ptr, NULL);
+  ptr = next2MASSfield (ptr); // j_msigcom
+  dMfull = strtod (ptr, NULL);
+  star[0].dMcal = sqrt (SQ(dMfull) - SQ(star[0].dM));
+  ptr = next2MASSfield (ptr); // j_snr (skip)
+
+  ptr = next2MASSfield (ptr); // h_m
+  star[1].M  = strtod (ptr, NULL);
+  ptr = next2MASSfield (ptr); // h_cmsig
+  star[1].dM = strtod (ptr, NULL);
+  ptr = next2MASSfield (ptr); // h_msigcom
+  dMfull = strtod (ptr, NULL);
+  star[1].dMcal = sqrt (SQ(dMfull) - SQ(star[1].dM));
+  ptr = next2MASSfield (ptr); // h_snr (skip)
+
+  ptr = next2MASSfield (ptr); // k_m
+  star[2].M  = strtod (ptr, NULL);
+  ptr = next2MASSfield (ptr); // k_cmsig
+  star[2].dM = strtod (ptr, NULL);
+  ptr = next2MASSfield (ptr); // k_msigcom
+  dMfull = strtod (ptr, NULL);
+  star[2].dMcal = sqrt (SQ(dMfull) - SQ(star[2].dM));
+  ptr = next2MASSfield (ptr); // k_snr (skip)
+
+  star[2].flags = star[1].flags = star[0].flags = 0;
+
+  ptr = next2MASSfield (ptr); // ph_qual
+  set2MASS_ph_qual (&star[0], ptr[0]);
+  set2MASS_ph_qual (&star[1], ptr[1]);
+  set2MASS_ph_qual (&star[2], ptr[2]);
+
+  ptr = next2MASSfield (ptr); // rd_flg
+  set2MASS_rd_flag (&star[0], ptr[0]);
+  set2MASS_rd_flag (&star[1], ptr[1]);
+  set2MASS_rd_flag (&star[2], ptr[2]);
+
+  ptr = next2MASSfield (ptr); // bl_flg
+  set2MASS_bl_flag (&star[0], ptr[0]);
+  set2MASS_bl_flag (&star[1], ptr[1]);
+  set2MASS_bl_flag (&star[2], ptr[2]);
+
+  ptr = next2MASSfield (ptr); // cc_flg
+  set2MASS_cc_flag (&star[0], ptr[0]);
+  set2MASS_cc_flag (&star[1], ptr[1]);
+  set2MASS_cc_flag (&star[2], ptr[2]);
+
+  ptr = next2MASSfield (ptr); // ndet (skip for now, XXX use somehow?)
+  ptr = next2MASSfield (ptr); // prox (skip)
+  ptr = next2MASSfield (ptr); // pxpa (skip)
+  ptr = next2MASSfield (ptr); // pxcntr (skip)
+
+  ptr = next2MASSfield (ptr); // gal_contam (one flag for all filters)
+  set2MASS_gal_flag (&star[0], ptr[0]);
+  set2MASS_gal_flag (&star[1], ptr[0]);
+  set2MASS_gal_flag (&star[2], ptr[0]);
+
+  ptr = next2MASSfield (ptr); // mp_flg (one flag for all filters)
+  set2MASS_mp_flag (&star[0], ptr[0]);
+  set2MASS_mp_flag (&star[1], ptr[0]);
+  set2MASS_mp_flag (&star[2], ptr[0]);
+
+  ptr = next2MASSfield (ptr); // pts_key (skip for now, XXX use somehow?)
+  ptr = next2MASSfield (ptr); // hemis (skip)
+  ptr = next2MASSfield (ptr); // date (skip)
+  ptr = next2MASSfield (ptr); // scan (skip)
+  ptr = next2MASSfield (ptr); // glon (skip)
+  ptr = next2MASSfield (ptr); // glat (skip)
+
+  ptr = next2MASSfield (ptr); // x_scan
+  star[0].X = strtod (ptr, NULL);
+  star[2].X = star[1].X = star[0].X;
+
+  ptr = next2MASSfield (ptr); // jdate (julian date)
+  jd = strtod (ptr, NULL);
+  star[0].t = ohana_jd_to_sec (jd);
+  star[2].t = star[1].t = star[0].t;
+
+  ptr = next2MASSfield (ptr); // j_psfchi
+  star[0].psfChisq = strtod (ptr, NULL);
+  ptr = next2MASSfield (ptr); // h_psfchi
+  star[1].psfChisq = strtod (ptr, NULL);
+  ptr = next2MASSfield (ptr); // k_psfchi
+  star[2].psfChisq = strtod (ptr, NULL);
+
+  ptr = next2MASSfield (ptr); // j_m_stdap
+  star[0].Map = strtod (ptr, NULL);
+  ptr = next2MASSfield (ptr); // j_msig_stdap (skip?)
+
+  ptr = next2MASSfield (ptr); // h_m_stdap
+  star[1].Map = strtod (ptr, NULL);
+  ptr = next2MASSfield (ptr); // h_msig_stdap (skip?)
+
+  ptr = next2MASSfield (ptr); // k_m_stdap
+  star[2].Map = strtod (ptr, NULL);
+  ptr = next2MASSfield (ptr); // k_msig_stdap (skip?)
+
+  ptr = next2MASSfield (ptr); // dist_edge_ns (skip)
+  ptr = next2MASSfield (ptr); // dist_edge_ew (skip)
+  ptr = next2MASSfield (ptr); // dist_edge_flg (skip)
+
+  ptr = next2MASSfield (ptr); // dup_src (one flag for all filters)
+  set2MASS_dup_flag (&star[0], ptr[0]);
+  set2MASS_dup_flag (&star[1], ptr[0]);
+  set2MASS_dup_flag (&star[2], ptr[0]);
+
+  ptr = next2MASSfield (ptr); // use_src (one flag for all filters)
+  set2MASS_use_flag (&star[0], ptr[0]);
+  set2MASS_use_flag (&star[1], ptr[0]);
+  set2MASS_use_flag (&star[2], ptr[0]);
+
+  star[0].code  = TM_J;
+  star[0].found = -1;
+  star[0].detID   = 0;
+  star[0].imageID = 0;
+
+  star[1].code  = TM_H;
+  star[1].found = -1;
+  star[1].detID   = 0;
+  star[1].imageID = 0;
+
+  star[2].code  = TM_K;
+  star[2].found = -1;
+  star[2].detID   = 0;
+  star[2].imageID = 0;
+
+  return TRUE;
+}
+
+/* return a pointer to the first char after the next field separator (|) */
+char *next2MASSfield (char *line) {
+
+  char *p, *q;
+
+  p = line;
+  q = strchr (p, '|');
+  if (q == NULL) return (NULL);
+  p = q + 1;
+  if (*p == 0) return (NULL);
+  return (p);
+}
+
+int set2MASS_ph_qual (Stars *star, char qual) {
+
+  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;
+    default: 
+      fprintf (stderr, "error!\n");
+      exit (2);
+  }      
+  return (TRUE);
+}
+
+int set2MASS_rd_flag (Stars *star, char qual) {
+
+  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;
+    default: 
+      fprintf (stderr, "error!\n");
+      exit (2);
+  }      
+  return (TRUE);
+}
+
+int set2MASS_cc_flag (Stars *star, char qual) {
+
+  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;
+    default: 
+      fprintf (stderr, "error!\n");
+      exit (2);
+  }      
+  return (TRUE);
+}
+
+int set2MASS_bl_flag (Stars *star, char qual) {
+
+  switch (qual) {
+    case '0': star[0].flags &= ~0x0008; break;
+    case '1': star[0].flags &= ~0x0008; break;
+    default:  star[0].flags |=  0x0008; break;
+  }      
+  return (TRUE);
+}
+
+int set2MASS_gal_flag (Stars *star, char qual) {
+
+  switch (qual) {
+    case '0': star[0].flags &= ~0x0080; break;
+    case '1': star[0].flags &= ~0x0080; break;
+    default:  
+      star[0].flags |= 0x0080; 
+      star[0].extNsigma = 100.0;
+      break;
+  }      
+  return (TRUE);
+}
+
+int set2MASS_mp_flag (Stars *star, char qual) {
+
+  switch (qual) {
+    case '0': star[0].flags &= ~0x0800; break;
+    case '1': star[0].flags &= ~0x0800; break;
+    default:  star[0].flags |=  0x0800; break;
+  }      
+  return (TRUE);
+}
+
+int set2MASS_dup_flag (Stars *star, char qual) {
+
+  switch (qual) {
+    case '0': star[0].flags &= ~0x1000; break;
+    case '1': star[0].flags &= ~0x1000; break;
+    default:  star[0].flags |=  0x1000; break;
+  }      
+  return (TRUE);
+}
+
+int set2MASS_use_flag (Stars *star, char qual) {
+
+  switch (qual) {
+    case '0': star[0].flags &= ~0x2000; break;
+    case '1': star[0].flags |=  0x2000; break;
+    default:  abort();
+  }      
+  return (TRUE);
+}
+
Index: /trunk/Ohana/src/addstar/src/get2mass_ops.c
===================================================================
--- /trunk/Ohana/src/addstar/src/get2mass_ops.c	(revision 16809)
+++ /trunk/Ohana/src/addstar/src/get2mass_ops.c	(revision 16810)
@@ -57,9 +57,11 @@
   }
 
-  star[0].M     = M;
-  star[0].dM    = dM;
-  star[0].code  = Photcode;
-  star[0].t     = time;
-  star[0].found = -1;
+  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;
 
   return TRUE;
@@ -103,4 +105,6 @@
   }
 
+  // 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;
@@ -108,4 +112,6 @@
   star[0].t     = time;
   star[0].found = -1;
+  star[0].detID   = 0;
+  star[0].imageID = 0;
 
   star[1].M     = H;
@@ -114,4 +120,6 @@
   star[1].t     = time;
   star[1].found = -1;
+  star[1].detID   = 0;
+  star[1].imageID = 0;
 
   star[2].M     = K;
@@ -120,4 +128,6 @@
   star[2].t     = time;
   star[2].found = -1;
+  star[2].detID   = 0;
+  star[2].imageID = 0;
 
   return TRUE;
Index: /trunk/Ohana/src/addstar/src/getgsc.c
===================================================================
--- /trunk/Ohana/src/addstar/src/getgsc.c	(revision 16809)
+++ /trunk/Ohana/src/addstar/src/getgsc.c	(revision 16810)
@@ -75,4 +75,8 @@
       stars[Nstars].code  = GSC_M;
       stars[Nstars].found = -1;
+
+      stars[Nstars].detID   = 0;
+      stars[Nstars].imageID = 0;
+
       Nstars ++;
       CHECK_REALLOCATE (stars, Stars, NSTARS, Nstars, 1000);
Index: /trunk/Ohana/src/addstar/src/gettycho.c
===================================================================
--- /trunk/Ohana/src/addstar/src/gettycho.c	(revision 16809)
+++ /trunk/Ohana/src/addstar/src/gettycho.c	(revision 16810)
@@ -96,4 +96,7 @@
 	stars[Ntycho].dP  = 0;
 
+	stars[Ntycho].detID   = 0;
+	stars[Ntycho].imageID = 0;
+
 	/* Tycho uses J2000 equinox and 1991.25 epoch for coordinates */
 	/* the magnitudes have no temporal information */ 
Index: /trunk/Ohana/src/addstar/src/getusno.c
===================================================================
--- /trunk/Ohana/src/addstar/src/getusno.c	(revision 16809)
+++ /trunk/Ohana/src/addstar/src/getusno.c	(revision 16810)
@@ -117,4 +117,7 @@
       stars[Nusno].found = -1;
 
+      stars[Nusno].detID   = 0;
+      stars[Nusno].imageID = 0;
+
       /* one pass of addstar does either r or b */
       if (photcode == USNO_RED) {
Index: /trunk/Ohana/src/addstar/src/getusnob.c
===================================================================
--- /trunk/Ohana/src/addstar/src/getusnob.c	(revision 16809)
+++ /trunk/Ohana/src/addstar/src/getusnob.c	(revision 16810)
@@ -141,4 +141,7 @@
       stars[Nusno].found = -1;
       
+      stars[Nusno].detID   = 0;
+      stars[Nusno].imageID = 0;
+
       /* USNO-B uses J2000 equinox and 2000.0 epoch for coordinates */
       /* the magnitudes have no temporal information */ 
Index: /trunk/Ohana/src/addstar/src/grefstars.c
===================================================================
--- /trunk/Ohana/src/addstar/src/grefstars.c	(revision 16809)
+++ /trunk/Ohana/src/addstar/src/grefstars.c	(revision 16810)
@@ -30,4 +30,6 @@
     stars[N].code = photcode;
     stars[N].found = FALSE;
+    stars[N].detID   = 0;
+    stars[N].imageID = 0;
     CHECK_REALLOCATE (stars, Stars, NSTARS, N+1, 100);
   }
Index: /trunk/Ohana/src/addstar/src/load2mass_as_rawdata.c
===================================================================
--- /trunk/Ohana/src/addstar/src/load2mass_as_rawdata.c	(revision 16809)
+++ /trunk/Ohana/src/addstar/src/load2mass_as_rawdata.c	(revision 16810)
@@ -135,5 +135,5 @@
 	stars[Nstars+2].R = tstars[j].R;
 	stars[Nstars+2].D = tstars[j].D;
-	get2mass_3star (&stars[Nstars], &buffer[offset], Nbyte - offset);
+	get2mass_3star_full (&stars[Nstars], &buffer[offset], Nbyte - offset);
 	// get2mass_star (&stars[Nstars], &buffer[offset], Nbyte - offset);
 
@@ -165,5 +165,5 @@
 
 	// an error exit status here is a significant error
-	if (!dvo_catalog_open (&catalog, skylist[0].regions[i], VERBOSE, "w")) {
+	if (!dvo_catalog_open (&catalog, skylist[0].regions[0], VERBOSE, "w")) {
 	  fprintf (stderr, "ERROR: failure to open/create catalog file %s\n", catalog.filename);
 	  exit (2);
Index: /trunk/Ohana/src/addstar/src/load2mass_catalog.c
===================================================================
--- /trunk/Ohana/src/addstar/src/load2mass_catalog.c	(revision 16809)
+++ /trunk/Ohana/src/addstar/src/load2mass_catalog.c	(revision 16810)
@@ -32,10 +32,10 @@
 
     // XXX for now, set the average mag data to NULL
-    catalog[0].average[Nave].Nm        = 0;
-    catalog[0].average[Nave].Nn        = 0;
-    catalog[0].average[Nave].Xp        = NAN_S_SHORT;
-    catalog[0].average[Nave].offset    = Nmeas;
-    catalog[0].average[Nave].missing   = -1;
-    catalog[0].average[Nave].code      = 0;
+    catalog[0].average[Nave].Nmeasure  	   = 0;
+    catalog[0].average[Nave].Nmissing  	   = 0;
+    catalog[0].average[Nave].Xp        	   = NAN_S_SHORT;
+    catalog[0].average[Nave].measureOffset = Nmeas;
+    catalog[0].average[Nave].missingOffset = -1;
+    catalog[0].average[Nave].code          = 0;
 
     for (j = 0; j < Nsec; j++) {
@@ -47,23 +47,28 @@
     // 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].dR       = 0.0;
-      catalog[0].measure[Nmeas].dD       = 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].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].dbFlags  = 0;
-      catalog[0].measure[Nmeas].dt       = 0xffff;
+      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].Mgal     = NAN;
-      catalog[0].measure[Nmeas].airmass  = 0;
-      catalog[0].measure[Nmeas].FWx      = NAN_S_SHORT;
-      catalog[0].measure[Nmeas].FWy      = NAN_S_SHORT;
-      catalog[0].measure[Nmeas].theta    = NAN_S_SHORT;
-
-      catalog[0].average[Nave].Nm++;
+      catalog[0].average[Nave].Nmeasure++;
       Nmeas ++;
       CHECK_REALLOCATE (catalog[0].measure, Measure, NMEAS, Nmeas, 100);
Index: /trunk/Ohana/src/addstar/src/replace_match.c
===================================================================
--- /trunk/Ohana/src/addstar/src/replace_match.c	(revision 16809)
+++ /trunk/Ohana/src/addstar/src/replace_match.c	(revision 16810)
@@ -6,5 +6,5 @@
 
   /* search for entry and replace values M, dM, R, D */
-  for (i = 0; i < average[0].Nm; i++) {
+  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);
@@ -12,5 +12,5 @@
     measure[i].M  = star[0].M;
     measure[i].dM = star[0].dM;
-    star[0].found = average[0].offset + i;
+    star[0].found = average[0].measureOffset + i;
     return (TRUE);
   }
Index: /trunk/Ohana/src/addstar/src/update_coords.c
===================================================================
--- /trunk/Ohana/src/addstar/src/update_coords.c	(revision 16809)
+++ /trunk/Ohana/src/addstar/src/update_coords.c	(revision 16810)
@@ -10,9 +10,9 @@
   Npt = r = d = r2 = d2 = 0;
 
-  if (average[0].Nm < 2) return;
+  if (average[0].Nmeasure < 2) return;
 
   /* find the average & sum-square (does not use reference coordinates) */
-  m = average[0].offset;  /* first measurement of this star */
-  for (i = 0; i < average[0].Nm; i++) {
+  m = average[0].measureOffset;  /* first measurement of this star */
+  for (i = 0; i < average[0].Nmeasure; i++) {
     if (measure[m].t == 0) {
       m = next[m];
@@ -35,6 +35,6 @@
   average[0].R -= r / 3600.0;
   average[0].D -= d / 3600.0;
-  m = average[0].offset;  /* first measurement of this star */
-  for (i = 0; i < average[0].Nm; i++) {
+  m = average[0].measureOffset;  /* first measurement of this star */
+  for (i = 0; i < average[0].Nmeasure; i++) {
     measure[m].dR -= r;
     measure[m].dD -= d;
Index: /trunk/Ohana/src/delstar/src/find_image_db.c
===================================================================
--- /trunk/Ohana/src/delstar/src/find_image_db.c	(revision 16809)
+++ /trunk/Ohana/src/delstar/src/find_image_db.c	(revision 16810)
@@ -44,6 +44,6 @@
   image = gfits_table_get_Image (&db[0].ftable, &Nimage, &db[0].swapped);
 
-  start = timage[0].tzero - MAX(0.05*timage[0].trate*timage[0].NY, 1);
-  stop  = timage[0].tzero + MAX(1.05*timage[0].trate*timage[0].NY, 1);
+  start = timage[0].tzero - MAX(0.01*timage[0].trate*timage[0].NY, 1);
+  stop  = timage[0].tzero + MAX(1.01*timage[0].trate*timage[0].NY, 1);
   code  = timage[0].photcode;
 
Index: /trunk/Ohana/src/delstar/src/find_matches.c
===================================================================
--- /trunk/Ohana/src/delstar/src/find_matches.c	(revision 16809)
+++ /trunk/Ohana/src/delstar/src/find_matches.c	(revision 16810)
@@ -37,6 +37,6 @@
   /* set up references for missing to average */
   for (i = 0; i < Nave; i++) {
-    for (j = 0; j < catalog[0].average[i].Nn; j++) {
-      ave_miss[catalog[0].average[i].missing + j] = i;
+    for (j = 0; j < catalog[0].average[i].Nmissing; j++) {
+      ave_miss[catalog[0].average[i].missingOffset + j] = i;
     }
   }
@@ -88,18 +88,18 @@
     /*** fix the corresponding average entry ***/
     n = catalog[0].measure[i].averef;
-    if (catalog[0].average[n].Nm == 0) { /* this should never happen */
+    if (catalog[0].average[n].Nmeasure == 0) { /* this should never happen */
       fprintf (stderr, "error? we deleted one too many objects?\n");
       exit (1);
     }
-    catalog[0].average[n].Nm --;
+    catalog[0].average[n].Nmeasure --;
     /* this was only entry in list: will be deleted below.  meanwhile, delete all missing entries*/
-    if ((catalog[0].average[n].Nm < 1) && (catalog[0].average[n].Nn > 0)) { 
-      m = catalog[0].average[n].missing;
-      for (j = 0; j < catalog[0].average[n].Nn; j++) {
+    if ((catalog[0].average[n].Nmeasure < 1) && (catalog[0].average[n].Nmissing > 0)) { 
+      m = catalog[0].average[n].missingOffset;
+      for (j = 0; j < catalog[0].average[n].Nmissing; j++) {
 	M = next_miss[m];
 	next_miss[m] = -2;
 	m = M;
       }
-      m = catalog[0].average[n].missing;
+      m = catalog[0].average[n].missingOffset;
       /* fix the list links: connect the previous valid link to the next valid link */
       for (j = m; (j >= 0) && (next_miss[j] == -2); j--); /* find previous entry to fix link */
@@ -119,9 +119,9 @@
     }
     /* this was first entry in list */
-    if ((catalog[0].average[n].offset == i) && (catalog[0].average[n].Nm > 0)) { 
-      m = catalog[0].average[n].offset;
+    if ((catalog[0].average[n].measureOffset == i) && (catalog[0].average[n].Nmeasure > 0)) { 
+      m = catalog[0].average[n].measureOffset;
       /* find next valid entry -- notice lack of error checking... */
       for (j = 0; (j < Nmeas) && (next[m+j] == -2); j++);
-      catalog[0].average[n].offset = m + j;
+      catalog[0].average[n].measureOffset = m + j;
     }
   } 
@@ -154,14 +154,14 @@
     /*** fix the corresponding average entry ***/
     n = ave_miss[i];
-    if (catalog[0].average[n].Nn == 0) { /* this should never happen */
+    if (catalog[0].average[n].Nmissing == 0) { /* this should never happen */
       fprintf (stderr, "error? we deleted one too many missing?\n");
       exit (1);
     }
-    catalog[0].average[n].Nn --;
+    catalog[0].average[n].Nmissing --;
     /* this was first entry in list */
-    if ((catalog[0].average[n].missing == i) && (catalog[0].average[n].Nn > 0)) { 
-      m = catalog[0].average[n].missing;
+    if ((catalog[0].average[n].missingOffset == i) && (catalog[0].average[n].Nmissing > 0)) { 
+      m = catalog[0].average[n].missingOffset;
       for (j = 0; (j < Nmiss) && (next_miss[m+j] == -2); j++);
-      catalog[0].average[n].missing = m + j;
+      catalog[0].average[n].missingOffset = m + j;
     }
   }
@@ -172,5 +172,5 @@
   /* fix Average list: delete entries with Nm == 0 */
   for (i = j = 0; (i < Nave) && (j < Nave); i++, j++) {
-    for (; (j < Nave) && (catalog[0].average[j].Nm == 0); j++);
+    for (; (j < Nave) && (catalog[0].average[j].Nmeasure == 0); j++);
     if ((i != j) && (j < Nave)) {
       catalog[0].average[i] = catalog[0].average[j];
@@ -189,7 +189,7 @@
   ALLOCATE (tmpmeasure, Measure, Nmeas);
   for (i = 0; i < Nave; i++) {
-    n = catalog[0].average[i].offset;
-    catalog[0].average[i].offset = N;
-    for (k = 0; k < catalog[0].average[i].Nm; k++, N++) {
+    n = catalog[0].average[i].measureOffset;
+    catalog[0].average[i].measureOffset = N;
+    for (k = 0; k < catalog[0].average[i].Nmeasure; k++, N++) {
       if ((n == -1) || (n == -2)) {
 	fprintf (stderr, "error: linked list is confused\n");
@@ -211,8 +211,8 @@
   ALLOCATE (tmpmissing, Missing, Nmiss);
   for (i = 0; i < Nave; i++) {
-    if (catalog[0].average[i].Nn > 0) {
-      n = catalog[0].average[i].missing;
-      catalog[0].average[i].missing = N;
-      for (k = 0; k < catalog[0].average[i].Nn; k++, N++) {
+    if (catalog[0].average[i].Nmissing > 0) {
+      n = catalog[0].average[i].missingOffset;
+      catalog[0].average[i].missingOffset = N;
+      for (k = 0; k < catalog[0].average[i].Nmissing; k++, N++) {
 	if ((n == -1) || (n == -2)) {
 	  fprintf (stderr, "error: linked list is confused\n");
Index: /trunk/Ohana/src/delstar/src/match_images.c
===================================================================
--- /trunk/Ohana/src/delstar/src/match_images.c	(revision 16809)
+++ /trunk/Ohana/src/delstar/src/match_images.c	(revision 16810)
@@ -16,6 +16,6 @@
   ALLOCATE (stop,  unsigned int, Nimage);
   for (j = 0; j < Nimage; j++) {
-    start[j] = image[j].tzero - MAX(0.05*image[j].trate*image[j].NY, 1);
-    stop[j]  = image[j].tzero + MAX(1.05*image[j].trate*image[j].NY, 1);
+    start[j] = image[j].tzero - MAX(0.01*image[j].trate*image[j].NY, 1);
+    stop[j]  = image[j].tzero + MAX(1.01*image[j].trate*image[j].NY, 1);
   }
 
Index: /trunk/Ohana/src/fixcat/src/match_images.c
===================================================================
--- /trunk/Ohana/src/fixcat/src/match_images.c	(revision 16809)
+++ /trunk/Ohana/src/fixcat/src/match_images.c	(revision 16810)
@@ -20,6 +20,6 @@
   ALLOCATE (stop,  unsigned int, Nimage);
   for (j = 0; j < Nimage; j++) {
-    start[j] = image[j].tzero - MAX(0.05*image[j].trate*image[j].NY, 1);
-    stop[j]  = image[j].tzero + MAX(1.05*image[j].trate*image[j].NY, 1);
+    start[j] = image[j].tzero - MAX(0.01*image[j].trate*image[j].NY, 1);
+    stop[j]  = image[j].tzero + MAX(1.01*image[j].trate*image[j].NY, 1);
   }
 
Index: /trunk/Ohana/src/gastro/src/getptolemy.c
===================================================================
--- /trunk/Ohana/src/gastro/src/getptolemy.c	(revision 16809)
+++ /trunk/Ohana/src/gastro/src/getptolemy.c	(revision 16810)
@@ -50,5 +50,5 @@
       stars[k].X = catalog.average[j].R;
       stars[k].Y = catalog.average[j].D;
-      stars[k].mag = catalog.measure[catalog.average[j].offset].M;
+      stars[k].mag = catalog.measure[catalog.average[j].measureOffset].M;
     }      
     dvo_catalog_free (&catalog);
Index: /trunk/Ohana/src/gastro2/src/getptolemy.c
===================================================================
--- /trunk/Ohana/src/gastro2/src/getptolemy.c	(revision 16809)
+++ /trunk/Ohana/src/gastro2/src/getptolemy.c	(revision 16810)
@@ -61,5 +61,5 @@
       Ref[0].stars[k].R = catalog.average[j].R;
       Ref[0].stars[k].D = catalog.average[j].D;
-      Ref[0].stars[k].M = catalog.measure[catalog.average[j].offset].M;
+      Ref[0].stars[k].M = catalog.measure[catalog.average[j].measureOffset].M;
     }      
     dvo_catalog_free (&catalog);
Index: /trunk/Ohana/src/getstar/src/ReadImageHeader.c
===================================================================
--- /trunk/Ohana/src/getstar/src/ReadImageHeader.c	(revision 16809)
+++ /trunk/Ohana/src/getstar/src/ReadImageHeader.c	(revision 16810)
@@ -98,5 +98,4 @@
   image[0].Xm   = NAN_S_SHORT;
   image[0].code = 0;
-  bzero (image[0].dummy, sizeof(image[0].dummy));
 
   return (TRUE);
Index: /trunk/Ohana/src/getstar/src/select_by_region.c
===================================================================
--- /trunk/Ohana/src/getstar/src/select_by_region.c	(revision 16809)
+++ /trunk/Ohana/src/getstar/src/select_by_region.c	(revision 16810)
@@ -54,6 +54,6 @@
 	mag = catalog[0].secfilt[i*Nsecfilt + Nsec].M;
       } else {
-	offset = catalog[0].average[i].offset;
-	for (m = 0; m < catalog[0].average[i].Nm; m++) {
+	offset = catalog[0].average[i].measureOffset;
+	for (m = 0; m < catalog[0].average[i].Nmeasure; m++) {
 	  if (catalog[0].measure[offset + m].photcode == code) {
 	    mag = PhotRel (&catalog[0].measure[offset + m], &catalog[0].average[i], &catalog[0].secfilt[i*Nsecfilt]);
@@ -66,5 +66,5 @@
 
     output[0].average[Nave] = catalog[0].average[i];
-    output[0].average[Nave].offset = Nmeas;
+    output[0].average[Nave].measureOffset = Nmeas;
     for (j = 0; j < Nsecfilt; j++) {
       output[0].secfilt[Nsecfilt*Nave + j] = catalog[0].secfilt[Nsecfilt*i + j];
@@ -72,7 +72,7 @@
 
     Nm = 0;
-    offset = catalog[0].average[i].offset;
+    offset = catalog[0].average[i].measureOffset;
 
-    for (j = 0; j < catalog[0].average[i].Nm; j++) {
+    for (j = 0; j < catalog[0].average[i].Nmeasure; j++) {
       output[0].measure[Nmeas] = catalog[0].measure[offset + j];
       output[0].measure[Nmeas].averef = Nave;
Index: /trunk/Ohana/src/getstar/src/write_getstar_ps1_dev_0.c
===================================================================
--- /trunk/Ohana/src/getstar/src/write_getstar_ps1_dev_0.c	(revision 16809)
+++ /trunk/Ohana/src/getstar/src/write_getstar_ps1_dev_0.c	(revision 16810)
@@ -58,6 +58,6 @@
     } else {
       output[i].mag = NAN;
-      offset = average[i].offset;
-      for (m = 0; m < average[i].Nm; m++) {
+      offset = average[i].measureOffset;
+      for (m = 0; m < average[i].Nmeasure; m++) {
         if (measure[offset + m].photcode == code_c0) {
           output[i].mag = PhotRel (&measure[offset + m], &average[i], &secfilt[i*Nsecfilt]);
@@ -72,6 +72,6 @@
     } else {
       output[i].c1 = NAN;
-      offset = average[i].offset;
-      for (m = 0; m < average[i].Nm; m++) {
+      offset = average[i].measureOffset;
+      for (m = 0; m < average[i].Nmeasure; m++) {
         if (measure[offset + m].photcode == code_c1) {
           output[i].c1 = PhotRel (&measure[offset + m], &average[i], &secfilt[i*Nsecfilt]);
@@ -86,6 +86,6 @@
     } else {
       output[i].c2 = NAN;
-      offset = average[i].offset;
-      for (m = 0; m < average[i].Nm; m++) {
+      offset = average[i].measureOffset;
+      for (m = 0; m < average[i].Nmeasure; m++) {
         if (measure[offset + m].photcode == code_c2) {
           output[i].c2 = PhotRel (&measure[offset + m], &average[i], &secfilt[i*Nsecfilt]);
Index: /trunk/Ohana/src/getstar/src/write_getstar_ps1_dev_1.c
===================================================================
--- /trunk/Ohana/src/getstar/src/write_getstar_ps1_dev_1.c	(revision 16809)
+++ /trunk/Ohana/src/getstar/src/write_getstar_ps1_dev_1.c	(revision 16810)
@@ -61,6 +61,6 @@
     } else {
       output[i].mag = NAN;
-      offset = average[i].offset;
-      for (m = 0; m < average[i].Nm; m++) {
+      offset = average[i].measureOffset;
+      for (m = 0; m < average[i].Nmeasure; m++) {
         if (measure[offset + m].photcode == code_c0) {
           output[i].mag = PhotRel (&measure[offset + m], &average[i], &secfilt[i*Nsecfilt]);
@@ -75,6 +75,6 @@
     } else {
       output[i].c1 = NAN;
-      offset = average[i].offset;
-      for (m = 0; m < average[i].Nm; m++) {
+      offset = average[i].measureOffset;
+      for (m = 0; m < average[i].Nmeasure; m++) {
         if (measure[offset + m].photcode == code_c1) {
           output[i].c1 = PhotRel (&measure[offset + m], &average[i], &secfilt[i*Nsecfilt]);
@@ -89,6 +89,6 @@
     } else {
       output[i].c2 = NAN;
-      offset = average[i].offset;
-      for (m = 0; m < average[i].Nm; m++) {
+      offset = average[i].measureOffset;
+      for (m = 0; m < average[i].Nmeasure; m++) {
         if (measure[offset + m].photcode == code_c2) {
           output[i].c2 = PhotRel (&measure[offset + m], &average[i], &secfilt[i*Nsecfilt]);
Index: /trunk/Ohana/src/getstar/src/write_getstar_ps1_dev_2.c
===================================================================
--- /trunk/Ohana/src/getstar/src/write_getstar_ps1_dev_2.c	(revision 16809)
+++ /trunk/Ohana/src/getstar/src/write_getstar_ps1_dev_2.c	(revision 16810)
@@ -67,6 +67,6 @@
     } else {
       output[i].mag = NAN;
-      offset = average[i].offset;
-      for (m = 0; m < average[i].Nm; m++) {
+      offset = average[i].measureOffset;
+      for (m = 0; m < average[i].Nmeasure; m++) {
         if (measure[offset + m].photcode == code_c0) {
           output[i].mag = PhotRel (&measure[offset + m], &average[i], &secfilt[i*Nsecfilt]);
@@ -81,6 +81,6 @@
     } else {
       output[i].c1 = NAN;
-      offset = average[i].offset;
-      for (m = 0; m < average[i].Nm; m++) {
+      offset = average[i].measureOffset;
+      for (m = 0; m < average[i].Nmeasure; m++) {
         if (measure[offset + m].photcode == code_c1) {
           output[i].c1 = PhotRel (&measure[offset + m], &average[i], &secfilt[i*Nsecfilt]);
@@ -95,6 +95,6 @@
     } else {
       output[i].c2 = NAN;
-      offset = average[i].offset;
-      for (m = 0; m < average[i].Nm; m++) {
+      offset = average[i].measureOffset;
+      for (m = 0; m < average[i].Nmeasure; m++) {
         if (measure[offset + m].photcode == code_c2) {
           output[i].c2 = PhotRel (&measure[offset + m], &average[i], &secfilt[i*Nsecfilt]);
Index: /trunk/Ohana/src/kapa2/include/buttons.h
===================================================================
--- /trunk/Ohana/src/kapa2/include/buttons.h	(revision 16809)
+++ /trunk/Ohana/src/kapa2/include/buttons.h	(revision 16810)
@@ -119,2 +119,26 @@
    0x42, 0x84, 0x84, 0x00, 0x42, 0x84, 0x84, 0x00, 0x62, 0xc4, 0xc4, 0x00,
    0x5c, 0xb9, 0xb8, 0x00};
+#define flipx_width 25
+#define flipx_height 25
+static unsigned char flipx_bits[] = {
+   0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x01, 0x00, 0x80, 0x10, 0x02, 0x00,
+   0x40, 0x00, 0x04, 0x00, 0x20, 0x10, 0x08, 0x00, 0x10, 0x10, 0x10, 0x00,
+   0x08, 0x00, 0x20, 0x00, 0x04, 0x10, 0x40, 0x00, 0x02, 0x10, 0x80, 0x00,
+   0x01, 0x00, 0x00, 0x01, 0x02, 0x10, 0x80, 0x00, 0x04, 0x10, 0x40, 0x00,
+   0x08, 0x00, 0x20, 0x00, 0x10, 0x10, 0x10, 0x00, 0x20, 0x10, 0x08, 0x00,
+   0x40, 0x00, 0x04, 0x00, 0x80, 0x10, 0x02, 0x00, 0x00, 0x11, 0x01, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+   0x00, 0x10, 0x00, 0x00 };
+#define flipy_width 25
+#define flipy_height 25
+static unsigned char flipy_bits[] = {
+   0x00, 0x10, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00,
+   0x00, 0x82, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x80, 0x00, 0x02, 0x00,
+   0x40, 0x00, 0x04, 0x00, 0x20, 0x00, 0x08, 0x00, 0x10, 0x00, 0x10, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xb7, 0x6d, 0xdb, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x20, 0x00, 0x08, 0x00,
+   0x40, 0x00, 0x04, 0x00, 0x80, 0x00, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00,
+   0x00, 0x82, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00,
+   0x00, 0x10, 0x00, 0x00 };
Index: /trunk/Ohana/src/kapa2/include/prototypes.h
===================================================================
--- /trunk/Ohana/src/kapa2/include/prototypes.h	(revision 16809)
+++ /trunk/Ohana/src/kapa2/include/prototypes.h	(revision 16810)
@@ -195,4 +195,6 @@
 int	      RecenterRescale	  PROTO((Graphic *graphic, KapaImageWidget *image));
 int	      ToggleDEG		  PROTO((Graphic *graphic, KapaImageWidget *image));
+int	      FlipImageX	  PROTO((Graphic *graphic, KapaImageWidget *image));
+int	      FlipImageY	  PROTO((Graphic *graphic, KapaImageWidget *image));
 int	      Overlay0		  PROTO((Graphic *graphic, KapaImageWidget *image));
 int	      Overlay1		  PROTO((Graphic *graphic, KapaImageWidget *image));
Index: /trunk/Ohana/src/kapa2/include/structures.h
===================================================================
--- /trunk/Ohana/src/kapa2/include/structures.h	(revision 16809)
+++ /trunk/Ohana/src/kapa2/include/structures.h	(revision 16810)
@@ -180,4 +180,6 @@
   Button   heat_button;
   Button   overlay_button[NOVERLAYS];
+  Button   flipx_button;
+  Button   flipy_button;
 
   // location of the status box
Index: /trunk/Ohana/src/kapa2/src/ButtonFunctions.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/ButtonFunctions.c	(revision 16809)
+++ /trunk/Ohana/src/kapa2/src/ButtonFunctions.c	(revision 16810)
@@ -17,5 +17,4 @@
   CreateWide (graphic, image); 
   Refresh ();
-  XFlush (graphic[0].display);
   return (TRUE);
 }
@@ -29,5 +28,4 @@
   CreateWide (graphic, image); 
   Refresh ();
-  XFlush (graphic[0].display);
   return (TRUE);
 }
@@ -41,5 +39,4 @@
   CreateWide (graphic, image); 
   Refresh ();
-  XFlush (graphic[0].display);
   return (TRUE);
 }
@@ -52,5 +49,4 @@
   Remap (graphic, image);
   Refresh ();
-  FlushDisplay (graphic[0].display);
   return (TRUE);
 
@@ -62,5 +58,4 @@
   Remap (graphic, image);
   Refresh ();
-  FlushDisplay (graphic[0].display);
   return (TRUE);
 
@@ -75,14 +70,34 @@
   Remap (graphic, image);
   Refresh ();
-  FlushDisplay (graphic[0].display);
   return (TRUE);
 
 }
 
+int FlipImageX (Graphic *graphic, KapaImageWidget *image) {
+
+  image[0].picture.flipx = !image[0].picture.flipx;
+  image[0].zoom.flipx 	 = !image[0].zoom.flipx;
+  image[0].wide.flipx 	 = !image[0].wide.flipx;
+ 
+  Remap (graphic, image);
+  CreateWide (graphic, image);
+  Refresh ();
+  return (TRUE);
+}
+
+int FlipImageY (Graphic *graphic, KapaImageWidget *image) {
+
+  image[0].picture.flipy = !image[0].picture.flipy;
+  image[0].zoom.flipy 	 = !image[0].zoom.flipy;
+  image[0].wide.flipy 	 = !image[0].wide.flipy;
+ 
+  Remap (graphic, image);
+  CreateWide (graphic, image);
+  Refresh ();
+  return (TRUE);
+}
+
 int ToggleDEG (Graphic *graphic, KapaImageWidget *image) {
 
-  image[0].picture.flipy = !image[0].picture.flipy;
-  image[0].zoom.flipy = !image[0].zoom.flipy;
-  image[0].wide.flipy = !image[0].wide.flipy;
   image[0].DecimalDegrees = image[0].DecimalDegrees ^ TRUE;
   StatusBox (graphic, image);
@@ -97,5 +112,4 @@
   image[0].overlay[0].active = image[0].overlay[0].active ^ TRUE;
   Refresh ();
-  FlushDisplay (graphic[0].display);
   return (TRUE);
 
@@ -106,5 +120,4 @@
   image[0].overlay[1].active = image[0].overlay[1].active ^ TRUE;
   Refresh ();
-  FlushDisplay (graphic[0].display);
   return (TRUE);
 
@@ -115,5 +128,4 @@
   image[0].overlay[2].active = image[0].overlay[2].active ^ TRUE;
   Refresh ();
-  FlushDisplay (graphic[0].display);
   return (TRUE);
 
@@ -124,5 +136,4 @@
   image[0].overlay[3].active = image[0].overlay[3].active ^ TRUE;
   Refresh ();
-  FlushDisplay (graphic[0].display);
   return (TRUE);
 
Index: /trunk/Ohana/src/kapa2/src/CheckButtons.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/CheckButtons.c	(revision 16809)
+++ /trunk/Ohana/src/kapa2/src/CheckButtons.c	(revision 16810)
@@ -26,4 +26,10 @@
     button = &image[0].hms_button;
 
+  if (InButton (event, &image[0].flipx_button)) 
+    button = &image[0].flipx_button;
+
+  if (InButton (event, &image[0].flipy_button)) 
+    button = &image[0].flipy_button;
+
   for (i = 0; i < NOVERLAYS; i++) {
     if (InButton (event, &image[0].overlay_button[i])) 
Index: /trunk/Ohana/src/kapa2/src/CheckVisual.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/CheckVisual.c	(revision 16809)
+++ /trunk/Ohana/src/kapa2/src/CheckVisual.c	(revision 16810)
@@ -14,5 +14,5 @@
   unsigned long planes[3];
   XPixmapFormatValues *pixmaps;
-  int Npixmaps;
+  int Npixmaps, Npixels;
 
   if (DEBUG) {
@@ -127,8 +127,15 @@
 
   if (isDynamic) {
+    Npixels = NPIXELS_DYNAMIC;
+    if ((N = get_argument (*argc, argv, "-ncolors"))) {
+      remove_argument(N, argc, argv);
+      Npixels = atoi (argv[N]);
+      remove_argument(N, argc, argv);
+    } 
+
     /* allocate color cells */
-    ALLOCATE (graphic[0].pixels, unsigned long, NPIXELS_DYNAMIC);
-    ALLOCATE (graphic[0].cmap,   XColor,        NPIXELS_DYNAMIC);
-    for (graphic[0].Npixels = NPIXELS_DYNAMIC; graphic[0].Npixels >= 16; graphic[0].Npixels -= 4) {
+    ALLOCATE (graphic[0].pixels, unsigned long, Npixels);
+    ALLOCATE (graphic[0].cmap,   XColor,        Npixels);
+    for (graphic[0].Npixels = Npixels; graphic[0].Npixels >= 16; graphic[0].Npixels -= 4) {
       if (DEBUG) fprintf (stderr, "trying %d colors\n", (int) graphic[0].Npixels);
       if (XAllocColorCells (graphic[0].display, graphic[0].colormap, FALSE, planes, 1, graphic[0].pixels, graphic[0].Npixels)) {
@@ -163,8 +170,15 @@
     }
   } else {
+    Npixels = NPIXELS_STATIC;
+    if ((N = get_argument (*argc, argv, "-ncolors"))) {
+      remove_argument(N, argc, argv);
+      Npixels = atoi (argv[N]);
+      remove_argument(N, argc, argv);
+    } 
+
     // XXX allocate the unsigned long *pixels here and above
-    ALLOCATE (graphic[0].pixels, unsigned long, NPIXELS_STATIC);
-    ALLOCATE (graphic[0].cmap,   XColor,        NPIXELS_STATIC);
-    graphic[0].Npixels = NPIXELS_STATIC;
+    ALLOCATE (graphic[0].pixels, unsigned long, Npixels);
+    ALLOCATE (graphic[0].cmap,   XColor,        Npixels);
+    graphic[0].Npixels = Npixels;
   }
 
Index: /trunk/Ohana/src/kapa2/src/Image.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/Image.c	(revision 16809)
+++ /trunk/Ohana/src/kapa2/src/Image.c	(revision 16810)
@@ -106,4 +106,10 @@
   InitButtonSize (&image[0].hms_button, hms_width, hms_height, hms_bits);
   InitButtonFunc (&image[0].hms_button, ToggleDEG);
+
+  InitButtonSize (&image[0].flipx_button, flipx_width, flipx_height, flipx_bits);
+  InitButtonFunc (&image[0].flipx_button, FlipImageX);
+
+  InitButtonSize (&image[0].flipy_button, flipy_width, flipy_height, flipy_bits);
+  InitButtonFunc (&image[0].flipy_button, FlipImageY);
 
   return (image);
@@ -175,4 +181,7 @@
     DrawButton (graphic, &image[0].hms_button);
 
+    DrawButton (graphic, &image[0].flipx_button);
+    DrawButton (graphic, &image[0].flipy_button);
+
     for (i = 0; i < NOVERLAYS; i++) {
       DrawButton (graphic, &image[0].overlay_button[i]);
Index: /trunk/Ohana/src/kapa2/src/SetImageSize.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/SetImageSize.c	(revision 16809)
+++ /trunk/Ohana/src/kapa2/src/SetImageSize.c	(revision 16810)
@@ -26,6 +26,11 @@
   dY = graphic[0].dy * section[0].dy;
 
+  textpad = USE_XWINDOW ? graphic[0].font[0].ascent : 10;
+  textdY = 6*textpad + 7*PAD1;
+  WdY = MAX (ZOOM_Y, textdY + 2*BUTTON_HEIGHT + PAD1);
+
   switch (image[0].location) {
-    case 0:
+
+    case 0: // no zoom / status / wide
       if (section->graph) {
 	  image[0].picture.x  = graph[0].axis[0].fx;
@@ -43,8 +48,5 @@
       return;
 
-    case 1:
-      textpad = USE_XWINDOW ? graphic[0].font[0].ascent : 10;
-      textdY = 6*textpad + 7*PAD1;
-      WdY = MAX (ZOOM_Y, textdY + 2*BUTTON_HEIGHT + PAD1);
+    case 1: // zoom / status / wide on bottom
 
       if (section->graph) {
@@ -110,16 +112,20 @@
       image[0].recenter_button.y = image[0].PS_button.y;
 
+      // add just below
+      image[0].flipx_button.x = image[0].recenter_button.x + image[0].recenter_button.dx + PAD1;
+      image[0].flipx_button.y = image[0].recenter_button.y;
+
+      image[0].flipy_button.x = image[0].hms_button.x + image[0].hms_button.dx + PAD1;
+      image[0].flipy_button.y = image[0].hms_button.y;
+
       // XXX zoom should scale somewhat with the image? (with a min and a max)
       // XXX actually, it is limited by the buttons and status region
       image[0].wide.dx = ZOOM_X; 
       image[0].wide.dy = ZOOM_Y;
-      image[0].wide.x = image[0].recenter_button.x + image[0].recenter_button.dx + PAD1;
-      image[0].wide.y = image[0].PS_button.y;
-      break;
-
-    case 3:
-      textpad = USE_XWINDOW ? graphic[0].font[0].ascent : 10;
-      textdY = 6*textpad + 7*PAD1;
-      WdY = MAX (ZOOM_Y, textdY + 2*BUTTON_HEIGHT + PAD1);
+      image[0].wide.x = image[0].flipx_button.x + image[0].flipx_button.dx + PAD1;
+      image[0].wide.y = image[0].zoom.y;
+      break;
+
+    case 3: // zoom / status / wide on top
 
       if (section->graph) {
@@ -185,13 +191,20 @@
       image[0].recenter_button.y = image[0].PS_button.y;
 
+      // add just below
+      image[0].flipx_button.x = image[0].recenter_button.x + image[0].recenter_button.dx + PAD1;
+      image[0].flipx_button.y = image[0].recenter_button.y;
+
+      image[0].flipy_button.x = image[0].hms_button.x + image[0].hms_button.dx + PAD1;
+      image[0].flipy_button.y = image[0].hms_button.y;
+
       // XXX zoom should scale somewhat with the image? (with a min and a max)
       // XXX actually, it is limited by the buttons and status region
       image[0].wide.dx = ZOOM_X; 
       image[0].wide.dy = ZOOM_Y;
-      image[0].wide.x = image[0].PS_button.x;
-      image[0].wide.y = image[0].PS_button.y + BUTTON_HEIGHT + PAD1;
-      break;
-
-    case 2:
+      image[0].wide.x = image[0].flipx_button.x + image[0].flipx_button.dx + PAD1;
+      image[0].wide.y = image[0].zoom.y;
+      break;
+
+    case 2: // zoom / status / wide on left
 
       if (section->graph) {
@@ -220,5 +233,4 @@
 
       /** everything below is tied in x-dir to the zoom box **/
-      textpad = USE_XWINDOW ? graphic[0].font[0].ascent : 10;
       image[0].text_x = image[0].zoom.x;
       image[0].text_y = image[0].zoom.y + image[0].zoom.dy + PAD1;
@@ -258,13 +270,20 @@
       image[0].recenter_button.y = image[0].PS_button.y;
 
+      // add just below
+      image[0].flipx_button.x = image[0].PS_button.x;
+      image[0].flipx_button.y = image[0].PS_button.y + BUTTON_HEIGHT + PAD1;
+
+      image[0].flipy_button.x = image[0].flipx_button.x + image[0].flipx_button.dx + PAD1;
+      image[0].flipy_button.y = image[0].flipx_button.y;
+
       // XXX zoom should scale somewhat with the image? (with a min and a max)
       // XXX actually, it is limited by the buttons and status region
       image[0].wide.dx = ZOOM_X; 
       image[0].wide.dy = ZOOM_Y;
-      image[0].wide.x = image[0].recenter_button.x + image[0].recenter_button.dx + PAD1;
-      image[0].wide.y = image[0].PS_button.y;
-      break;
-
-    case 4:
+      image[0].wide.x = image[0].flipx_button.x;
+      image[0].wide.y = image[0].flipx_button.y + BUTTON_HEIGHT + PAD1;
+      break;
+
+    case 4:  // zoom / status / wide on right
 
       if (section->graph) {
@@ -293,5 +312,4 @@
 
       /** everything below is tied in x-dir to the zoom box **/
-      textpad = USE_XWINDOW ? graphic[0].font[0].ascent : 10;
       image[0].text_x = image[0].zoom.x;
       image[0].text_y = image[0].zoom.y + image[0].zoom.dy + PAD1;
@@ -331,10 +349,17 @@
       image[0].recenter_button.y = image[0].PS_button.y;
 
+      // add just below
+      image[0].flipx_button.x = image[0].zoom.x;
+      image[0].flipx_button.y = image[0].PS_button.y + BUTTON_HEIGHT + PAD1;
+
+      image[0].flipy_button.x = image[0].flipx_button.x + image[0].flipx_button.dx + PAD1;
+      image[0].flipy_button.y = image[0].flipx_button.y;
+
       // XXX zoom should scale somewhat with the image? (with a min and a max)
       // XXX actually, it is limited by the buttons and status region
       image[0].wide.dx = ZOOM_X; 
       image[0].wide.dy = ZOOM_Y;
-      image[0].wide.x = image[0].PS_button.x;
-      image[0].wide.y = image[0].PS_button.y + BUTTON_HEIGHT + PAD1;
+      image[0].wide.x = image[0].flipx_button.x;
+      image[0].wide.y = image[0].flipx_button.y + BUTTON_HEIGHT + PAD1;
       break;
 
Index: /trunk/Ohana/src/libautocode/Makefile.Targets
===================================================================
--- /trunk/Ohana/src/libautocode/Makefile.Targets	(revision 16809)
+++ /trunk/Ohana/src/libautocode/Makefile.Targets	(revision 16810)
@@ -8,4 +8,5 @@
 $(ASRC)/average-panstarrs-dev-1.$(ARCH).o \
 $(ASRC)/average-ps1-dev-1.$(ARCH).o \
+$(ASRC)/average-ps1-dev-2.$(ARCH).o \
 $(ASRC)/secfilt.$(ARCH).o \
 $(ASRC)/secfilt-loneos.$(ARCH).o \
@@ -14,4 +15,5 @@
 $(ASRC)/secfilt-panstarrs-dev-1.$(ARCH).o \
 $(ASRC)/secfilt-ps1-dev-1.$(ARCH).o \
+$(ASRC)/secfilt-ps1-dev-2.$(ARCH).o \
 $(ASRC)/measure.$(ARCH).o \
 $(ASRC)/measure-loneos.$(ARCH).o \
@@ -20,8 +22,10 @@
 $(ASRC)/measure-panstarrs-dev-1.$(ARCH).o \
 $(ASRC)/measure-ps1-dev-1.$(ARCH).o \
+$(ASRC)/measure-ps1-dev-2.$(ARCH).o \
 $(ASRC)/missing.$(ARCH).o \
 $(ASRC)/photcode.$(ARCH).o \
 $(ASRC)/photcode-elixir.$(ARCH).o \
 $(ASRC)/photcode-ps1-dev-1.$(ARCH).o \
+$(ASRC)/photcode-ps1-dev-2.$(ARCH).o \
 $(ASRC)/image.$(ARCH).o \
 $(ASRC)/image-loneos.$(ARCH).o \
@@ -30,4 +34,5 @@
 $(ASRC)/image-panstarrs-dev-1.$(ARCH).o \
 $(ASRC)/image-ps1-dev-1.$(ARCH).o \
+$(ASRC)/image-ps1-dev-2.$(ARCH).o \
 $(ASRC)/regimage.$(ARCH).o \
 $(ASRC)/detreg.$(ARCH).o \
@@ -55,4 +60,5 @@
 $(AINC)/average-panstarrs-dev-1.h \
 $(AINC)/average-ps1-dev-1.h \
+$(AINC)/average-ps1-dev-2.h \
 $(AINC)/secfilt.h \
 $(AINC)/secfilt-loneos.h \
@@ -61,4 +67,5 @@
 $(AINC)/secfilt-panstarrs-dev-1.h \
 $(AINC)/secfilt-ps1-dev-1.h \
+$(AINC)/secfilt-ps1-dev-2.h \
 $(AINC)/measure.h \
 $(AINC)/measure-loneos.h \
@@ -67,8 +74,10 @@
 $(AINC)/measure-panstarrs-dev-1.h \
 $(AINC)/measure-ps1-dev-1.h \
+$(AINC)/measure-ps1-dev-2.h \
 $(AINC)/missing.h \
 $(AINC)/photcode.h \
 $(AINC)/photcode-elixir.h \
 $(AINC)/photcode-ps1-dev-1.h \
+$(AINC)/photcode-ps1-dev-2.h \
 $(AINC)/image.h \
 $(AINC)/image-loneos.h \
@@ -77,4 +86,5 @@
 $(AINC)/image-panstarrs-dev-1.h \
 $(AINC)/image-ps1-dev-1.h \
+$(AINC)/image-ps1-dev-2.h \
 $(AINC)/regimage.h \
 $(AINC)/detreg.h \
Index: /trunk/Ohana/src/libautocode/def/AddstarClientOptions.d
===================================================================
--- /trunk/Ohana/src/libautocode/def/AddstarClientOptions.d	(revision 16809)
+++ /trunk/Ohana/src/libautocode/def/AddstarClientOptions.d	(revision 16810)
@@ -2,9 +2,10 @@
 EXTNAME OPTIONS
 TYPE    BINTABLE
-SIZE    76
+SIZE    80
 
 FIELD     Nsigma,           NSIGMA,               double,         match radius in terms of astrometric error 
 FIELD     radius,           RADIUS,		  double,         match radius in arcsec (default)
 FIELD  	  mode,             MODE,                 int,            data source mode
+FIELD  	  filelist,         FILELIST,             int,            if true file is a list of input files
 FIELD  	  existing_regions, EXISTING_REGIONS,     int,            use only existing regions
 FIELD  	  only_match,       ONLY_MATCH,           int,            only update matched stars
Index: /trunk/Ohana/src/libautocode/def/Stars.d
===================================================================
--- /trunk/Ohana/src/libautocode/def/Stars.d	(revision 16809)
+++ /trunk/Ohana/src/libautocode/def/Stars.d	(revision 16810)
@@ -2,5 +2,5 @@
 EXTNAME STARS
 TYPE    BINTABLE
-SIZE    244
+SIZE    248
 
 FIELD     X,                X,          double,    x coordinate on image,	     pixels
@@ -20,4 +20,5 @@
 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
@@ -25,12 +26,13 @@
 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     Mgal,             MGAL,       double,    alternative (galaxy) 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     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     psfProb,          PSF_PROB,   float
+FIELD     psfChisq,         PSF_CHISQ,  float
 FIELD     crNsigma,         CR_NSIGMA,  float
 FIELD     extNsigma,        EXT_NSIGMA, float
Index: /trunk/Ohana/src/libautocode/def/average-panstarrs-dev-0.d
===================================================================
--- /trunk/Ohana/src/libautocode/def/average-panstarrs-dev-0.d	(revision 16809)
+++ /trunk/Ohana/src/libautocode/def/average-panstarrs-dev-0.d	(revision 16810)
@@ -27,6 +27,6 @@
 
 # Pan-STARRS uses a 64-bit detection ID.  keep this in two 32 bit ints for backwards compatibility?
-FIELD objID_hi,       OBJ_ID_HI,    unsigned int,   ID upper bytes
-FIELD objID_lo,       OBJ_ID_LO,    unsigned int,   ID lower bytes
+FIELD objID,          OBJ_ID,     unsigned int,   ID upper bytes
+FIELD catID,          CAT_ID,     unsigned int,   ID lower bytes
 
 # this structure should only be used for internal representations
Index: /trunk/Ohana/src/libautocode/def/average-panstarrs-dev-1.d
===================================================================
--- /trunk/Ohana/src/libautocode/def/average-panstarrs-dev-1.d	(revision 16809)
+++ /trunk/Ohana/src/libautocode/def/average-panstarrs-dev-1.d	(revision 16810)
@@ -27,6 +27,6 @@
 
 # Pan-STARRS uses a 64-bit detection ID.  keep this in two 32 bit ints for backwards compatibility?
-FIELD objID_hi,       OBJ_ID_HI,    unsigned int,   ID upper bytes
-FIELD objID_lo,       OBJ_ID_LO,    unsigned int,   ID lower bytes
+FIELD objID,          OBJ_ID,     unsigned int,   ID upper bytes
+FIELD catID,          CAT_ID,     unsigned int,   ID lower bytes
 
 # this structure should only be used for internal representations
Index: /trunk/Ohana/src/libautocode/def/average-ps1-dev-1.d
===================================================================
--- /trunk/Ohana/src/libautocode/def/average-ps1-dev-1.d	(revision 16809)
+++ /trunk/Ohana/src/libautocode/def/average-ps1-dev-1.d	(revision 16810)
@@ -27,6 +27,6 @@
 
 # Pan-STARRS uses a 64-bit detection ID.  keep this in two 32 bit ints for backwards compatibility?
-FIELD objID_hi,       OBJ_ID_HI,    unsigned int,   ID upper bytes
-FIELD objID_lo,       OBJ_ID_LO,    unsigned int,   ID lower bytes
+FIELD objID,          OBJ_ID,     unsigned int,   ID upper bytes
+FIELD catID,          CAT_ID,     unsigned int,   ID lower bytes
 
 # this structure should only be used for internal representations
Index: /trunk/Ohana/src/libautocode/def/average-ps1-dev-2.d
===================================================================
--- /trunk/Ohana/src/libautocode/def/average-ps1-dev-2.d	(revision 16809)
+++ /trunk/Ohana/src/libautocode/def/average-ps1-dev-2.d	(revision 16810)
@@ -2,5 +2,5 @@
 EXTNAME      DVO_AVERAGE_PS1_DEV_2
 TYPE         BINTABLE
-SIZE         72
+SIZE         80
 DESCRIPTION  DVO Average Object Table
 
@@ -19,17 +19,26 @@
 FIELD dP,             PAR_ERR,    float,            parallax error,               arcsec
 
-FIELD Xp,             SIGMA_POS,  short, 	    position scatter,   	  1/100 arcsec
-FIELD Npsf,           NPSF,       unsigned short,   number of psf measurements
-FIELD Next,           NEXT,       unsigned short,   number of extended measurements
-FIELD Nmiss,          NMISS,      unsigned short,   number of missings
-FIELD psfOffset,      OFF_PSF,    int,     	    offset to first measurement
-FIELD extOffset,      OFF_EXT,    int,     	    offset to first measurement
-FIELD missOffset,     OFF_MISS,   int,     	    offset to first missing obs
+FIELD Xp,             SIGMA_POS,   short, 	    position scatter,   	  1/100 arcsec
+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
 
-# Pan-STARRS uses a 64-bit detection ID.  keep this in two 32 bit ints for backwards compatibility?
-FIELD objID_hi,       OBJ_ID_HI,  unsigned int,     ID upper bytes
-FIELD objID_lo,       OBJ_ID_LO,  unsigned int,     ID lower bytes
+# 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.
+
+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
 
 # this structure should only be used for internal representations
Index: /trunk/Ohana/src/libautocode/def/average.d
===================================================================
--- /trunk/Ohana/src/libautocode/def/average.d	(revision 16809)
+++ /trunk/Ohana/src/libautocode/def/average.d	(revision 16810)
@@ -2,5 +2,5 @@
 EXTNAME      DVO_AVERAGE
 TYPE         BINTABLE
-SIZE         72
+SIZE         80
 DESCRIPTION  DVO Average Object Table
 
@@ -19,14 +19,26 @@
 FIELD dP,             PAR_ERR,    float,            parallax error,               arcsec
 
-FIELD Xp,             SIGMA_POS,  short, 	    position scatter,   	  1/100 arcsec
-FIELD Nm,             NMEAS,      unsigned short,   number of measures
-FIELD Nn,             NMISS,      unsigned short,   number of missings
+FIELD Xp,             SIGMA_POS,   short, 	    position scatter,   	  1/100 arcsec
+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 offset,         offset,     int,     	    offset to first measurement
-FIELD missing,        missing,    int,     	    offset to first missing obs
+FIELD dummy,          DUMMY,      char[2],          padding
 
-# Pan-STARRS uses a 64-bit detection ID.  keep this in two 32 bit ints for backwards compatibility?
-FIELD objID_hi,       OBJ_ID_HI,    unsigned int,   ID upper bytes
-FIELD objID_lo,       OBJ_ID_LO,    unsigned int,   ID lower bytes
+# 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.
+
+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
 
 # this structure should only be used for internal representations
Index: /trunk/Ohana/src/libautocode/def/extend-ps1-dev-2.d
===================================================================
--- /trunk/Ohana/src/libautocode/def/extend-ps1-dev-2.d	(revision 16809)
+++ /trunk/Ohana/src/libautocode/def/extend-ps1-dev-2.d	(revision 16810)
@@ -1,6 +1,6 @@
-STRUCT       Extend_PS1_DEV_1
-EXTNAME      DVO_EXTEND_PS1_DEV_1
+STRUCT       Extend_PS1_DEV_2
+EXTNAME      DVO_EXTEND_PS1_DEV_2
 TYPE         BINTABLE
-SIZE         104
+SIZE         160
 DESCRIPTION  DVO Detection Extended Source Parameters Table 
 
@@ -15,4 +15,5 @@
 FIELD imageID,        IMAGE_ID,     	  unsigned int,   reference to image
 FIELD photcode,       PHOTCODE,     	  unsigned short, photcode
+FIELD padding,        PADDING,     	  unsigned short, padding
 
 FIELD FWx,            EXT_MAJOR,    	  float,          object fwhm major axis
Index: /trunk/Ohana/src/libautocode/def/extmodel-ps1-dev-2.d
===================================================================
--- /trunk/Ohana/src/libautocode/def/extmodel-ps1-dev-2.d	(revision 16810)
+++ /trunk/Ohana/src/libautocode/def/extmodel-ps1-dev-2.d	(revision 16810)
@@ -0,0 +1,22 @@
+STRUCT       ExtModel_PS1_DEV_2
+EXTNAME      DVO_EXTMODEL_PS1_DEV_2
+TYPE         BINTABLE
+SIZE         104
+DESCRIPTION  DVO Detection Extended Model Fits
+
+FIELD dR,             D_RA,         	  float,          RA offset,                	  arcsec
+FIELD dD,             D_DEC,        	  float,          DEC offset,               	  arcsec
+FIELD M,              MAG,          	  float,          catalog mag,       	       	  mag
+FIELD dM,             MAG_ERR,      	  float,          mag error,                    mag
+
+# Pan-STARRS uses a 64-bit detection ID.  keep this in two 32 bit ints for backwards compatibility?
+# I don't actually have these indexed, but this lets us match back to the measurement
+FIELD detID,          DET_ID,       	  unsigned int,   detection ID
+FIELD imageID,        IMAGE_ID,     	  unsigned int,   reference to image
+FIELD photcode,       PHOTCODE,     	  unsigned short, photcode
+
+FIELD FWx,            EXT_MAJOR,    	  float,          object fwhm major axis
+FIELD FWy,            EXT_MINOR,    	  float,          object fwhm minor axis
+FIELD theta,          EXT_THETA,    	  float,          angle wrt ccd X dir
+
+## XXX other model parameter values here
Index: /trunk/Ohana/src/libautocode/def/image-ps1-dev-2.d
===================================================================
--- /trunk/Ohana/src/libautocode/def/image-ps1-dev-2.d	(revision 16809)
+++ /trunk/Ohana/src/libautocode/def/image-ps1-dev-2.d	(revision 16810)
@@ -1,6 +1,6 @@
-STRUCT       Image_PS1_DEV_1
-EXTNAME      DVO_IMAGE_PS1_DEV_1
+STRUCT       Image_PS1_DEV_2
+EXTNAME      DVO_IMAGE_PS1_DEV_2
 TYPE         BINTABLE
-SIZE         288
+SIZE         280
 DESCRIPTION  DVO Image Table 
 
@@ -26,6 +26,6 @@
 FIELD 	  nstar,            NSTAR,                unsigned int,   number of stars on image
 FIELD 	  secz,             SECZ,                 float,      	  airmass,                   mag
-FIELD 	  NX,               NX,                   short,      	  image width
-FIELD 	  NY,               NY,                   short,      	  image height
+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
@@ -48,8 +48,9 @@
 FIELD 	  code,             CODE,                 char,           image quality flag
 FIELD 	  ccdnum,           CCDNUM,               unsigned char,  CCD ID number
-FIELD 	  imageID,          IMAGE_ID,             unsigned int,   image ID
-# 44 bytes 
+FIELD 	  imageID,          IMAGE_ID,             unsigned int,   internal image ID
+FIELD 	  externID,         EXTERN_ID,            unsigned int,   external image ID
+FIELD 	  sourceID,         SOURCE_ID,            unsigned short, analysis source ID
+# 48 bytes 
 
-FIELD 	  dummy,            DUMMY,                char[14],       unused
 FIELD 	  order,            ORDER,                short,      	  Mrel 2D polynomical order 
 FIELD 	  Mx,               MX,                   short,      	  Mrel polyterm
Index: /trunk/Ohana/src/libautocode/def/image.d
===================================================================
--- /trunk/Ohana/src/libautocode/def/image.d	(revision 16809)
+++ /trunk/Ohana/src/libautocode/def/image.d	(revision 16810)
@@ -2,5 +2,5 @@
 EXTNAME      DVO_IMAGE
 TYPE         BINTABLE
-SIZE         288
+SIZE         280
 DESCRIPTION  DVO Image Table 
 
@@ -48,8 +48,9 @@
 FIELD 	  code,             CODE,                 char,           image quality flag
 FIELD 	  ccdnum,           CCDNUM,               unsigned char,  CCD ID number
-FIELD 	  imageID,          IMAGE_ID,             unsigned int,   image ID
+FIELD 	  imageID,          IMAGE_ID,             unsigned int,   internal image ID
+FIELD 	  externID,         EXTERN_ID,            unsigned int,   external image ID
+FIELD 	  sourceID,         SOURCE_ID,            unsigned short, analysis source ID
 # 48 bytes 
 
-FIELD 	  dummy,            DUMMY,                char[14],       unused
 FIELD 	  order,            ORDER,                short,      	  Mrel 2D polynomical order 
 FIELD 	  Mx,               MX,                   short,      	  Mrel polyterm
Index: /trunk/Ohana/src/libautocode/def/measure-ps1-dev-1.d
===================================================================
--- /trunk/Ohana/src/libautocode/def/measure-ps1-dev-1.d	(revision 16809)
+++ /trunk/Ohana/src/libautocode/def/measure-ps1-dev-1.d	(revision 16810)
@@ -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 psfProb,        PSF_PROB,     float,          psf coverage/quality factor
+FIELD psfChisq,       PSF_CHISQ,    float,          psf coverage/quality factor
 FIELD crNsigma,       CR_NSIGMA,    float,          psf coverage/quality factor
 FIELD extNsigma,      EXT_NSIGMA,   float,          psf coverage/quality factor
Index: /trunk/Ohana/src/libautocode/def/measure-ps1-dev-2.d
===================================================================
--- /trunk/Ohana/src/libautocode/def/measure-ps1-dev-2.d	(revision 16809)
+++ /trunk/Ohana/src/libautocode/def/measure-ps1-dev-2.d	(revision 16810)
@@ -1,6 +1,6 @@
-STRUCT       Measure_PS1_DEV_1
-EXTNAME      DVO_MEASURE_PS1_DEV_1
+STRUCT       Measure_PS1_DEV_2
+EXTNAME      DVO_MEASURE_PS1_DEV_2
 TYPE         BINTABLE
-SIZE         104
+SIZE         112
 DESCRIPTION  DVO Detection Measurement Table 
 
@@ -9,6 +9,7 @@
 FIELD M,              MAG,          float,          catalog mag,       	       	  mag
 FIELD Mcal,           M_CAL,        float,          image cal mag,	          mag
-FIELD Mgal,           M_GAL,        float,          galaxy 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)
 
@@ -30,11 +31,11 @@
 # 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 image
+FIELD imageID,        IMAGE_ID,     unsigned int,   reference to DVO image ID
 
 # do we need more resolution than a short? should this be a log?
 FIELD qPSF,           PSF_QF,       float,          psf coverage/quality factor
-FIELD psfProb,        PSF_PROB,     float,          psf coverage/quality factor
-FIELD crNsigma,       CR_NSIGMA,    float,          psf coverage/quality factor
-FIELD extNsigma,      EXT_NSIGMA,   float,          psf coverage/quality factor
+FIELD psfChisq,       PSF_CHISQ,    float,          psf fit chisq
+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 
@@ -54,3 +55,3 @@
 FIELD dophot,         DOPHOT,       char,           dophot type
 
-FIELD dummy,          DUMMY,        char[2],        padding
+FIELD dummy,          DUMMY,        char[6],        padding
Index: /trunk/Ohana/src/libautocode/def/measure.d
===================================================================
--- /trunk/Ohana/src/libautocode/def/measure.d	(revision 16809)
+++ /trunk/Ohana/src/libautocode/def/measure.d	(revision 16810)
@@ -2,5 +2,5 @@
 EXTNAME      DVO_MEASURE
 TYPE         BINTABLE
-SIZE         104
+SIZE         112
 DESCRIPTION  DVO Detection Measurement Table 
 
@@ -9,6 +9,7 @@
 FIELD M,              MAG,          float,          catalog mag,       	       	  mag
 FIELD Mcal,           M_CAL,        float,          image cal mag,	          mag
-FIELD Mgal,           M_GAL,        float,          galaxy 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)
 
@@ -30,11 +31,11 @@
 # 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 image
+FIELD imageID,        IMAGE_ID,     unsigned int,   reference to DVO image ID
 
 # do we need more resolution than a short? should this be a log?
 FIELD qPSF,           PSF_QF,       float,          psf coverage/quality factor
-FIELD psfProb,        PSF_PROB,     float,          psf coverage/quality factor
-FIELD crNsigma,       CR_NSIGMA,    float,          psf coverage/quality factor
-FIELD extNsigma,      EXT_NSIGMA,   float,          psf coverage/quality factor
+FIELD psfChisq,       PSF_CHISQ,    float,          psf fit chisq
+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 
@@ -43,4 +44,5 @@
 FIELD photcode,       PHOTCODE,     unsigned short, photcode
 
+# 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
@@ -54,3 +56,3 @@
 FIELD dophot,         DOPHOT,       char,           dophot type
 
-FIELD dummy,          DUMMY,        char[2],        padding
+FIELD dummy,          DUMMY,        char[6],        padding
Index: /trunk/Ohana/src/libautocode/def/photcode-ps1-dev-1.d
===================================================================
--- /trunk/Ohana/src/libautocode/def/photcode-ps1-dev-1.d	(revision 16809)
+++ /trunk/Ohana/src/libautocode/def/photcode-ps1-dev-1.d	(revision 16810)
@@ -6,18 +6,18 @@
 
 # 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  astromScale,  ASTROM_SCALE,  float,          astrom error = mag error * astromScale
-FIELD  photSysErr,   PHOT_SYS_ERR,  float,          systematic photometric error
-FIELD  padding,      PADDING,       float[4],       placeholder
+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  astromErrMagScale, ASTROM_ERR_MAG_SCALE,  float,          astrometric error / mag error scale
+FIELD  photomErrSys,   	  PHOTOM_ERR_SYS,  	 float,          systematic photometric error
+FIELD  padding,           PADDING,               float[4],       placeholder
Index: /trunk/Ohana/src/libautocode/def/photcode-ps1-dev-2.d
===================================================================
--- /trunk/Ohana/src/libautocode/def/photcode-ps1-dev-2.d	(revision 16809)
+++ /trunk/Ohana/src/libautocode/def/photcode-ps1-dev-2.d	(revision 16810)
@@ -1,23 +1,29 @@
-STRUCT       PhotCode_PS1_DEV_1
-EXTNAME      DVO_PHOTCODE_PS1_DEV_1
+STRUCT       PhotCode_PS1_DEV_2
+EXTNAME      DVO_PHOTCODE_PS1_DEV_2
 TYPE         BINTABLE
-SIZE         104
+SIZE         96
 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  astromScale,  ASTROM_SCALE,  float,          astrom error = mag error * astromScale
-FIELD  photSysErr,   PHOT_SYS_ERR,  float,          systematic photometric error
-FIELD  padding,      PADDING,       float[4],       placeholder
+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  photomErrSys,   	  PHOTOM_ERR_SYS,  	 float,          systematic photometric error
+
+#   dR_total^2 =  dR_sys^2 + AS * dR_obs^2 + MS * dM_obs^2
+#   dR_sys : systematicAstrometryError
+#   AS     : astrometryErrorScale
+#   MS     : astrometryErrorMagScale
Index: /trunk/Ohana/src/libautocode/def/photcode.d
===================================================================
--- /trunk/Ohana/src/libautocode/def/photcode.d	(revision 16809)
+++ /trunk/Ohana/src/libautocode/def/photcode.d	(revision 16810)
@@ -2,22 +2,28 @@
 EXTNAME      DVO_PHOTCODE_RAW
 TYPE         BINTABLE
-SIZE         104
+SIZE         96
 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  astromScale,  ASTROM_SCALE,  float,          astrom error = mag error * astromScale
-FIELD  photSysErr,   PHOT_SYS_ERR,  float,          systematic photometric error
-FIELD  padding,      PADDING,       float[4],       placeholder
+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  photomErrSys,   	  PHOTOM_ERR_SYS,  	 float,          systematic photometric error
+
+#   dR_total^2 =  dR_sys^2 + AS * dR_obs^2 + MS * dM_obs^2
+#   dR_sys : systematicAstrometryError
+#   AS     : astrometryErrorScale
+#   MS     : astrometryErrorMagScale
Index: /trunk/Ohana/src/libautocode/def/ps1_dev_0.d
===================================================================
--- /trunk/Ohana/src/libautocode/def/ps1_dev_0.d	(revision 16809)
+++ /trunk/Ohana/src/libautocode/def/ps1_dev_0.d	(revision 16810)
@@ -16,5 +16,5 @@
 FIELD sky,    	SKY,              float,    sky flux,             cnts/sec
 FIELD dSky,    	SKY_SIG,          float,    sky flux errorf       cnts/sec
-FIELD psfProb,  PSF_PROBABILITY,  float,    psf probability
+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
Index: /trunk/Ohana/src/libautocode/def/ps1_dev_1.d
===================================================================
--- /trunk/Ohana/src/libautocode/def/ps1_dev_1.d	(revision 16809)
+++ /trunk/Ohana/src/libautocode/def/ps1_dev_1.d	(revision 16810)
@@ -16,5 +16,5 @@
 FIELD sky,    	 SKY,              float,    sky flux,             cnts/sec
 FIELD dSky,    	 SKY_SIG,          float,    sky flux errorf       cnts/sec
-FIELD psfProb,   PSF_PROBABILITY,  float,    psf probability
+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
Index: /trunk/Ohana/src/libautocode/def/secfilt-ps1-dev-2.d
===================================================================
--- /trunk/Ohana/src/libautocode/def/secfilt-ps1-dev-2.d	(revision 16809)
+++ /trunk/Ohana/src/libautocode/def/secfilt-ps1-dev-2.d	(revision 16810)
@@ -1,4 +1,4 @@
-STRUCT       SecFilt_PS1_DEV_1
-EXTNAME      DVO_SECFILT_PS1_DEV_1
+STRUCT       SecFilt_PS1_DEV_2
+EXTNAME      DVO_SECFILT_PS1_DEV_2
 TYPE         BINTABLE
 SIZE         16
Index: /trunk/Ohana/src/libdvo/Makefile
===================================================================
--- /trunk/Ohana/src/libdvo/Makefile	(revision 16809)
+++ /trunk/Ohana/src/libdvo/Makefile	(revision 16810)
@@ -29,5 +29,6 @@
 $(DESTINC)/panstarrs_dev_0_defs.h \
 $(DESTINC)/panstarrs_dev_1_defs.h \
-$(DESTINC)/ps1_dev_1_defs.h
+$(DESTINC)/ps1_dev_1_defs.h \
+$(DESTINC)/ps1_dev_2_defs.h
 
 INCS = $(DEFS) $(DESTINC)/dvo.h $(DESTINC)/autocode.h
@@ -37,7 +38,4 @@
 $(SRC)/coordops.$(ARCH).o	 \
 $(SRC)/dvosorts.$(ARCH).o	 \
-$(SRC)/dvo_photcode_ops.$(ARCH).o \
-$(SRC)/dvo_photcode_convert_elixir.$(ARCH).o \
-$(SRC)/dvo_photcode_convert_ps1_dev_1.$(ARCH).o \
 $(SRC)/dvo_photcode_ops.$(ARCH).o \
 $(SRC)/LoadPhotcodes.$(ARCH).o   \
@@ -64,4 +62,5 @@
 $(SRC)/dvo_convert_panstarrs_DEV_1.$(ARCH).o \
 $(SRC)/dvo_convert_PS1_DEV_1.$(ARCH).o \
+$(SRC)/dvo_convert_PS1_DEV_2.$(ARCH).o \
 $(SRC)/skyregion_io.$(ARCH).o    \
 $(SRC)/skyregion_gsc.$(ARCH).o    \
Index: /trunk/Ohana/src/libdvo/include/dvo.h
===================================================================
--- /trunk/Ohana/src/libdvo/include/dvo.h	(revision 16809)
+++ /trunk/Ohana/src/libdvo/include/dvo.h	(revision 16810)
@@ -16,5 +16,6 @@
 	      DVO_FORMAT_PANSTARRS_DEV_0,
 	      DVO_FORMAT_PANSTARRS_DEV_1,
-	      DVO_FORMAT_PS1_DEV_1
+	      DVO_FORMAT_PS1_DEV_1,
+	      DVO_FORMAT_PS1_DEV_2
 } DVOTableFormat;
 
@@ -215,4 +216,7 @@
   struct Catalog *secfilt_catalog;		/* secfilt catalog data (split) */
 
+  unsigned int objID;
+  unsigned int catID;
+
   /* extra catalog information */
   int lockmode;
@@ -383,4 +387,5 @@
 # include "panstarrs_dev_1_defs.h"
 # include "ps1_dev_1_defs.h"
+# include "ps1_dev_2_defs.h"
 
 /*** DVO image db I/O Functions ***/
Index: /trunk/Ohana/src/libdvo/include/ps1_dev_2_defs.h
===================================================================
--- /trunk/Ohana/src/libdvo/include/ps1_dev_2_defs.h	(revision 16810)
+++ /trunk/Ohana/src/libdvo/include/ps1_dev_2_defs.h	(revision 16810)
@@ -0,0 +1,11 @@
+Image 		       	*Image_PS1_DEV_2_ToInternal (Image_PS1_DEV_2 *in, int Nvalues);
+Image_PS1_DEV_2  	*ImageInternalTo_PS1_DEV_2 (Image *in, int Nvalues);
+Average 	       	*Average_PS1_DEV_2_ToInternal (Average_PS1_DEV_2 *in, int Nvalues, SecFilt **primary);
+Average_PS1_DEV_2       *AverageInternalTo_PS1_DEV_2 (Average *in, int Nvalues, SecFilt *primary);
+Measure 	       	*Measure_PS1_DEV_2_ToInternal (Measure_PS1_DEV_2 *in, int Nvalues);
+Measure_PS1_DEV_2       *MeasureInternalTo_PS1_DEV_2 (Measure *in, int Nvalues);
+SecFilt 	       	*SecFilt_PS1_DEV_2_ToInternal (SecFilt_PS1_DEV_2 *in, int Nvalues);
+SecFilt_PS1_DEV_2       *SecFiltInternalTo_PS1_DEV_2 (SecFilt *in, int Nvalues);
+
+PhotCode *PhotCode_PS1_DEV_2_To_Internal (PhotCode_PS1_DEV_2 *in, int Nvalues);
+PhotCode_PS1_DEV_2 *PhotCode_Internal_To_PS1_DEV_2 (PhotCode *in, int Nvalues);
Index: /trunk/Ohana/src/libdvo/src/LoadPhotcodesFITS.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/LoadPhotcodesFITS.c	(revision 16809)
+++ /trunk/Ohana/src/libdvo/src/LoadPhotcodesFITS.c	(revision 16810)
@@ -50,4 +50,10 @@
     photcode = PhotCode_PS1_DEV_1_To_Internal (photcode_ps1_dev_1, Ncode);
     free (photcode_ps1_dev_1);
+  } 
+
+  if (!strcmp (extname, "DVO_PHOTCODE_PS1_DEV_2")) {
+    PhotCode_PS1_DEV_2 *photcode_ps1_dev_2 = gfits_table_get_PhotCode_PS1_DEV_2 (&db.ftable, &Ncode, &db.swapped);
+    photcode = PhotCode_PS1_DEV_2_To_Internal (photcode_ps1_dev_2, Ncode);
+    free (photcode_ps1_dev_2);
   } 
 
Index: /trunk/Ohana/src/libdvo/src/LoadPhotcodesText.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/LoadPhotcodesText.c	(revision 16809)
+++ /trunk/Ohana/src/libdvo/src/LoadPhotcodesText.c	(revision 16810)
@@ -27,6 +27,7 @@
   char *c;
   char line[256], **c1_names, **c2_names, **eq_names;
-  char name[32], type[32], Zero[32], Airmass[32], Offset[32],
-    C1[32], C2[32], Slope[32], Color[32], Primary[32];
+  char name[32], type[32], Zero[32], Airmass[32], Offset[32];
+  char C1[32], C2[32], Slope[32], Color[32], Primary[32];
+  char astromErrSys[32], astromErrScale[32], astromErrMagScale[32], photomErrSys[32];
 
   table = GetPhotcodeTable ();
@@ -60,12 +61,27 @@
     for (c = line; isspace (*c); c++);
     if (*c == '#') continue;
-    Nfield = sscanf (c, "%d %s %s %s %s %s %s %s %s %s %s", 
-		     &code, name, type, Zero, Airmass, Offset, C1, C2, Slope, Color, Primary);
-
-    // XXX to add the AstromError (and PhotError) terms, we need to add them to the photcode structure, and
-    // define methods to read (at least) the old and the new photcode versions.
-
-    if (Nfield != 11) { continue; }
-    
+    Nfield = sscanf (c, "%d %s %s %s %s %s %s %s %s %s %s %s %s %s %s", 
+		     &code, name, type, Zero, Airmass, Offset, C1, C2, Slope, Color, Primary, astromErrSys, astromErrScale, astromErrMagScale, photomErrSys);
+
+    switch (Nfield) {
+      case 11: 
+	// minimum number of fields : original elixir layout
+	strcpy (astromErrSys,      "0.0");
+	strcpy (astromErrScale,    "0.0");
+	strcpy (astromErrMagScale, "0.0");
+	strcpy (photomErrSys,      "0.0");
+	break;
+      case 14: 
+	// allow only astrom elements
+	strcpy (photomErrSys,      "0.0");
+	break;
+      case 15: 
+	// all fields defined
+	break;
+      default:
+	// skip unknown layouts
+	continue;
+    }
+
     if (!code) {
 	fprintf (stderr, "photcode values may not be 0: fix %s\n", name);
@@ -95,4 +111,9 @@
       photcode[Ncode].type  = PHOT_ALT;
     }
+
+    photcode[Ncode].astromErrSys      = atof (astromErrSys);
+    photcode[Ncode].astromErrScale    = atof (astromErrScale);
+    photcode[Ncode].astromErrMagScale = atof (astromErrMagScale);
+    photcode[Ncode].photomErrSys      = atof (photomErrSys);
 
     switch (photcode[Ncode].type) {
Index: /trunk/Ohana/src/libdvo/src/SavePhotcodesFITS.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/SavePhotcodesFITS.c	(revision 16809)
+++ /trunk/Ohana/src/libdvo/src/SavePhotcodesFITS.c	(revision 16810)
@@ -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_1 *photcode_output = PhotCode_Internal_To_PS1_DEV_1 (table[0].code, table[0].Ncode);
+  PhotCode_PS1_DEV_2 *photcode_output = PhotCode_Internal_To_PS1_DEV_2 (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_1 (&db.ftable, photcode_output, table[0].Ncode);
+  gfits_table_set_PhotCode_PS1_DEV_2 (&db.ftable, photcode_output, table[0].Ncode);
   gfits_db_save (&db);
   gfits_db_close (&db);
Index: /trunk/Ohana/src/libdvo/src/dvo_catalog.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/dvo_catalog.c	(revision 16809)
+++ /trunk/Ohana/src/libdvo/src/dvo_catalog.c	(revision 16810)
@@ -51,4 +51,5 @@
   if (!strcasecmp (catformat, "PANSTARRS_DEV_1")) return (DVO_FORMAT_PANSTARRS_DEV_1);
   if (!strcasecmp (catformat, "PS1_DEV_1"))       return (DVO_FORMAT_PS1_DEV_1);
+  if (!strcasecmp (catformat, "PS1_DEV_2"))       return (DVO_FORMAT_PS1_DEV_2);
   return (DVO_FORMAT_UNDEF);
 }
Index: /trunk/Ohana/src/libdvo/src/dvo_catalog_chipcoords.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/dvo_catalog_chipcoords.c	(revision 16809)
+++ /trunk/Ohana/src/libdvo/src/dvo_catalog_chipcoords.c	(revision 16810)
@@ -54,6 +54,6 @@
   
   for (i = 0; i < catalog[0].Naverage; i++) {
-    m = average[i].offset;
-    for (j = 0; j < average[i].Nm; j++, m++) {
+    m = average[i].measureOffset;
+    for (j = 0; j < average[i].Nmeasure; j++, m++) {
       ra  = average[i].R - measure[m].dR / 3600.0;
       dec = average[i].D - measure[m].dD / 3600.0;
Index: /trunk/Ohana/src/libdvo/src/dvo_catalog_raw.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/dvo_catalog_raw.c	(revision 16809)
+++ /trunk/Ohana/src/libdvo/src/dvo_catalog_raw.c	(revision 16810)
@@ -73,4 +73,5 @@
       FORMAT_CASE (PANSTARRS_DEV_1, Panstarrs_DEV_1);
       FORMAT_CASE (PS1_DEV_1, PS1_DEV_1);
+      FORMAT_CASE (PS1_DEV_2, PS1_DEV_2);
 
     default:
@@ -188,6 +189,6 @@
   if (catalog[0].catflags & LOAD_AVES) {
     for (i = Nmeas = Nmiss = 0; i < catalog[0].Naverage; i++) {
-      Nmeas += catalog[0].average[i].Nm; 
-      Nmiss += catalog[0].average[i].Nn; 
+      Nmeas += catalog[0].average[i].Nmeasure; 
+      Nmiss += catalog[0].average[i].Nmissing; 
     }
     if ((Nmeas != catalog[0].Nmeasure) || (Nmiss != catalog[0].Nmissing)) {
@@ -256,4 +257,5 @@
   if (catalog[0].catformat == DVO_FORMAT_PANSTARRS_DEV_1) gfits_modify (&catalog[0].header, "FORMAT", "%s", 1, "PANSTARRS_DEV_1");
   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");
 
   /* rewind file pointers and truncate file */
@@ -350,4 +352,5 @@
       FORMAT_CASE (PANSTARRS_DEV_1, Panstarrs_DEV_1);
       FORMAT_CASE (PS1_DEV_1, PS1_DEV_1);
+      FORMAT_CASE (PS1_DEV_2, PS1_DEV_2);
 
     default:
@@ -395,4 +398,5 @@
       FORMAT_CASE (PANSTARRS_DEV_1, Panstarrs_DEV_1);
       FORMAT_CASE (PS1_DEV_1, PS1_DEV_1);
+      FORMAT_CASE (PS1_DEV_2, PS1_DEV_2);
 
     default:
@@ -444,4 +448,5 @@
       FORMAT_CASE (PANSTARRS_DEV_1, Panstarrs_DEV_1);
       FORMAT_CASE (PS1_DEV_1, PS1_DEV_1);
+      FORMAT_CASE (PS1_DEV_2, PS1_DEV_2);
 
     default:
@@ -489,4 +494,5 @@
       FORMAT_CASE (PANSTARRS_DEV_1, Panstarrs_DEV_1);
       FORMAT_CASE (PS1_DEV_1, PS1_DEV_1);
+      FORMAT_CASE (PS1_DEV_2, PS1_DEV_2);
 
     default:
@@ -538,4 +544,5 @@
       FORMAT_CASE (PANSTARRS_DEV_1, Panstarrs_DEV_1);
       FORMAT_CASE (PS1_DEV_1, PS1_DEV_1);
+      FORMAT_CASE (PS1_DEV_2, PS1_DEV_2);
 
     default:
@@ -583,4 +590,5 @@
       FORMAT_CASE (PANSTARRS_DEV_1, Panstarrs_DEV_1);
       FORMAT_CASE (PS1_DEV_1, PS1_DEV_1);
+      FORMAT_CASE (PS1_DEV_2, PS1_DEV_2);
 
     default:
Index: /trunk/Ohana/src/libdvo/src/dvo_convert.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/dvo_convert.c	(revision 16809)
+++ /trunk/Ohana/src/libdvo/src/dvo_convert.c	(revision 16810)
@@ -48,4 +48,5 @@
   CONVERT_FORMAT ("DVO_AVERAGE_PANSTARRS_DEV_1", PANSTARRS_DEV_1, Panstarrs_DEV_1);
   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);
 # undef CONVERT_FORMAT
 
@@ -77,4 +78,5 @@
       FORMAT_CASE (PANSTARRS_DEV_1, Panstarrs_DEV_1);
       FORMAT_CASE (PS1_DEV_1,       PS1_DEV_1);
+      FORMAT_CASE (PS1_DEV_2,       PS1_DEV_2);
 # undef FORMAT_CASE
 
@@ -119,4 +121,5 @@
   CONVERT_FORMAT ("DVO_MEASURE_PANSTARRS_DEV_1", PANSTARRS_DEV_1, Panstarrs_DEV_1);
   CONVERT_FORMAT ("DVO_MEASURE_PS1_DEV_1",       PS1_DEV_1,       PS1_DEV_1);
+  CONVERT_FORMAT ("DVO_MEASURE_PS1_DEV_2",       PS1_DEV_2,       PS1_DEV_2);
 # undef CONVERT_FORMAT
 
@@ -148,4 +151,5 @@
       FORMAT_CASE (PANSTARRS_DEV_1, Panstarrs_DEV_1);
       FORMAT_CASE (PS1_DEV_1,       PS1_DEV_1);
+      FORMAT_CASE (PS1_DEV_2,       PS1_DEV_2);
 # undef FORMAT_CASE
 
@@ -190,4 +194,5 @@
   CONVERT_FORMAT ("DVO_SECFILT_PANSTARRS_DEV_1", PANSTARRS_DEV_1, Panstarrs_DEV_1);
   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);
 # undef CONVERT_FORMAT
 
@@ -219,4 +224,5 @@
       FORMAT_CASE (PANSTARRS_DEV_1, Panstarrs_DEV_1);
       FORMAT_CASE (PS1_DEV_1,       PS1_DEV_1);
+      FORMAT_CASE (PS1_DEV_2,       PS1_DEV_2);
 # undef FORMAT_CASE
 
@@ -281,4 +287,5 @@
   CONVERT_FORMAT ("DVO_IMAGE_PANSTARRS_DEV_1", PANSTARRS_DEV_1, Panstarrs_DEV_1);
   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);
 # undef CONVERT_FORMAT
 
@@ -313,4 +320,5 @@
       FORMAT_CASE (PANSTARRS_DEV_1, Panstarrs_DEV_1);
       FORMAT_CASE (PS1_DEV_1,       PS1_DEV_1);
+      FORMAT_CASE (PS1_DEV_2,       PS1_DEV_2);
 # undef FORMAT_CASE
 
@@ -361,4 +369,5 @@
       FORMAT_CASE (PANSTARRS_DEV_1, Panstarrs_DEV_1);
       FORMAT_CASE (PS1_DEV_1,       PS1_DEV_1);
+      FORMAT_CASE (PS1_DEV_2,       PS1_DEV_2);
 # undef FORMAT_CASE
 
Index: /trunk/Ohana/src/libdvo/src/dvo_convert_PS1_DEV_1.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/dvo_convert_PS1_DEV_1.c	(revision 16809)
+++ /trunk/Ohana/src/libdvo/src/dvo_convert_PS1_DEV_1.c	(revision 16810)
@@ -1,7 +1,6 @@
 # include <dvo.h>
 
-// XXX these functions ahve to be adjusted to agree with the new definition of PS1_DEV_1
-
-/* convert panstarrs-format measures to internal measures */
+/* convert PS1_DEV_1 formats to internal formats */
+
 Measure *Measure_PS1_DEV_1_ToInternal (Measure_PS1_DEV_1 *in, int Nvalues) {
 
@@ -16,5 +15,5 @@
     out[i].M          = in[i].M;
     out[i].Mcal       = in[i].Mcal;
-    out[i].Mgal       = in[i].Mgal;
+    out[i].Map        = in[i].Mgal;
     out[i].dM         = in[i].dM;
     out[i].dt         = in[i].dt;
@@ -30,5 +29,5 @@
     out[i].imageID    = in[i].imageID;
     out[i].qPSF       = in[i].qPSF;
-    out[i].psfProb    = in[i].psfProb;
+    out[i].psfChisq   = in[i].psfChisq;
     out[i].crNsigma   = in[i].crNsigma;
     out[i].extNsigma  = in[i].extNsigma;
@@ -47,5 +46,4 @@
 }
 
-/* convert internal measures to panstarrs-format measures */
 Measure_PS1_DEV_1 *MeasureInternalTo_PS1_DEV_1 (Measure *in, int Nvalues) {
 
@@ -60,5 +58,5 @@
     out[i].M          = in[i].M;
     out[i].Mcal       = in[i].Mcal;
-    out[i].Mgal       = in[i].Mgal;
+    out[i].Mgal       = in[i].Map;
     out[i].dM         = in[i].dM;
     out[i].dt         = in[i].dt;
@@ -74,5 +72,5 @@
     out[i].imageID    = in[i].imageID;
     out[i].qPSF       = in[i].qPSF;
-    out[i].psfProb    = in[i].psfProb;
+    out[i].psfChisq   = in[i].psfChisq;
     out[i].crNsigma   = in[i].crNsigma;
     out[i].extNsigma  = in[i].extNsigma;
@@ -91,6 +89,5 @@
 }
 
-/* convert panstarrs-format averages to internal averages */
-// 'primary is needed to conform with the API for Loneos and Elixir, but is not used
+// 'primary' is needed to conform with the API for Loneos and Elixir, but is not used
 Average *Average_PS1_DEV_1_ToInternal (Average_PS1_DEV_1 *in, int Nvalues, SecFilt **primary) {
 
@@ -99,4 +96,35 @@
 
   ALLOCATE (out, Average, Nvalues);
+
+  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].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;
+    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;
+  }
+  return (out);
+}
+
+// 'primary' is needed to conform with the API for Loneos and Elixir, but is not used
+Average_PS1_DEV_1 *AverageInternalTo_PS1_DEV_1 (Average *in, int Nvalues, SecFilt *primary) {
+
+  int i;
+  Average_PS1_DEV_1 *out;
+
+  ALLOCATE (out, Average_PS1_DEV_1, Nvalues);
 
   for (i = 0; i < Nvalues; i++) {
@@ -104,9 +132,9 @@
     out[i].D        = in[i].D;      
     out[i].Xp       = in[i].Xp;     
-    out[i].Nm       = in[i].Nm;     
-    out[i].Nn       = in[i].Nn;     
+    out[i].Nm       = in[i].Nmeasure;     
+    out[i].Nn       = in[i].Nmissing;     
     out[i].code     = in[i].code;   
-    out[i].offset   = in[i].offset; 
-    out[i].missing  = in[i].missing;
+    out[i].offset   = in[i].measureOffset; 
+    out[i].missing  = in[i].missingOffset;
     out[i].dR       = in[i].dR;
     out[i].dD       = in[i].dD;
@@ -117,43 +145,10 @@
     out[i].P        = in[i].P;
     out[i].dP       = in[i].dP;
-    out[i].objID_hi = in[i].objID_hi;
-    out[i].objID_lo = in[i].objID_lo;
-  }
-  return (out);
-}
-
-/* convert internal averages to panstarrs-format averages */
-// 'primary is needed to conform with the API for Loneos and Elixir, but is not used
-Average_PS1_DEV_1 *AverageInternalTo_PS1_DEV_1 (Average *in, int Nvalues, SecFilt *primary) {
-
-  int i;
-  Average_PS1_DEV_1 *out;
-
-  ALLOCATE (out, Average_PS1_DEV_1, Nvalues);
-
-  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].Nm;     
-    out[i].Nn       = in[i].Nn;     
-    out[i].code     = in[i].code;   
-    out[i].offset   = in[i].offset; 
-    out[i].missing  = in[i].missing;
-    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_hi = in[i].objID_hi;
-    out[i].objID_lo = in[i].objID_lo;
-  }
-  return (out);
-}
-
-/* convert panstarrs-format secfilts to internal secfilts */
+    out[i].objID    = in[i].objID;
+    out[i].catID    = in[i].catID;
+  }
+  return (out);
+}
+
 SecFilt *SecFilt_PS1_DEV_1_ToInternal (SecFilt_PS1_DEV_1 *in, int Nvalues) {
 
@@ -173,5 +168,4 @@
 }
 
-/* convert internal secfilts to panstarrs-format secfilts */
 SecFilt_PS1_DEV_1 *SecFiltInternalTo_PS1_DEV_1 (SecFilt *in, int Nvalues) {
 
@@ -191,5 +185,4 @@
 }
 
-/* convert panstarrs-format images to internal images */
 Image *Image_PS1_DEV_1_ToInternal (Image_PS1_DEV_1 *in, int Nvalues) {
 
@@ -300,2 +293,66 @@
   return (out);
 }
+
+PhotCode_PS1_DEV_1 *PhotCode_Internal_To_PS1_DEV_1 (PhotCode *in, int Nvalues) {
+
+  int i;
+  PhotCode_PS1_DEV_1 *out;
+
+  ALLOCATE (out, PhotCode_PS1_DEV_1, 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 = 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));            
+
+  }
+  return (out);
+}
Index: /trunk/Ohana/src/libdvo/src/dvo_convert_PS1_DEV_2.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/dvo_convert_PS1_DEV_2.c	(revision 16810)
+++ /trunk/Ohana/src/libdvo/src/dvo_convert_PS1_DEV_2.c	(revision 16810)
@@ -0,0 +1,365 @@
+# include <dvo.h>
+
+/* convert PS1_DEV_2 formats to internal formats */
+
+Measure *Measure_PS1_DEV_2_ToInternal (Measure_PS1_DEV_2 *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].averef     = in[i].averef;
+    out[i].detID      = in[i].detID;
+    out[i].imageID    = in[i].imageID;
+    out[i].qPSF       = in[i].qPSF;
+    out[i].psfChisq   = in[i].psfChisq;
+    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].photcode   = in[i].photcode;
+    out[i].dXccd      = in[i].dXccd;
+    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;
+  }
+  return (out);
+}
+
+Measure_PS1_DEV_2 *MeasureInternalTo_PS1_DEV_2 (Measure *in, int Nvalues) {
+
+  int i;
+  Measure_PS1_DEV_2 *out;
+
+  ALLOCATE (out, Measure_PS1_DEV_2, 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].averef     = in[i].averef;
+    out[i].detID      = in[i].detID;
+    out[i].imageID    = in[i].imageID;
+    out[i].qPSF       = in[i].qPSF;
+    out[i].psfChisq   = in[i].psfChisq;
+    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].photcode   = in[i].photcode;
+    out[i].dXccd      = in[i].dXccd;
+    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;
+  }
+  return (out);
+}
+
+// 'primary' is needed to conform with the API for Loneos and Elixir, but is not used
+Average *Average_PS1_DEV_2_ToInternal (Average_PS1_DEV_2 *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].Nmeasure      = in[i].Nmeasure;     
+    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;
+    out[i].extendOffset  = in[i].extendOffset;
+    out[i].objID 	 = in[i].objID;
+    out[i].catID 	 = in[i].catID;
+  }
+  return (out);
+}
+
+// 'primary' is needed to conform with the API for Loneos and Elixir, but is not used
+Average_PS1_DEV_2 *AverageInternalTo_PS1_DEV_2 (Average *in, int Nvalues, SecFilt *primary) {
+
+  int i;
+  Average_PS1_DEV_2 *out;
+
+  ALLOCATE (out, Average_PS1_DEV_2, 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].Nmeasure      = in[i].Nmeasure;     
+    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;
+    out[i].extendOffset  = in[i].extendOffset;
+    out[i].objID 	 = in[i].objID;
+    out[i].catID 	 = in[i].catID;
+  }
+  return (out);
+}
+
+SecFilt *SecFilt_PS1_DEV_2_ToInternal (SecFilt_PS1_DEV_2 *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;
+ }
+  return (out);
+}
+
+SecFilt_PS1_DEV_2 *SecFiltInternalTo_PS1_DEV_2 (SecFilt *in, int Nvalues) {
+
+  int i;
+  SecFilt_PS1_DEV_2 *out;
+
+  ALLOCATE (out, SecFilt_PS1_DEV_2, 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;
+  }
+  return (out);
+}
+
+Image *Image_PS1_DEV_2_ToInternal (Image_PS1_DEV_2 *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));
+    strcpy (out[i].name, in[i].name);
+
+    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].code		    = in[i].code;
+    out[i].ccdnum	    = in[i].ccdnum;
+    out[i].imageID	    = in[i].imageID;
+    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_DEV_2 *ImageInternalTo_PS1_DEV_2 (Image *in, int Nvalues) {
+
+  int i;
+  Image_PS1_DEV_2 *out;
+
+  ALLOCATE (out, Image_PS1_DEV_2, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
+    strcpy (out[i].name, in[i].name);
+
+    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].code		    = in[i].code;
+    out[i].ccdnum	    = in[i].ccdnum;
+    out[i].imageID	    = in[i].imageID;
+    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_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++) {
+    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;
+  }
+  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++) {
+    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;
+  }
+  return (out);
+}
Index: /trunk/Ohana/src/libdvo/src/dvo_convert_elixir.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/dvo_convert_elixir.c	(revision 16809)
+++ /trunk/Ohana/src/libdvo/src/dvo_convert_elixir.c	(revision 16810)
@@ -16,5 +16,8 @@
     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;
-    out[i].Mgal     = (in[i].Mgal    == NAN_S_SHORT) ? NAN : in[i].Mgal   * 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;
@@ -39,5 +42,5 @@
     out[i].dSky      = 0;
     out[i].qPSF      = 0;
-    out[i].psfProb   = 0;
+    out[i].psfChisq  = 0;
     out[i].crNsigma  = 0;
     out[i].extNsigma = 0;
@@ -66,5 +69,5 @@
     out[i].dt       = isnan(in[i].dt     ) ? NAN_S_SHORT : in[i].dt      * 1000.0;
     out[i].Mcal     = isnan(in[i].Mcal   ) ? NAN_S_SHORT : in[i].Mcal    * 1000.0;
-    out[i].Mgal     = isnan(in[i].Mgal   ) ? NAN_S_SHORT : in[i].Mgal    * 1000.0;
+    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;
 
@@ -95,12 +98,12 @@
 
   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].Nm;     
-    out[i].Nn      = in[i].Nn;     
-    out[i].code    = in[i].code;   
-    out[i].offset  = in[i].offset; 
-    out[i].missing = in[i].missing;
+    out[i].R       	 = in[i].R;      
+    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 */
@@ -115,6 +118,6 @@
 
     /* XXX add these later */
-    out[i].objID_hi = 0;
-    out[i].objID_lo = 0;
+    out[i].objID   = 0;
+    out[i].catID   = 0;
 
     primary[0][i].M     = (in[i].M  == NAN_S_SHORT) ? NAN : in[i].M  * 0.001;      
@@ -139,9 +142,9 @@
     out[i].D       = in[i].D;      
     out[i].Xp      = in[i].Xp;     
-    out[i].Nm      = in[i].Nm;     
-    out[i].Nn      = in[i].Nn;     
+    out[i].Nm      = in[i].Nmeasure;     
+    out[i].Nn      = in[i].Nmissing;     
     out[i].code    = in[i].code;   
-    out[i].offset  = in[i].offset; 
-    out[i].missing = in[i].missing;
+    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;
@@ -297,2 +300,60 @@
   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++) {
+    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));            
+  }
+  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++) {
+    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));            
+
+    // not defined in Elixir:
+    out[i].astromErrSys      = 0.0;
+    out[i].astromErrScale    = 0.0;
+    out[i].astromErrMagScale = 0.0;
+    out[i].photomErrSys      = 0.0;
+  }
+  return (out);
+}
Index: /trunk/Ohana/src/libdvo/src/dvo_convert_loneos.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/dvo_convert_loneos.c	(revision 16809)
+++ /trunk/Ohana/src/libdvo/src/dvo_convert_loneos.c	(revision 16810)
@@ -24,16 +24,19 @@
 
     /* these values don't exist in the Loneos format */
-    out[i].Mgal     = out[i].M;
-    out[i].dt       = 0;
-    out[i].airmass  = 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].psfProb   = 0;
+
+    // 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].dt        = 0;
+    out[i].airmass   = 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].psfChisq  = 0;
     out[i].crNsigma  = 0;
     out[i].extNsigma = 0;
@@ -87,12 +90,12 @@
 
   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].Nm;     
-    out[i].Nn      = in[i].Nn;     
-    out[i].code    = in[i].code;   
-    out[i].offset  = in[i].offset; 
-    out[i].missing = in[i].missing;
+    out[i].R       	 = in[i].R;      
+    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 */
@@ -107,6 +110,6 @@
 
     /* XXX add these later */
-    out[i].objID_hi = 0;
-    out[i].objID_lo = 0;
+    out[i].objID   = 0;
+    out[i].catID   = 0;
 
     primary[0][i].M  = (in[i].M  == NAN_S_SHORT) ? NAN : in[i].M  * 0.001;      
@@ -131,9 +134,9 @@
     out[i].D       = in[i].D;      
     out[i].Xp      = in[i].Xp;     
-    out[i].Nm      = in[i].Nm;     
-    out[i].Nn      = in[i].Nn;     
+    out[i].Nm      = in[i].Nmeasure;     
+    out[i].Nn      = in[i].Nmissing;     
     out[i].code    = in[i].code;   
-    out[i].offset  = in[i].offset; 
-    out[i].missing = in[i].missing;
+    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;
Index: /trunk/Ohana/src/libdvo/src/dvo_convert_panstarrs_DEV_0.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/dvo_convert_panstarrs_DEV_0.c	(revision 16809)
+++ /trunk/Ohana/src/libdvo/src/dvo_convert_panstarrs_DEV_0.c	(revision 16810)
@@ -15,5 +15,8 @@
     out[i].dM         = in[i].dM;
     out[i].Mcal       = in[i].Mcal;
-    out[i].Mgal       = in[i].Mgal;
+
+    // 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;
@@ -39,5 +42,5 @@
 
     // these don't have a correspondence
-    out[i].psfProb   = 0;
+    out[i].psfChisq  = 0;
     out[i].crNsigma  = 0;
     out[i].extNsigma = 0;
@@ -61,5 +64,5 @@
     out[i].dM         = in[i].dM;
     out[i].Mcal       = in[i].Mcal;
-    out[i].Mgal       = in[i].Mgal;
+    out[i].Mgal       = in[i].Map;
     out[i].airmass    = in[i].airmass;
     out[i].az         = in[i].az;
@@ -99,12 +102,44 @@
 
   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].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;
+    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;
+  }
+  return (out);
+}
+
+/* convert internal averages to panstarrs-format averages */
+// 'primary is needed to conform with the API for Loneos and Elixir, but is not used
+Average_Panstarrs_DEV_0 *AverageInternalTo_Panstarrs_DEV_0 (Average *in, int Nvalues, SecFilt *primary) {
+
+  int i;
+  Average_Panstarrs_DEV_0 *out;
+
+  ALLOCATE (out, Average_Panstarrs_DEV_0, Nvalues);
+
+  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].Nm;     
-    out[i].Nn       = in[i].Nn;     
+    out[i].Nm       = in[i].Nmeasure;     
+    out[i].Nn       = in[i].Nmissing;     
     out[i].code     = in[i].code;   
-    out[i].offset   = in[i].offset; 
-    out[i].missing  = in[i].missing;
+    out[i].offset   = in[i].measureOffset; 
+    out[i].missing  = in[i].missingOffset;
     out[i].dR       = in[i].dR;
     out[i].dD       = in[i].dD;
@@ -115,38 +150,6 @@
     out[i].P        = in[i].P;
     out[i].dP       = in[i].dP;
-    out[i].objID_hi = in[i].objID_hi;
-    out[i].objID_lo = in[i].objID_lo;
-  }
-  return (out);
-}
-
-/* convert internal averages to panstarrs-format averages */
-// 'primary is needed to conform with the API for Loneos and Elixir, but is not used
-Average_Panstarrs_DEV_0 *AverageInternalTo_Panstarrs_DEV_0 (Average *in, int Nvalues, SecFilt *primary) {
-
-  int i;
-  Average_Panstarrs_DEV_0 *out;
-
-  ALLOCATE (out, Average_Panstarrs_DEV_0, Nvalues);
-
-  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].Nm;     
-    out[i].Nn       = in[i].Nn;     
-    out[i].code     = in[i].code;   
-    out[i].offset   = in[i].offset; 
-    out[i].missing  = in[i].missing;
-    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_hi = in[i].objID_hi;
-    out[i].objID_lo = in[i].objID_lo;
+    out[i].objID    = in[i].objID;
+    out[i].catID    = in[i].catID;
   }
   return (out);
Index: /trunk/Ohana/src/libdvo/src/dvo_convert_panstarrs_DEV_1.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/dvo_convert_panstarrs_DEV_1.c	(revision 16809)
+++ /trunk/Ohana/src/libdvo/src/dvo_convert_panstarrs_DEV_1.c	(revision 16810)
@@ -15,5 +15,8 @@
     out[i].dM         = in[i].dM;
     out[i].Mcal       = in[i].Mcal;
-    out[i].Mgal       = in[i].Mgal;
+
+    // 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;
@@ -39,5 +42,5 @@
 
     // these don't have a correspondence
-    out[i].psfProb   = 0;
+    out[i].psfChisq  = 0;
     out[i].crNsigma  = 0;
     out[i].extNsigma = 0;
@@ -61,5 +64,5 @@
     out[i].dM         = in[i].dM;
     out[i].Mcal       = in[i].Mcal;
-    out[i].Mgal       = in[i].Mgal;
+    out[i].Mgal       = in[i].Map;
     out[i].airmass    = in[i].airmass;
     out[i].az         = in[i].az;
@@ -99,12 +102,44 @@
 
   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].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;
+    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;
+  }
+  return (out);
+}
+
+/* convert internal averages to panstarrs-format averages */
+// 'primary is needed to conform with the API for Loneos and Elixir, but is not used
+Average_Panstarrs_DEV_1 *AverageInternalTo_Panstarrs_DEV_1 (Average *in, int Nvalues, SecFilt *primary) {
+
+  int i;
+  Average_Panstarrs_DEV_1 *out;
+
+  ALLOCATE (out, Average_Panstarrs_DEV_1, Nvalues);
+
+  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].Nm;     
-    out[i].Nn       = in[i].Nn;     
+    out[i].Nm       = in[i].Nmeasure;     
+    out[i].Nn       = in[i].Nmissing;     
     out[i].code     = in[i].code;   
-    out[i].offset   = in[i].offset; 
-    out[i].missing  = in[i].missing;
+    out[i].offset   = in[i].measureOffset; 
+    out[i].missing  = in[i].missingOffset;
     out[i].dR       = in[i].dR;
     out[i].dD       = in[i].dD;
@@ -115,38 +150,6 @@
     out[i].P        = in[i].P;
     out[i].dP       = in[i].dP;
-    out[i].objID_hi = in[i].objID_hi;
-    out[i].objID_lo = in[i].objID_lo;
-  }
-  return (out);
-}
-
-/* convert internal averages to panstarrs-format averages */
-// 'primary is needed to conform with the API for Loneos and Elixir, but is not used
-Average_Panstarrs_DEV_1 *AverageInternalTo_Panstarrs_DEV_1 (Average *in, int Nvalues, SecFilt *primary) {
-
-  int i;
-  Average_Panstarrs_DEV_1 *out;
-
-  ALLOCATE (out, Average_Panstarrs_DEV_1, Nvalues);
-
-  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].Nm;     
-    out[i].Nn       = in[i].Nn;     
-    out[i].code     = in[i].code;   
-    out[i].offset   = in[i].offset; 
-    out[i].missing  = in[i].missing;
-    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_hi = in[i].objID_hi;
-    out[i].objID_lo = in[i].objID_lo;
+    out[i].objID    = in[i].objID;
+    out[i].catID    = in[i].catID;
   }
   return (out);
Index: /trunk/Ohana/src/libdvo/src/dvo_image.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/dvo_image.c	(revision 16809)
+++ /trunk/Ohana/src/libdvo/src/dvo_image.c	(revision 16810)
@@ -194,4 +194,5 @@
   if (db[0].format == DVO_FORMAT_PANSTARRS_DEV_1) gfits_modify (&db[0].header, "FORMAT", "%s", 1, "PANSTARRS_DEV_1");
   if (db[0].format == DVO_FORMAT_PS1_DEV_1)       gfits_modify (&db[0].header, "FORMAT", "%s", 1, "PS1_DEV_1");
+  if (db[0].format == DVO_FORMAT_PS1_DEV_2)       gfits_modify (&db[0].header, "FORMAT", "%s", 1, "PS1_DEV_2");
   
   return;
Index: /trunk/Ohana/src/libdvo/src/dvo_image_raw.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/dvo_image_raw.c	(revision 16809)
+++ /trunk/Ohana/src/libdvo/src/dvo_image_raw.c	(revision 16810)
@@ -53,4 +53,5 @@
   if (db[0].format == DVO_FORMAT_PANSTARRS_DEV_1) ImageSize = sizeof(Image_Panstarrs_DEV_1);
   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);
 
   /* check that filesize makes sense */
@@ -76,4 +77,5 @@
   if (db[0].format == DVO_FORMAT_PANSTARRS_DEV_1) gfits_table_mkheader_Image_Panstarrs_DEV_1 (&db[0].theader);
   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);
     
   /* read data from file */
Index: unk/Ohana/src/libdvo/src/dvo_photcode_convert_elixir.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/dvo_photcode_convert_elixir.c	(revision 16809)
+++ 	(revision )
@@ -1,57 +1,0 @@
-# include <dvo.h>
-
-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++) {
-    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));            
-  }
-  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++) {
-    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));            
-
-    // not defined in Elixir:
-    out[i].astromScale = 1.0;
-    out[i].photSysErr = 1.0;
-  }
-  return (out);
-}
Index: unk/Ohana/src/libdvo/src/dvo_photcode_convert_ps1_dev_1.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/dvo_photcode_convert_ps1_dev_1.c	(revision 16809)
+++ 	(revision )
@@ -1,59 +1,0 @@
-# include <dvo.h>
-
-PhotCode_PS1_DEV_1 *PhotCode_Internal_To_PS1_DEV_1 (PhotCode *in, int Nvalues) {
-
-  int i;
-  PhotCode_PS1_DEV_1 *out;
-
-  ALLOCATE (out, PhotCode_PS1_DEV_1, 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].astromScale = in[i].astromScale;  
-    out[i].photSysErr = in[i].photSysErr;   
-  }
-  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].astromScale = in[i].astromScale;  
-    out[i].photSysErr = in[i].photSysErr;   
-  }
-  return (out);
-}
Index: /trunk/Ohana/src/libdvo/src/dvo_photcode_ops.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/dvo_photcode_ops.c	(revision 16809)
+++ /trunk/Ohana/src/libdvo/src/dvo_photcode_ops.c	(revision 16810)
@@ -370,5 +370,5 @@
   if (color == NULL) return (NAN);
   if (color[0].type == PHOT_REF) {
-    for (i = 0; (i < average[0].Nm) && (isnan(m1)); i++) {
+    for (i = 0; (i < average[0].Nmeasure) && (isnan(m1)); i++) {
       if (measure[i].photcode == color[0].code) {
 	m1 = measure[i].M;
@@ -384,5 +384,5 @@
   if (color == NULL) return (NAN);
   if (color[0].type == PHOT_REF) {
-    for (i = 0; (i < average[0].Nm) && (isnan(m2)); i++) {
+    for (i = 0; (i < average[0].Nmeasure) && (isnan(m2)); i++) {
       if (measure[i].photcode == color[0].code) {
 	m2 = measure[i].M;
@@ -466,5 +466,5 @@
   if (code == NULL) return (FALSE);
   if (code[0].type == PHOT_REF) {
-    for (i = 0; i < average[0].Nm; i++) {
+    for (i = 0; i < average[0].Nmeasure; i++) {
       if (measure[i].photcode == c1) {
 	M1 = measure[i].M;
@@ -482,5 +482,5 @@
   if (code == NULL) return (FALSE);
   if (code[0].type == PHOT_REF) {
-    for (i = 0; i < average[0].Nm; i++) {
+    for (i = 0; i < average[0].Nmeasure; i++) {
       if (measure[i].photcode == c2) {
 	M2 = measure[i].M;
Index: /trunk/Ohana/src/libfits/include/gfitsio.h
===================================================================
--- /trunk/Ohana/src/libfits/include/gfitsio.h	(revision 16809)
+++ /trunk/Ohana/src/libfits/include/gfitsio.h	(revision 16810)
@@ -184,4 +184,5 @@
 int     gfits_get_bintable_column      PROTO((Header *header, FTable *table, char *label, void **data));
 int     gfits_get_bintable_column_type PROTO((Header *header, char *label, char *type, int *Nval));
+void   *gfits_get_bintable_column_data PROTO((Header *header, FTable *table, char *label, char *type, int *Nrow, int *Ncol));
 int     gfits_get_table_column         PROTO((Header *header, FTable *table, char *label, void **data));
 int     gfits_get_table_column_type    PROTO((Header *header, char *label, char *type));
Index: /trunk/Ohana/src/libfits/table/F_get_column.c
===================================================================
--- /trunk/Ohana/src/libfits/table/F_get_column.c	(revision 16809)
+++ /trunk/Ohana/src/libfits/table/F_get_column.c	(revision 16810)
@@ -14,4 +14,104 @@
   tmp = Pin[2]; Pin[2] = Pin[5]; Pin[5] = tmp; \
   tmp = Pin[3]; Pin[3] = Pin[4]; Pin[4] = tmp; }
+
+void *gfits_get_bintable_column_data (Header *header, FTable *table, char *label, char *type, int *Nrow, int *Ncol) {
+
+  int i, N, Nfields, Nval, Nbytes, Nx, Ny, Nstart, Nv, Nb;
+  char tlabel[80], field[80], format[80], tmpline[16];
+  char *Pin, *Pout, *array;
+  double Bscale, Bzero;
+
+  if (label == (char *) NULL) return (NULL);
+  if (label[0] == 0) return (NULL);
+
+  /* find label in header */
+  tlabel[0] = 0;
+  if (!gfits_scan (header, "TFIELDS", "%d", 1, &Nfields)) return (NULL);
+  for (i = 1; strcmp (label, tlabel) && (i < Nfields + 1); i++) {
+    sprintf (field, "TTYPE%d", i);
+    gfits_scan (header, field, "%s", 1, tlabel);
+  }
+  if (strcmp (label, tlabel)) return (NULL);
+  N = i - 1;
+
+  Bscale = 1; 
+  Bzero  = 0;
+
+  /* interpret format */
+  sprintf (field, "TSCAL%d", N);
+  gfits_scan (header, field, "%lf", 1, &Bscale);
+  sprintf (field, "TZERO%d", N);
+  gfits_scan (header, field, "%lf", 1, &Bzero);
+  sprintf (field, "TFORM%d", N);
+  gfits_scan (header, field, "%s", 1, format);
+
+  if (!gfits_bintable_format (format, type, &Nval, &Nbytes)) return (NULL);
+  
+  /* check existing table dimensions */
+  gfits_scan (header, "NAXIS1",  "%d", 1, &Nx);
+  gfits_scan (header, "NAXIS2",  "%d", 1, &Ny);
+
+  /* scan columns to find insert point */
+  Nstart = 0;
+  for (i = 1; i < N; i++) {
+    sprintf (field, "TFORM%d", i);
+    gfits_scan (header, field, "%s", 1, format);
+    gfits_bintable_format (format, tmpline, &Nv, &Nb);
+    Nstart += Nv*Nb;
+  }
+
+  /* extract bytes from table into array */
+  ALLOCATE (array, char, Nbytes*Nval*Ny);
+  Pin  = table[0].buffer + Nstart;
+  Pout = array;
+  for (i = 0; i < Ny; i++, Pin += Nx, Pout += Nval*Nbytes) {
+    memcpy (Pout, Pin, Nval*Nbytes);
+  }
+
+  /* convert data in-situ with correct type, byte swap and Bzero/Bscale */
+  Pin  = array;
+  Pout = array;
+  if (!strcmp (type, "char")) {
+    for (i = 0; i < Nval*Ny; i++, Pin+=Nbytes, Pout+=Nbytes) {
+      *(char *)Pout = *(char *)Pin*Bscale + Bzero;
+    }
+  }
+  if (!strcmp (type, "short")) {
+    for (i = 0; i < Nval*Ny; i++, Pin+=Nbytes, Pout+=Nbytes) {
+# ifdef BYTE_SWAP
+      SWAP_BYTE;
+# endif
+      *(short *)Pout = *(short *)Pin*Bscale + Bzero;
+    }  
+  }
+  if (!strcmp (type, "int")) {
+    for (i = 0; i < Nval*Ny; i++, Pin+=Nbytes, Pout+=Nbytes) {
+# ifdef BYTE_SWAP
+      SWAP_WORD;
+# endif
+      *(int *)Pout = *(int *)Pin*Bscale + Bzero;
+    }
+  }
+  if (!strcmp (type, "float")) {
+    for (i = 0; i < Nval*Ny; i++, Pin+=Nbytes, Pout+=Nbytes) {
+# ifdef BYTE_SWAP
+      SWAP_WORD;
+# endif
+      *(float *)Pout = *(float *)Pin*Bscale + Bzero;
+    }
+  }
+  if (!strcmp (type, "double")) {
+    for (i = 0; i < Nval*Ny; i++, Pin+=Nbytes, Pout+=Nbytes) {
+# ifdef BYTE_SWAP
+      SWAP_DBLE;
+# endif
+      *(double *)Pout = *(double *)Pin*Bscale + Bzero;
+    }
+  }
+
+  *Ncol = Nval;
+  *Nrow = Ny;
+  return (array);
+}
 
 /***********************/
Index: /trunk/Ohana/src/libkapa/src/KapaOpen.c
===================================================================
--- /trunk/Ohana/src/libkapa/src/KapaOpen.c	(revision 16809)
+++ /trunk/Ohana/src/libkapa/src/KapaOpen.c	(revision 16810)
@@ -2,4 +2,5 @@
 
 # define MY_PORT 2500
+# define MY_PORT_MAX 2520
 # define MY_WAIT 100000
 # define DEBUG 0
@@ -26,5 +27,5 @@
   }
 
-  if (DEBUG) fprintf (stderr, "init sock: %d, len: %d\n", InitSocket, length);
+  if (DEBUG) fprintf (stderr, "init sock: %d, len: %d, port %d\n", InitSocket, length, Address[0].sin_port);
   status = bind (InitSocket, (struct sockaddr *) Address, length);
   if (status == -1) {
@@ -32,5 +33,5 @@
 	close (InitSocket);
 	Address[0].sin_port ++;
-	if (Address[0].sin_port > MY_PORT + 10) exit (2);
+	if (Address[0].sin_port > MY_PORT_MAX) exit (2);
 	goto retry_server;
     }
@@ -193,5 +194,5 @@
       close (InitSocket);
       Address.sin_port ++;
-      if (Address.sin_port > MY_PORT + 10) return (-1);
+      if (Address.sin_port > MY_PORT_MAX) return (-1);
       goto retry_client;
     }
Index: /trunk/Ohana/src/markstar/src/match_images.c
===================================================================
--- /trunk/Ohana/src/markstar/src/match_images.c	(revision 16809)
+++ /trunk/Ohana/src/markstar/src/match_images.c	(revision 16810)
@@ -22,6 +22,6 @@
   ALLOCATE (source, short int, Nimage);
   for (j = 0; j < Nimage; j++) {
-    start[j] = image[j].tzero - MAX(0.05*image[j].trate*image[j].NY, 1);
-    stop[j]  = image[j].tzero + MAX(1.05*image[j].trate*image[j].NY, 1);
+    start[j] = image[j].tzero - MAX(0.01*image[j].trate*image[j].NY, 1);
+    stop[j]  = image[j].tzero + MAX(1.01*image[j].trate*image[j].NY, 1);
     source[j] = image[j].photcode;
   }
Index: /trunk/Ohana/src/mosastro/src/getptolemy.c
===================================================================
--- /trunk/Ohana/src/mosastro/src/getptolemy.c	(revision 16809)
+++ /trunk/Ohana/src/mosastro/src/getptolemy.c	(revision 16810)
@@ -50,5 +50,5 @@
       stars[k].R = catalog.average[j].R;
       stars[k].D = catalog.average[j].D;
-      stars[k].M = catalog.measure[catalog.average[j].offset].M;
+      stars[k].M = catalog.measure[catalog.average[j].measureOffset].M;
     }      
     dvo_catalog_free (&catalog);
Index: /trunk/Ohana/src/opihi/dvo/avextract.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/avextract.c	(revision 16809)
+++ /trunk/Ohana/src/opihi/dvo/avextract.c	(revision 16810)
@@ -100,5 +100,5 @@
 
     for (j = 0; (j < catalog.Naverage) && !interrupt; j++) {
-      m = catalog.average[j].offset;
+      m = catalog.average[j].measureOffset;
       // extract the relevant values
       // XXX for measure values, this could be optimized for one loop over measures...
Index: /trunk/Ohana/src/opihi/dvo/ccd.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/ccd.c	(revision 16809)
+++ /trunk/Ohana/src/opihi/dvo/ccd.c	(revision 16810)
@@ -72,5 +72,5 @@
     for (i = 0; i < catalog.Naverage; i++) {
       M1 = M2 = NULL;
-      m = catalog.average[i].offset;
+      m = catalog.average[i].measureOffset;
 
       SetSelectionParam (0);
Index: /trunk/Ohana/src/opihi/dvo/cmd.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/cmd.c	(revision 16809)
+++ /trunk/Ohana/src/opihi/dvo/cmd.c	(revision 16810)
@@ -70,5 +70,5 @@
     for (i = 0; i < catalog.Naverage; i++) {
       M1 = M3 = NULL;
-      m = catalog.average[i].offset;
+      m = catalog.average[i].measureOffset;
 
       SetSelectionParam (0);
Index: /trunk/Ohana/src/opihi/dvo/dbExtractAverages.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/dbExtractAverages.c	(revision 16809)
+++ /trunk/Ohana/src/opihi/dvo/dbExtractAverages.c	(revision 16810)
@@ -45,8 +45,8 @@
 
     case AVE_NMEAS:
-      value = average[0].Nm;
+      value = average[0].Nmeasure;
       break;
     case AVE_NMISS:
-      value = average[0].Nn;
+      value = average[0].Nmissing;
       break;
     case AVE_Xp:
@@ -72,5 +72,5 @@
 	  // XXX need to code this correctly: this returns just the first matching value
 	  value = NAN;
-	  for (i = 0; i < average[0].Nm; i++) {
+	  for (i = 0; i < average[0].Nmeasure; i++) {
 	    if (field->photcode->code != measure[i].photcode) continue;
 	    value = measure[i].M;
Index: /trunk/Ohana/src/opihi/dvo/dbExtractMeasures.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/dbExtractMeasures.c	(revision 16809)
+++ /trunk/Ohana/src/opihi/dvo/dbExtractMeasures.c	(revision 16810)
@@ -1,3 +1,8 @@
 # include "dvoshell.h"
+
+// to add a new field to the extractions:
+// 1) add the selection for the field below
+// 2) add the field to the ParseMeasureField in dbFields.c
+// 3) add the field to the measure enum list in dvoshell.h
 
 /* time concepts */
@@ -111,8 +116,8 @@
       break;
     case MEAS_NMEAS: /* OK */
-      value = average[0].Nm;
+      value = average[0].Nmeasure;
       break;
     case MEAS_NMISS: /* OK */
-      value = average[0].Nn;
+      value = average[0].Nmissing;
       break;
     case MEAS_OBJFLAGS: /* OK */
@@ -171,5 +176,5 @@
     case MEAS_XCCD: /* OK */
 /* I need to perform this conversion for ELIXIR and LONEOS formats on load */      
-# if 0
+# if 1
       value = measure[0].Xccd;
 # else
@@ -184,5 +189,5 @@
     case MEAS_YCCD: /* OK */
 /* I need to perform this conversion for ELIXIR and LONEOS formats on load */      
-# if 0
+# if 1
       value = measure[0].Yccd;
 # else
@@ -230,6 +235,6 @@
       value = measure[0].qPSF;
       break;
-    case MEAS_PSF_PROB: /* OK */
-      value = measure[0].psfProb;
+    case MEAS_PSF_CHISQ: /* OK */
+      value = measure[0].psfChisq;
       break;
     case MEAS_CR_NSIGMA: /* OK */
Index: /trunk/Ohana/src/opihi/dvo/dbFields.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/dbFields.c	(revision 16809)
+++ /trunk/Ohana/src/opihi/dvo/dbFields.c	(revision 16810)
@@ -148,5 +148,5 @@
   if (!strcasecmp (fieldName, "IMAGEID"))    ESCAPE (MEAS_IMAGE_ID,     MAG_NONE);
   if (!strcasecmp (fieldName, "PSF_QF"))     ESCAPE (MEAS_PSF_QF,     	MAG_NONE);
-  if (!strcasecmp (fieldName, "PSF_PROB"))   ESCAPE (MEAS_PSF_PROB,     MAG_NONE);
+  if (!strcasecmp (fieldName, "PSF_CHISQ"))  ESCAPE (MEAS_PSF_CHISQ,    MAG_NONE);
   if (!strcasecmp (fieldName, "CR_NSIGMA"))  ESCAPE (MEAS_CR_NSIGMA,    MAG_NONE);
   if (!strcasecmp (fieldName, "EXT_NSIGMA")) ESCAPE (MEAS_EXT_NSIGMA,   MAG_NONE);
Index: /trunk/Ohana/src/opihi/dvo/fitcolors.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/fitcolors.c	(revision 16809)
+++ /trunk/Ohana/src/opihi/dvo/fitcolors.c	(revision 16810)
@@ -216,5 +216,5 @@
 
 	  M1 = M2 = NULL;
-	  m = catalog[k].average[i].offset;
+	  m = catalog[k].average[i].measureOffset;
 
 	  SetSelectionParam (0);
Index: /trunk/Ohana/src/opihi/dvo/fitsed.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/fitsed.c	(revision 16809)
+++ /trunk/Ohana/src/opihi/dvo/fitsed.c	(revision 16810)
@@ -207,6 +207,6 @@
 
       // load the measurements for this source
-      m = catalog.average[i].offset;
-      for (j = 0; j < catalog.average[i].Nm; j++) {
+      m = catalog.average[i].measureOffset;
+      for (j = 0; j < catalog.average[i].Nmeasure; j++) {
 	idx = hashcode[catalog.measure[m+j].photcode];
 	if (idx == -1) continue;
Index: /trunk/Ohana/src/opihi/dvo/gstar.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/gstar.c	(revision 16809)
+++ /trunk/Ohana/src/opihi/dvo/gstar.c	(revision 16810)
@@ -151,5 +151,5 @@
 	gprint (GP_LOG, "%11.7f ", catalog.average[k].R);
 	gprint (GP_LOG, "%11.7f ", catalog.average[k].D);
-	gprint (GP_LOG, "%3d   ",  catalog.average[k].Nm);
+	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);
@@ -164,6 +164,6 @@
 	    gprint (GP_LOG, "%f",     catalog.average[k].P);
 	    gprint (GP_LOG, "%f",     catalog.average[k].dP);
-	    gprint (GP_LOG, "%x",     catalog.average[k].objID_hi);
-	    gprint (GP_LOG, "%x",     catalog.average[k].objID_lo);
+	    gprint (GP_LOG, "%x",     catalog.average[k].objID);
+	    gprint (GP_LOG, "%x",     catalog.average[k].catID);
 	}
 
@@ -188,6 +188,6 @@
 
       if (GetMeasures || SaveVectors) {
-	m = catalog.average[k].offset;
-	for (j = 0; j < catalog.average[k].Nm; j++, m++) {
+	m = catalog.average[k].measureOffset;
+	for (j = 0; j < catalog.average[k].Nmeasure; j++, m++) {
 
 	  Mcat = PhotCat (&catalog.measure[m]);
@@ -209,5 +209,5 @@
 	    if (FULL_OUTPUT) {
 		gprint (GP_LOG, "%f", catalog.measure[m].Mcal);
-		gprint (GP_LOG, "%f", catalog.measure[m].Mgal);
+		gprint (GP_LOG, "%f", catalog.measure[m].Map);
 		gprint (GP_LOG, "%f", pow(10.0, 0.4*catalog.measure[m].dt));
 		gprint (GP_LOG, "%f", 1.0 + catalog.measure[m].airmass);
@@ -223,5 +223,5 @@
 		gprint (GP_LOG, "%d", catalog.measure[m].imageID);
 		gprint (GP_LOG, "%f", catalog.measure[m].qPSF);
-		gprint (GP_LOG, "%f", catalog.measure[m].psfProb);
+		gprint (GP_LOG, "%f", catalog.measure[m].psfChisq);
 		gprint (GP_LOG, "%f", catalog.measure[m].crNsigma);
 		gprint (GP_LOG, "%f", catalog.measure[m].extNsigma);
Index: /trunk/Ohana/src/opihi/dvo/imextract.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/imextract.c	(revision 16809)
+++ /trunk/Ohana/src/opihi/dvo/imextract.c	(revision 16810)
@@ -1,5 +1,7 @@
 # include "dvoshell.h"
 
-enum {ZERO, RA, DEC, Xm, AIRMASS, MCAL, dMCAL, PHOTCODE, TIME, FWHM, EXPTIME, NSTAR, SKY, NCAL, FLAG, NX_PIX, NY_PIX, THETA, SKEW, SCALE, DSCALE};
+// need to upgrade this to support multiple fields and WHERE clauses
+
+enum {ZERO, RA, DEC, Xm, AIRMASS, MCAL, dMCAL, PHOTCODE, TIME, FWHM, EXPTIME, NSTAR, SKY, NCAL, FLAG, NX_PIX, NY_PIX, THETA, SKEW, SCALE, DSCALE, IMAGE_ID};
 
 int imextract (int argc, char **argv) {
@@ -94,4 +96,5 @@
   if (!strcasecmp (argv[1], "scale")) mode = SCALE;
   if (!strcasecmp (argv[1], "dscale")) mode = DSCALE;
+  if (!strcasecmp (argv[1], "imageID")) mode = IMAGE_ID;
   if (mode == ZERO) {
     gprint (GP_ERR, "value may be one of the following:\n");
@@ -181,4 +184,7 @@
 	vec[0].elements[N] = image[j].NY;
 	break;
+      case IMAGE_ID:
+	vec[0].elements[N] = image[j].imageID;
+	break;
       case THETA: {
 	double theta1, theta2, s1, s2;
Index: /trunk/Ohana/src/opihi/dvo/lcurve.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/lcurve.c	(revision 16809)
+++ /trunk/Ohana/src/opihi/dvo/lcurve.c	(revision 16810)
@@ -122,6 +122,6 @@
     if (r < Radius2) {
       /* found star, extract measurements */
-      m = catalog.average[N1[i]].offset;
-      for (j = 0; j < catalog.average[N1[i]].Nm; j++, m++) {
+      m = catalog.average[N1[i]].measureOffset;
+      for (j = 0; j < catalog.average[N1[i]].Nmeasure; j++, m++) {
 	if (ErrorBars) dYvec.elements[N] = catalog.measure[m].dM;
 	Xvec.elements[N] = TimeValue (catalog.measure[m].t, TimeReference, TimeFormat);
Index: /trunk/Ohana/src/opihi/dvo/lightcurve.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/lightcurve.c	(revision 16809)
+++ /trunk/Ohana/src/opihi/dvo/lightcurve.c	(revision 16810)
@@ -105,6 +105,6 @@
       k = N1[i];
       /* found star, extract measurements */
-      m = catalog.average[k].offset;
-      for (j = 0; j < catalog.average[k].Nm; j++, m++) {
+      m = catalog.average[k].measureOffset;
+      for (j = 0; j < catalog.average[k].Nmeasure; j++, m++) {
 
 	if (PhotCodeSelect) {
Index: /trunk/Ohana/src/opihi/dvo/mextract.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/mextract.c	(revision 16809)
+++ /trunk/Ohana/src/opihi/dvo/mextract.c	(revision 16810)
@@ -120,6 +120,6 @@
 
     for (j = 0; (j < catalog.Naverage) && !interrupt; j++) {
-      m = catalog.average[j].offset;
-      for (k = 0; (k < catalog.average[j].Nm); k++, m++) {
+      m = catalog.average[j].measureOffset;
+      for (k = 0; (k < catalog.average[j].Nmeasure); k++, m++) {
 
 	// extract the relevant values for this measurement
Index: /trunk/Ohana/src/opihi/dvo/photometry.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/photometry.c	(revision 16809)
+++ /trunk/Ohana/src/opihi/dvo/photometry.c	(revision 16810)
@@ -562,5 +562,5 @@
   *nlist = 0; 
   Nlist = 0;
-  NLIST = MAX (1, average[0].Nm);
+  NLIST = MAX (1, average[0].Nmeasure);
   ALLOCATE (list, double, NLIST);
 
@@ -569,5 +569,5 @@
 
   /* look for measures */
-  for (i = 0; i < average[0].Nm; i++) {
+  for (i = 0; i < average[0].Nmeasure; i++) {
     TESTCODE (code, measure[i]);  /* skip measurements not matching photcode */
     TESTMEASURE (measure[i]);     /* exclusions based on measure.params  */
@@ -633,8 +633,8 @@
 
     case AVE_NMEAS:
-      value = average[0].Nm;
+      value = average[0].Nmeasure;
       break;
     case AVE_NMISS:
-      value = average[0].Nn;
+      value = average[0].Nmissing;
       break;
     case AVE_Xp:
@@ -658,5 +658,5 @@
 	case MAG_CAL:
 	  value = NAN;
-	  for (i = 0; i < average[0].Nm; i++) {
+	  for (i = 0; i < average[0].Nmeasure; i++) {
 	      if (code[0].code != measure[i].photcode) continue;
 	      value = measure[i].M;
@@ -679,5 +679,5 @@
     case AVE_NCODE:
       value = 0;
-      for (i = 0; i < average[0].Nm; i++) {
+      for (i = 0; i < average[0].Nmeasure; i++) {
 	if (code[0].code != GetPhotcodeEquivCodebyCode (measure[i].photcode)) continue;
 	value ++;
@@ -686,5 +686,5 @@
     case AVE_NPHOT:
       value = 0;
-      for (i = 0; i < average[0].Nm; i++) {
+      for (i = 0; i < average[0].Nmeasure; i++) {
 	if (code[0].code != GetPhotcodeEquivCodebyCode (measure[i].photcode)) continue;
 	if (measure[i].dbFlags & (ID_MEAS_POOR | ID_MEAS_SKIP)) continue;
@@ -695,5 +695,5 @@
     case AVE_NCRIT:
       value = 0;
-      for (i = 0; i < average[0].Nm; i++) {
+      for (i = 0; i < average[0].Nmeasure; i++) {
 	if ((code != NULL) && (code[0].code != GetPhotcodeEquivCodebyCode (measure[i].photcode))) continue;
 	if (ErrSelect && (measure[i].dM > ErrValue)) continue;
@@ -716,5 +716,5 @@
   
   Nt = Nc = 0;
-  for (k = 0; k < average[0].Nm; k++) {
+  for (k = 0; k < average[0].Nmeasure; k++) {
     if ((code != NULL) && (code[0].code != GetPhotcodeEquivCodebyCode (measure[k].photcode))) continue;
     Nc ++;
@@ -732,5 +732,5 @@
   
   Nt[0] = Nt[1] = Nt[2] = 0;
-  for (k = 0; k < average[0].Nm; k++) {
+  for (k = 0; k < average[0].Nmeasure; k++) {
     if (code != GetPhotcodeEquivCodebyCode (measure[k].photcode)) continue;
     N = GetMeasureTypeCode (&measure[k]);
@@ -793,5 +793,5 @@
   if ((code != NULL) && (code[0].type == PHOT_REF)) {
     Nm = 0;
-    for (i = 0; i < average[0].Nm; i++) {
+    for (i = 0; i < average[0].Nmeasure; i++) {
       TESTCODE (code, measure[i]);
       Nm++;
@@ -805,5 +805,5 @@
   if (FWHMSelect) {
     Nm = 0;
-    for (i = 0; i < average[0].Nm; i++) {
+    for (i = 0; i < average[0].Nmeasure; i++) {
       fwhm = measure[i].FWx / 100.0;
       switch (FWHMsign) {
@@ -820,5 +820,5 @@
       Nm++;
     }
-    if (average[0].Nm * FWHMfrac > Nm) return (FALSE);
+    if (average[0].Nmeasure * FWHMfrac > Nm) return (FALSE);
   }
 
@@ -833,5 +833,5 @@
   if (NcodeSelect) {
     Nm = 0;
-    for (i = 0; i < average[0].Nm; i++) {
+    for (i = 0; i < average[0].Nmeasure; i++) {
       TESTCODE (code, measure[i]);
       Nm++;
@@ -872,5 +872,5 @@
   if (NphotSelect) {
     Nm = 0;
-    for (i = 0; i < average[0].Nm; i++) {
+    for (i = 0; i < average[0].Nmeasure; i++) {
       TESTCODE (code, measure[i]);
       if (measure[i].dbFlags && ID_MEAS_SKIP) continue;
@@ -931,5 +931,5 @@
    Ns    - secfilt entry (-1 for PRI)
    &catalog.average[i], 
-   &catalog.measure[catalog.average[i].offset], 
+   &catalog.measure[catalog.average[i].measureOffset], 
    &catalog.secfilt[i*Nsec] 
 */
@@ -974,5 +974,5 @@
   *nlist = 0; 
   Nlist = 0;
-  NLIST = MAX (1, average[0].Nm*average[0].Nm);
+  NLIST = MAX (1, average[0].Nmeasure*average[0].Nmeasure);
   ALLOCATE (list, double, NLIST);
   M1 = M2 = NULL;
@@ -1015,5 +1015,5 @@
   *nlist = 0; 
   Nlist = 0;
-  NLIST = MAX (1, average[0].Nm*average[0].Nm);
+  NLIST = MAX (1, average[0].Nmeasure*average[0].Nmeasure);
   ALLOCATE (list, double, NLIST);
 
@@ -1031,10 +1031,10 @@
 
   /* loop twice over all measures */
-  for (i = 0; i < average[0].Nm; i++) {
+  for (i = 0; i < average[0].Nmeasure; i++) {
     SetSelectionParam (Np0);
     TESTCODE (code[0], measure[i]);
     TESTMEASURE (measure[i]);
     SETMAG(M1, measure[i], mode[0]);
-    for (j = 0; j < average[0].Nm; j++) {
+    for (j = 0; j < average[0].Nmeasure; j++) {
       if (i == j) continue;
       SetSelectionParam (Np1);
@@ -1086,5 +1086,5 @@
   *nlist = 0; 
   Nlist = 0;
-  NLIST = MAX (1, average[0].Nm*average[0].Nm);
+  NLIST = MAX (1, average[0].Nmeasure*average[0].Nmeasure);
   ALLOCATE (list, double, NLIST);
 
@@ -1099,9 +1099,9 @@
 
   /* loop twice over all measures */
-  for (i = 0; i < average[0].Nm; i++) {
+  for (i = 0; i < average[0].Nmeasure; i++) {
     TESTCODE (code[0], measure[i]);
     TESTMEASURE (measure[i]);
     SETMAG(M1, measure[i], mode[0]);
-    for (j = 0; j < average[0].Nm; j++) {
+    for (j = 0; j < average[0].Nmeasure; j++) {
       if (i == j) continue;
       TESTCODE (code[1], measure[j]);
Index: /trunk/Ohana/src/opihi/dvo/pmeasure.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/pmeasure.c	(revision 16809)
+++ /trunk/Ohana/src/opihi/dvo/pmeasure.c	(revision 16810)
@@ -111,6 +111,6 @@
       while (catalog.average[i].R < Rmin) catalog.average[i].R += 360.0;
       while (catalog.average[i].R > Rmax) catalog.average[i].R -= 360.0;
-      m = catalog.average[i].offset;
-      for (k = 0; k < catalog.average[i].Nm; k++) {
+      m = catalog.average[i].measureOffset;
+      for (k = 0; k < catalog.average[i].Nmeasure; k++) {
 	if (FlagClip) {
 	  flags = catalog.measure[m+k].dbFlags;
Index: /trunk/Ohana/src/opihi/dvo/subpix.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/subpix.c	(revision 16809)
+++ /trunk/Ohana/src/opihi/dvo/subpix.c	(revision 16810)
@@ -130,6 +130,6 @@
 
   /* only print the entries for existing measurements of this star */ 
-  measure = &catalog.measure[catalog.average[Nentry].offset];
-  Nmeasure = catalog.average[Nentry].Nm;
+  measure = &catalog.measure[catalog.average[Nentry].measureOffset];
+  Nmeasure = catalog.average[Nentry].Nmeasure;
   for (i = 0; i < Nsub; i++) {
     I = index[i];
Index: /trunk/Ohana/src/opihi/include/dvoshell.h
===================================================================
--- /trunk/Ohana/src/opihi/include/dvoshell.h	(revision 16809)
+++ /trunk/Ohana/src/opihi/include/dvoshell.h	(revision 16810)
@@ -72,5 +72,5 @@
       MEAS_IMAGE_ID, 
       MEAS_PSF_QF, 
-      MEAS_PSF_PROB, 
+      MEAS_PSF_CHISQ, 
       MEAS_CR_NSIGMA, 
       MEAS_EXT_NSIGMA, 
Index: /trunk/Ohana/src/opihi/pantasks/ipptool2book.c
===================================================================
--- /trunk/Ohana/src/opihi/pantasks/ipptool2book.c	(revision 16809)
+++ /trunk/Ohana/src/opihi/pantasks/ipptool2book.c	(revision 16810)
@@ -108,7 +108,4 @@
     FREEKEYS;
     return FALSE;
-  }
-  if (strcmp(bookName, argv[2])) {
-    gprint (GP_ERR, "WARNING: metadata output name %s does not match expected bookname %s\n", bookName, argv[2]);
   }
   free (line);
Index: /trunk/Ohana/src/relastro/Makefile
===================================================================
--- /trunk/Ohana/src/relastro/Makefile	(revision 16809)
+++ /trunk/Ohana/src/relastro/Makefile	(revision 16810)
@@ -37,4 +37,6 @@
 $(SRC)/UpdateObjects.$(ARCH).o   \
 $(SRC)/UpdateSimple.$(ARCH).o    \
+$(SRC)/UpdateMeasures.$(ARCH).o  \
+$(SRC)/GetAstromError.$(ARCH).o  \
 $(SRC)/args.$(ARCH).o		 \
 $(SRC)/bcatalog.$(ARCH).o	 \
Index: /trunk/Ohana/src/relastro/include/relastro.h
===================================================================
--- /trunk/Ohana/src/relastro/include/relastro.h	(revision 16809)
+++ /trunk/Ohana/src/relastro/include/relastro.h	(revision 16810)
@@ -10,4 +10,6 @@
 } CoordMode;
 
+typedef enum {ERROR_MODE_RA, ERROR_MODE_DEC, ERROR_MODE_POS} ErrorMode;
+
 typedef struct {
   double R, D;  /* Sky Coords    - degrees */
@@ -15,5 +17,7 @@
   double L, M;  /* Focal Plane   - pixels  */
   double X, Y;  /* Chip Coords   - pixels  */
-  double Mag, dMag;
+  double Mag;
+  double dMag;
+  double dPos;
   int mask;
 } StarData;
@@ -263,9 +267,10 @@
 void fit_add (CoordFit *fit, double x1, double y1, double x2, double y2, double wt);
 void fit_eval (CoordFit *fit);
+void fit_apply (CoordFit *fit, double *x2, double *y2, double x1, double y1);
 double **poly2d_dx (double **poly, int Nx, int Ny);
 double **poly2d_dy (double **poly, int Nx, int Ny);
 double **poly2d_copy (double **poly, int Nx, int Ny);
 double poly2d_eval (double **poly, int Nx, int Ny, double x, double y);
-void fit_apply_coords (CoordFit *fit, Coords *coords);
+CoordFit *fit_apply_coords (CoordFit *fit, Coords *coords);
 int CoordsGetCenter (CoordFit *fit, double tol, double *xo, double *yo);
 CoordFit *CoordsSetCenter (CoordFit *input, double Xo, double Yo);
@@ -278,4 +283,7 @@
 int UpdateChips (Catalog *catalog, int Ncatalog);
 int UpdateMosaic (Catalog *catalog, int Ncatalog);
+int UpdateMeasures (Catalog *catalog, int Ncatalog);
+void fixImageRaw (Catalog *catalog, int Ncatalog, int im);
+
 int sun_ecliptic (double jd, double *lambda, double *beta, double *epsilon);
 int ParFactor (double *pR, double *pD, double R, double D, time_t T);
Index: /trunk/Ohana/src/relastro/src/FitChip.c
===================================================================
--- /trunk/Ohana/src/relastro/src/FitChip.c	(revision 16809)
+++ /trunk/Ohana/src/relastro/src/FitChip.c	(revision 16810)
@@ -1,24 +1,67 @@
 # include "relastro.h"
+# define SCATTER_MAX_ERROR 0.05
 
 void FitChip (StarData *raw, StarData *ref, int Nmatch, Coords *coords) {
 
-  int i;
+  int i, Nscatter, Niter;
   CoordFit *fit;
+  double dL, dM, dR, dRmax, *values;
 
-  fit = fit_init (coords[0].Npolyterms);
-  for (i = 0; i < Nmatch; i++) {
-    if (raw[i].mask) continue;
-    fit_add (fit, raw[i].X, raw[i].Y, ref[i].L, ref[i].M, 1.0);
-  }
-  fit_eval (fit);
-  fit_apply_coords (fit, coords);
-  fit_free (fit);
+  ALLOCATE (values, double, Nmatch);
 
-  // apply new coords to raw (X,Y -> L,M)
-  for (i = 0; i < Nmatch; i++) {
-    XY_to_LM (&raw[i].L, &raw[i].M, raw[i].X, raw[i].Y, coords);
+  for (Niter = 0; Niter < 3; Niter ++) {
+    // measure the scatter distribution (use only the bright end detections)
+    for (i = Nscatter = 0; i < Nmatch; i++) {
+      if (raw[i].mask) continue;
+      if (raw[i].dMag > SCATTER_MAX_ERROR) continue;
+
+      dL = raw[i].L - ref[i].L;
+      dM = raw[i].M - ref[i].M;
+      dR = hypot (dL, dM);
+    
+      values[Nscatter] = dR;
+      Nscatter++;
+    }
+
+    // for a 2D Gaussian, 40% of the points are within 1 sigma; dRmax is ~ 3 sigma
+    dsort (values, Nscatter);
+    dRmax = 3.0*values[(int)(0.40*Nscatter)];
+
+    fit = fit_init (coords[0].Npolyterms);
+
+    for (i = 0; i < Nmatch; i++) {
+      if (raw[i].mask) continue;
+
+      // require radius of XXX arcsec
+      dL = raw[i].L - ref[i].L;
+      dM = raw[i].M - ref[i].M;
+      dR = hypot (dL, dM);
+
+      if (dR > dRmax) {
+	continue;
+	raw[i].mask = TRUE;
+      }
+    
+      fit_add (fit, raw[i].X, raw[i].Y, ref[i].L, ref[i].M, raw[i].dPos);
+    }
+    fprintf (stderr, "scatter limit: %f based on %d detections; using %d of %d for fit\n",
+	     dRmax, Nscatter, fit[0].Npts, Nmatch);
+
+    if (fit[0].Npts < 25) {
+      fit_free (fit);
+      free (values);
+      return;
+    }
+    fit_eval (fit);
+    fit_apply_coords (fit, coords);
+    fit_free (fit);
+
+    for (i = 0; i < Nmatch; i++) {
+      XY_to_LM (&raw[i].L, &raw[i].M, raw[i].X, raw[i].Y, coords);
+    }
   }
 
-  fit_free (fit);
+  free (values);
+  return;
 }
 
@@ -34,3 +77,28 @@
 */
 
-/* XXX I'm not using the errors at all : this could at least be done with the dMag values */
+/* example using fit_apply() :
+
+  f = fopen ("test3.dat", "w");
+
+  // apply new coords to raw (X,Y -> L,M)
+  for (i = 0; i < Nmatch; i++) {
+    fprintf (f, "%f %f  %f %f  ", raw[i].X, raw[i].Y, raw[i].L, raw[i].M);
+    fit_apply (newfit, &L1, &M1, raw[i].X - coords[0].crpix1, raw[i].Y - coords[0].crpix2);
+    fprintf (f, "%f %f\n", L1, M1);
+  }
+  fclose (f);
+*/
+
+/*** XXX this function can be improved in 4 important ways:
+
+1) the initial value of the clipping radius could be set based on the distribution of the
+   value (eg, inner 50%) (better to use dL, dM rather than dP, dQ)
+
+2) multiple clipping passes could be performed
+
+3) the per-star astrometric errors could be included in the fit (non-systematic terms at
+   least, or scaled values of the mag error, or simply the mag error itself)
+
+4) we could ignore input detections on the basis of the photFlags
+
+*/
Index: /trunk/Ohana/src/relastro/src/FitMosaic.c
===================================================================
--- /trunk/Ohana/src/relastro/src/FitMosaic.c	(revision 16809)
+++ /trunk/Ohana/src/relastro/src/FitMosaic.c	(revision 16810)
@@ -5,9 +5,23 @@
   int i;
   CoordFit *fit;
+  double dP, dQ, dR;
 
   fit = fit_init (coords[0].Npolyterms);
   for (i = 0; i < Nmatch; i++) {
     if (raw[i].mask) continue;
+
+    // require radius of XXX arcsec
+    dP = raw[i].P - ref[i].P;
+    dQ = raw[i].Q - ref[i].Q;
+    dR = 3600.0 * hypot (dP, dQ);
+
+    // XXX the value needs to be set in a more intelligent way
+    if (dR > 0.15) continue;
+    
     fit_add (fit, raw[i].L, raw[i].M, ref[i].P, ref[i].Q, 1.0);
+  }
+  if (fit[0].Npts == 0) {
+    fit_free (fit);
+    return;
   }
   fit_eval (fit);
Index: /trunk/Ohana/src/relastro/src/FitSimple.c
===================================================================
--- /trunk/Ohana/src/relastro/src/FitSimple.c	(revision 16809)
+++ /trunk/Ohana/src/relastro/src/FitSimple.c	(revision 16810)
@@ -5,9 +5,23 @@
   int i;
   CoordFit *fit;
+  double dP, dQ, dR;
 
   fit = fit_init (coords[0].Npolyterms);
   for (i = 0; i < Nmatch; i++) {
     if (raw[i].mask) continue;
+
+    // require radius of XXX arcsec
+    dP = raw[i].P - ref[i].P;
+    dQ = raw[i].Q - ref[i].Q;
+    dR = 3600.0 * hypot (dP, dQ);
+
+    // XXX the value needs to be set in a more intelligent way
+    if (dR > 0.15) continue;
+    
     fit_add (fit, raw[i].X, raw[i].Y, ref[i].P, ref[i].Q, 1.0);
+  }
+  if (fit[0].Npts == 0) {
+    fit_free (fit);
+    return;
   }
   fit_eval (fit);
@@ -21,6 +35,4 @@
     raw[i].Q = raw[i].M;
   }
-
-  fit_free (fit);
 }
 
@@ -37,2 +49,4 @@
 
 /* XXX I'm not using the errors at all : this could at least be done with the dMag values */
+
+/* XXX See notes in FitChips.c */
Index: /trunk/Ohana/src/relastro/src/GetAstromError.c
===================================================================
--- /trunk/Ohana/src/relastro/src/GetAstromError.c	(revision 16810)
+++ /trunk/Ohana/src/relastro/src/GetAstromError.c	(revision 16810)
@@ -0,0 +1,36 @@
+# include "relastro.h"
+
+float GetAstromError (Measure *measure, int mode) {
+
+  PhotCode *code;
+  float dPobs, dPsys, dPtotal, dM, AS, MS;
+
+  switch (mode) {
+    case ERROR_MODE_RA:
+      dPobs = measure[0].dXccd;  // need to redefine this as RAerr
+      break;
+    case ERROR_MODE_DEC:
+      dPobs = measure[0].dYccd;  // need to redefine this as RAerr
+      break;
+    case ERROR_MODE_POS:
+      dPobs = hypot (measure[0].dXccd, measure[0].dYccd);  // need to redefine this as RAerr
+      break;
+    default:
+      abort();
+  }
+
+  /* the astrometric errors are not being carried yet (but should be!) */
+  /* we use the photometric mag error as a weighting term */
+
+  code 	= GetPhotcodebyCode (measure[0].photcode);
+  AS   	= code[0].astromErrScale;
+  MS   	= code[0].astromErrMagScale;
+  dPsys = code[0].astromErrSys;
+  dM    = measure[0].dM;
+  
+  dPtotal = sqrt(SQ(dPsys) + AS*SQ(dPobs) + MS*SQ(dM));
+  dPtotal = MAX (dPtotal, MIN_ERROR);
+
+  return (dPtotal);
+}
+
Index: /trunk/Ohana/src/relastro/src/ImageOps.c
===================================================================
--- /trunk/Ohana/src/relastro/src/ImageOps.c	(revision 16809)
+++ /trunk/Ohana/src/relastro/src/ImageOps.c	(revision 16810)
@@ -33,6 +33,6 @@
 
   for (i = 0; i < Nimage; i++) {
-    start[i] = image[i].tzero - MAX(0.05*image[i].trate*image[i].NY, 1);
-    stop[i]  = image[i].tzero + MAX(1.05*image[i].trate*image[i].NY, 1);
+    start[i] = image[i].tzero - MAX(0.01*image[i].trate*image[i].NY, 1);
+    stop[i]  = image[i].tzero + MAX(1.01*image[i].trate*image[i].NY, 1);
   }
 }
@@ -81,4 +81,5 @@
 
   int i, j;
+  char *name;
 
   for (i = 0; i < Ncatalog; i++) {
@@ -87,4 +88,10 @@
     }
   }
+
+  for (i = 0; VERBOSE && (i < Nimage); i++) {
+    name = GetPhotcodeNamebyCode (image[i].photcode);
+    fprintf (stderr, "image %d has %d measures (%s, %s)\n", i, Nlist[i], 
+	     ohana_sec_to_date(image[i].tzero), name);
+  } 
 }
 
@@ -182,7 +189,75 @@
 // return StarData values for detections in the specified image, converting coordinates from the
 // chip positions: X,Y -> L,M -> P,Q -> R,D
+void fixImageRaw (Catalog *catalog, int Ncatalog, int im) {
+
+  int i, m, c, n;
+  double X, Y, L, M, P, Q, R, D, dR, dD;
+  
+  Mosaic *mosaic;
+  Coords *moscoords, *imcoords;
+  
+  moscoords = NULL;
+  mosaic = getMosaicForImage (im);
+  if (mosaic != NULL) {
+      moscoords = &mosaic[0].coords;
+  }
+  imcoords = &image[im].coords;
+
+  for (i = 0; i < Nlist[im]; i++) {
+    m = mlist[im][i];
+    c = clist[im][i];
+
+    X = catalog[c].measure[m].Xccd;
+    Y = catalog[c].measure[m].Yccd;
+    n = catalog[c].measure[m].averef;
+
+    if (moscoords == NULL) {
+      // this is a Simple image (not a mosaic)
+      // note that for a Simple image, L,M = P,Q
+      XY_to_LM (&L, &M, X, Y, imcoords);
+      LM_to_RD (&R, &D, L, M, imcoords);
+    } else {
+      XY_to_LM (&L, &M, X, Y, imcoords);
+      XY_to_LM (&P, &Q, L, M, moscoords);
+      LM_to_RD (&R, &D, P, Q, moscoords);
+    }
+
+    // new dR, dD : test
+    dR = 3600.0*(catalog[c].average[n].R - R);
+    dD = 3600.0*(catalog[c].average[n].D - D);
+    
+    if (fabs(catalog[c].measure[m].dR - dR) > 10.0) {
+      // XXXXX running into this still for last megacam exposure: wrong mosaic?
+      // ???? inconsistently hitting this????
+      fprintf (stderr, "!");
+      abort ();
+    }
+    if (fabs(catalog[c].measure[m].dD - dD) > 10.0) {
+      fprintf (stderr, "*");
+      abort ();
+    }
+
+    catalog[c].measure[m].dR = dR;
+    catalog[c].measure[m].dD = dD;
+
+    if (catalog[c].measure[m].dR > +180.0*3600.0) {
+      // average on high end of boundary, move star up
+      R += 360.0;
+      catalog[c].measure[m].dR = 3600.0*(catalog[c].average[n].R - R);
+    }
+    if (catalog[c].measure[m].dR < -180.0*3600.0) {
+      // average on low end of boundary, move star down
+      R -= 360.0;
+      catalog[c].measure[m].dR = 3600.0*(catalog[c].average[n].R - R);
+    }
+  }  
+  return;
+}
+
+// return StarData values for detections in the specified image, converting coordinates from the
+// chip positions: X,Y -> L,M -> P,Q -> R,D
 StarData *getImageRaw (Catalog *catalog, int Ncatalog, int im, int *Nstars, CoordMode mode) {
 
-  int i, m, c;
+  int i, m, c, n;
   
   Mosaic *mosaic;
@@ -213,6 +288,12 @@
     raw[i].Mag  = catalog[c].measure[m].M;
     raw[i].dMag = catalog[c].measure[m].dM;
+    raw[i].dPos = GetAstromError (&catalog[c].measure[m], ERROR_MODE_POS);
+
+    n = catalog[c].measure[m].averef;
 
     raw[i].mask = FALSE;
+    if (catalog[c].average[n].Nmeasure < 2) {
+      raw[i].mask = TRUE;
+    }
 
     switch (mode) {
@@ -273,4 +354,5 @@
     ref[i].Mag  = catalog[c].measure[m].M;
     ref[i].dMag = catalog[c].measure[m].dM;
+    ref[i].dPos = GetAstromError (&catalog[c].measure[m], ERROR_MODE_POS);
 
     ref[i].mask = FALSE;
@@ -286,5 +368,5 @@
       case MODE_MOSAIC:
       RD_to_LM (&ref[i].P, &ref[i].Q, ref[i].R, ref[i].D, moscoords);
-      LM_to_XY (&ref[i].M, &ref[i].L, ref[i].P, ref[i].Q, moscoords);
+      LM_to_XY (&ref[i].L, &ref[i].M, ref[i].P, ref[i].Q, moscoords);
       LM_to_XY (&ref[i].X, &ref[i].Y, ref[i].L, ref[i].M, &image[im].coords);
       break;
Index: /trunk/Ohana/src/relastro/src/MosaicOps.c
===================================================================
--- /trunk/Ohana/src/relastro/src/MosaicOps.c	(revision 16809)
+++ /trunk/Ohana/src/relastro/src/MosaicOps.c	(revision 16810)
@@ -38,6 +38,6 @@
 
     /* set image time range */
-    start = image[i].tzero - MAX(0.05*image[i].trate*image[i].NY, 1);
-    stop  = image[i].tzero + MAX(1.05*image[i].trate*image[i].NY, 1);
+    start = image[i].tzero - MAX(0.01*image[i].trate*image[i].NY, 1);
+    stop  = image[i].tzero + MAX(1.01*image[i].trate*image[i].NY, 1);
 
     /* a new mosaic, define ranges */
@@ -77,6 +77,6 @@
 
     /* set image time range */
-    start = image[i].tzero - MAX(0.05*image[i].trate*image[i].NY, 1);
-    stop  = image[i].tzero + MAX(1.05*image[i].trate*image[i].NY, 1);
+    start = image[i].tzero - MAX(0.01*image[i].trate*image[i].NY, 1);
+    stop  = image[i].tzero + MAX(1.01*image[i].trate*image[i].NY, 1);
 
     /* find existing mosaic with this time range */
Index: /trunk/Ohana/src/relastro/src/UpdateChips.c
===================================================================
--- /trunk/Ohana/src/relastro/src/UpdateChips.c	(revision 16809)
+++ /trunk/Ohana/src/relastro/src/UpdateChips.c	(revision 16810)
@@ -21,4 +21,5 @@
     ref = getImageRef (catalog, Ncatalog, i, &Nstars, MODE_MOSAIC);
 
+    fprintf (stderr, "image %d : Nstars: %d\n", i, Nstars);
     FitChip (raw, ref, Nstars, &image[i].coords);
 
Index: /trunk/Ohana/src/relastro/src/UpdateMeasures.c
===================================================================
--- /trunk/Ohana/src/relastro/src/UpdateMeasures.c	(revision 16810)
+++ /trunk/Ohana/src/relastro/src/UpdateMeasures.c	(revision 16810)
@@ -0,0 +1,21 @@
+# include "relastro.h"
+
+int UpdateMeasures (Catalog *catalog, int Ncatalog) {
+
+  int i, Nimage;
+  Image *image;
+
+  image = getimages (&Nimage);
+
+  for (i = 0; i < Nimage; i++) {
+
+    /* skip DIS images (since they have no associated detections) */
+    if (!strcmp(&image[i].coords.ctype[4], "-DIS")) continue;
+
+    /* convert measure coordinates to raw entries */
+    fixImageRaw (catalog, Ncatalog, i);
+  }
+
+  return (TRUE);
+}
+
Index: /trunk/Ohana/src/relastro/src/UpdateObjects.c
===================================================================
--- /trunk/Ohana/src/relastro/src/UpdateObjects.c	(revision 16809)
+++ /trunk/Ohana/src/relastro/src/UpdateObjects.c	(revision 16810)
@@ -18,5 +18,5 @@
   for (i = 0; i < Ncatalog; i++) {
     for (j = 0; j < catalog[i].Naverage; j++) {
-      Nmax = MAX (Nmax, catalog[i].average[j].Nm);
+      Nmax = MAX (Nmax, catalog[i].average[j].Nmeasure);
     }
   }
@@ -48,5 +48,4 @@
   double Tmin, Tmax;
   float errorScale;
-  PhotCode *code;
 
   initObjectData (catalog, Ncatalog);
@@ -81,10 +80,10 @@
 
       N = 0;
-      m = catalog[i].average[j].offset;
+      m = catalog[i].average[j].measureOffset;
 
       Tmin = Tmax = (catalog[i].measure[m].t - To) / (86400*365.25);
       mode = FIT_MODE;
 
-      for (k = 0; k < catalog[i].average[j].Nm; k++, m++) {
+      for (k = 0; k < catalog[i].average[j].Nmeasure; k++, m++) {
 	if (catalog[i].measure[m].dbFlags & MEAS_BAD) continue;
 	
@@ -96,11 +95,6 @@
 	Tmax = MAX(Tmax, T[N]);
 
-	/* the astrometric errors are not being carried yet (but should be!) */
-	/* we use the photometric mag error as a weighting term */
-
-	code = GetPhotcodebyCode (catalog[0].measure[m].photcode);
-	errorScale = code[0].astromScale;
-	dR[N] = MAX (catalog[i].measure[m].dM, MIN_ERROR) * errorScale;
-	dD[N] = MAX (catalog[i].measure[m].dM, MIN_ERROR) * errorScale;
+	dR[N] = GetAstromError (&catalog[i].measure[m], ERROR_MODE_RA);
+	dD[N] = GetAstromError (&catalog[i].measure[m], ERROR_MODE_DEC);
 	dT[N] = catalog[i].measure[m].dt;
 
@@ -193,6 +187,6 @@
 
       // the measure fields must be updated before the average fields
-      m = catalog[i].average[j].offset;
-      for (k = 0; k < catalog[i].average[j].Nm; k++, m++) {
+      m = catalog[i].average[j].measureOffset;
+      for (k = 0; k < catalog[i].average[j].Nmeasure; k++, m++) {
 	if (catalog[i].measure[m].dbFlags & MEAS_BAD) continue;
 	setMeanR (fit.Ro, &catalog[i].measure[m], &catalog[i].average[j], &catalog[i].secfilt[j*PhotNsec]);
Index: /trunk/Ohana/src/relastro/src/args.c
===================================================================
--- /trunk/Ohana/src/relastro/src/args.c	(revision 16809)
+++ /trunk/Ohana/src/relastro/src/args.c	(revision 16810)
@@ -202,16 +202,27 @@
   fprintf (stderr, "ERROR: USAGE: relastro -region RA RA DEC DEC\n");
   fprintf (stderr, "  working options: \n");
-  fprintf (stderr, "  -time (start) (stop)\n");
-  fprintf (stderr, "  -v\n");
+  fprintf (stderr, "  -update-objects\n");
+  fprintf (stderr, "    -pm\n");
+  fprintf (stderr, "    -par\n");
+  fprintf (stderr, "    -pmpar\n");
+  fprintf (stderr, "  -update-simple\n");
+  fprintf (stderr, "  -update-chips\n");
+  fprintf (stderr, "  -update-mosaics\n");
+  fprintf (stderr, "  -time (start)(stop)\n");
+  fprintf (stderr, "  -photcode (code)[,code,code...]\n");
   fprintf (stderr, "  -plot\n");
   fprintf (stderr, "  -plotdelay (seconds)\n");
-  fprintf (stderr, "  -update\n");
+  fprintf (stderr, "  -statmode (mode)\n");
+  fprintf (stderr, "  -reset");
+  fprintf (stderr, "  -update : apply new fit to database\n");
   fprintf (stderr, "  -params\n");
-  fprintf (stderr, "  -reset\n");
+  fprintf (stderr, "  -plrange\n");
+  fprintf (stderr, "  -minerror\n");
+  fprintf (stderr, "  -area\n");
   fprintf (stderr, "  -area Xmin Xmax Ymin Ymax\n");
   fprintf (stderr, "  -instmag min max\n\n");
-  fprintf (stderr, "  planned options: \n");
-  fprintf (stderr, "  -photcode code[,code,code,..]\n");
+  fprintf (stderr, "  -v\n");
   fprintf (stderr, "  \n");
   exit (2);
 } 
+
Index: /trunk/Ohana/src/relastro/src/bcatalog.c
===================================================================
--- /trunk/Ohana/src/relastro/src/bcatalog.c	(revision 16809)
+++ /trunk/Ohana/src/relastro/src/bcatalog.c	(revision 16810)
@@ -22,9 +22,9 @@
   /* exclude stars not in range or with too few measurements */
   for (i = 0; i < catalog[0].Naverage; i++) {
-    if (catalog[0].average[i].Nm < 2) continue; 
+    if (catalog[0].average[i].Nmeasure < 2) continue; 
 
     /* start with all stars good */
     subcatalog[0].average[Naverage] = catalog[0].average[i];
-    subcatalog[0].average[Naverage].offset = Nmeasure;
+    subcatalog[0].average[Naverage].measureOffset = Nmeasure;
     for (j = 0; j < PhotNsec; j++) {
       subcatalog[0].secfilt[PhotNsec*Naverage+j] = catalog[0].secfilt[PhotNsec*i+j];
@@ -38,7 +38,7 @@
 
     Nm = 0;
-    for (j = 0; j < catalog[0].average[i].Nm; j++) {
+    for (j = 0; j < catalog[0].average[i].Nmeasure; j++) {
 
-      offset = catalog[0].average[i].offset + j;
+      offset = catalog[0].average[i].measureOffset + j;
 
       /* select measurements by photcode, if specified */
@@ -95,5 +95,5 @@
       continue; 
     }
-    subcatalog[0].average[Naverage].Nm = Nm;
+    subcatalog[0].average[Naverage].Nmeasure = Nm;
     Naverage ++;
     if (Naverage == NAVERAGE) {
Index: /trunk/Ohana/src/relastro/src/fitpoly.c
===================================================================
--- /trunk/Ohana/src/relastro/src/fitpoly.c	(revision 16809)
+++ /trunk/Ohana/src/relastro/src/fitpoly.c	(revision 16810)
@@ -128,4 +128,14 @@
       matrix[i][j] = fit[0].sum[ix+jx][iy+jy];
     }
+
+    // mask the terms not represented by the Coords terms
+    if (ix + iy > fit[0].Norder) {
+      for (j = 0; j < fit[0].Nelems; j++) {
+	matrix[i][j] = 0.0;
+      }
+      vector[i][0] = 0.0;
+      vector[i][1] = 0.0;
+      matrix[i][i] = 1.0;
+    }      
   }
 
@@ -133,6 +143,6 @@
     ix = i % fit[0].Nterms;
     iy = i / fit[0].Nterms;
-    fprintf (stderr, "x2 : x^%dy^%d: %10.4g    y2 : x^%dy^%d: %10.4g \n", 
-	     ix, iy, vector[i][0], ix, iy, vector[i][1]);
+    // fprintf (stderr, "x2 : x^%dy^%d: %10.4g    y2 : x^%dy^%d: %10.4g \n", 
+    // ix, iy, vector[i][0], ix, iy, vector[i][1]);
   }	
 
@@ -142,6 +152,6 @@
     ix = i % fit[0].Nterms;
     iy = i / fit[0].Nterms;
-    fprintf (stderr, "x2 : x^%dy^%d: %10.4g    y2 : x^%dy^%d: %10.4g \n", 
-	     ix, iy, vector[i][0], ix, iy, vector[i][1]);
+    // fprintf (stderr, "x2 : x^%dy^%d: %10.4g    y2 : x^%dy^%d: %10.4g \n", 
+    // ix, iy, vector[i][0], ix, iy, vector[i][1]);
   }	
 
@@ -158,4 +168,28 @@
 }
 
+void fit_apply (CoordFit *fit, double *x2, double *y2, double x1, double y1) {
+  
+  int ix, iy;
+  double xterm, yterm, term;
+  double x, y;
+
+  x = 0.0;
+  y = 0.0;
+
+  xterm = 1;
+  for (ix = 0; ix < fit[0].Nterms; ix++) {
+    yterm = 1;
+    for (iy = 0; iy < fit[0].Nterms; iy++) {
+      term = xterm*yterm;
+      x += fit[0].xfit[ix][iy]*term;
+      y += fit[0].yfit[ix][iy]*term;
+      yterm *= y1;
+    }
+    xterm *= x1;
+  }
+  *x2 = x;
+  *y2 = y;
+}
+
 // Nx, Ny is the number of terms in x and in y
 double **poly2d_dx (double **poly, int Nx, int Ny) {
@@ -209,5 +243,5 @@
   for (i = 0; i < Nx; i++) {
     for (j = 0; j < Ny; j++) {
-      out[i][j] = poly[i][j+1];
+      out[i][j] = poly[i][j];
     }
   }
@@ -237,9 +271,9 @@
 /* this should only apply to the polynomial, not the projection terms */
 /* compare with psastro supporting code */
-void fit_apply_coords (CoordFit *fit, Coords *coords) {
+CoordFit *fit_apply_coords (CoordFit *fit, Coords *coords) {
 
   double c11, c12;
   double c21, c22;
-  double Xo, Yo, R;
+  double Xo, Yo, R1, R2;
   CoordFit *modfit;
 
@@ -256,48 +290,41 @@
   modfit = CoordsSetCenter (fit, Xo, Yo);
 
+  /* we do not modify crval1,2: these are kept at the default values */
+
+  // set cdelt1, cdelt2
+  coords[0].cdelt1 = hypot (modfit[0].xfit[1][0], modfit[0].xfit[0][1]);
+  coords[0].cdelt2 = hypot (modfit[0].yfit[1][0], modfit[0].yfit[0][1]);
+  R1 = 1 / coords[0].cdelt1;
+  R2 = 1 / coords[0].cdelt2;
+
   // set pc1_1, pc1_2, pc2_1, pc2_2 (cd1,cd2 = 1.0)
-  coords[0].pc1_1 = modfit[0].xfit[1][0];
-  coords[0].pc1_2 = modfit[0].xfit[0][1];
-  coords[0].pc2_1 = modfit[0].yfit[1][0];
-  coords[0].pc2_2 = modfit[0].yfit[0][1];
+  coords[0].pc1_1 = modfit[0].xfit[1][0] * R1;
+  coords[0].pc1_2 = modfit[0].xfit[0][1] * R2;
+  coords[0].pc2_1 = modfit[0].yfit[1][0] * R1;
+  coords[0].pc2_2 = modfit[0].yfit[0][1] * R2;
 
   // set the polyterm elements 
   if (coords->Npolyterms > 1) {
-    coords[0].polyterms[0][0] = modfit[0].xfit[2][0];
-    coords[0].polyterms[1][0] = modfit[0].xfit[1][1];
-    coords[0].polyterms[2][0] = modfit[0].xfit[0][2];
-
-    coords[0].polyterms[0][1] = modfit[0].yfit[2][0];
-    coords[0].polyterms[1][1] = modfit[0].yfit[1][1];
-    coords[0].polyterms[2][1] = modfit[0].yfit[0][2];
+    coords[0].polyterms[0][0] = modfit[0].xfit[2][0]*R1*R1;
+    coords[0].polyterms[1][0] = modfit[0].xfit[1][1]*R1*R2;
+    coords[0].polyterms[2][0] = modfit[0].xfit[0][2]*R2*R2;
+
+    coords[0].polyterms[0][1] = modfit[0].yfit[2][0]*R1*R1;
+    coords[0].polyterms[1][1] = modfit[0].yfit[1][1]*R1*R2;
+    coords[0].polyterms[2][1] = modfit[0].yfit[0][2]*R2*R2;
   }
 
   // I need to validate Norder
   if (coords->Npolyterms > 2) {
-    coords[0].polyterms[3][0] = modfit[0].xfit[3][0];
-    coords[0].polyterms[4][0] = modfit[0].xfit[2][1];
-    coords[0].polyterms[5][0] = modfit[0].xfit[1][2];
-    coords[0].polyterms[6][0] = modfit[0].xfit[0][3];
-
-    coords[0].polyterms[3][1] = modfit[0].yfit[3][0];
-    coords[0].polyterms[4][1] = modfit[0].yfit[2][1];
-    coords[0].polyterms[5][1] = modfit[0].yfit[1][2];
-    coords[0].polyterms[6][1] = modfit[0].yfit[0][3];
-  }
-
-  /* we do not modify crval1,2: these are kept at the default values */
-
-  /* normalize pc11,etc */
-  c11 = coords[0].pc1_1;
-  c21 = coords[0].pc1_1;
-  c12 = coords[0].pc1_1;
-  c22 = coords[0].pc1_1;
-  coords[0].cdelt1 = coords[0].cdelt2 = sqrt(fabs(c11*c22 - c12*c21));
-  R = 1 / coords[0].cdelt1;
-
-  coords[0].pc1_1  = c11*R;
-  coords[0].pc2_1  = c21*R;
-  coords[0].pc1_2  = c12*R;
-  coords[0].pc2_2  = c22*R;
+    coords[0].polyterms[3][0] = modfit[0].xfit[3][0]*R1*R1*R1;
+    coords[0].polyterms[4][0] = modfit[0].xfit[2][1]*R1*R1*R2;
+    coords[0].polyterms[5][0] = modfit[0].xfit[1][2]*R1*R2*R2;
+    coords[0].polyterms[6][0] = modfit[0].xfit[0][3]*R2*R2*R2;
+
+    coords[0].polyterms[3][1] = modfit[0].yfit[3][0]*R1*R1*R1;
+    coords[0].polyterms[4][1] = modfit[0].yfit[2][1]*R1*R1*R2;
+    coords[0].polyterms[5][1] = modfit[0].yfit[1][2]*R1*R2*R2;
+    coords[0].polyterms[6][1] = modfit[0].yfit[0][3]*R2*R2*R2;
+  }
 
   fit_free (modfit);
Index: /trunk/Ohana/src/relastro/src/load_catalogs.c
===================================================================
--- /trunk/Ohana/src/relastro/src/load_catalogs.c	(revision 16809)
+++ /trunk/Ohana/src/relastro/src/load_catalogs.c	(revision 16810)
@@ -39,6 +39,6 @@
 	for (j = 0; j < catalog[i].Naverage; j++) {
 	  catalog[i].average[j].code = 0;
-	  m = catalog[i].average[j].offset;
-	  for (k = 0; k < catalog[i].average[j].Nm; k++) {
+	  m = catalog[i].average[j].measureOffset;
+	  for (k = 0; k < catalog[i].average[j].Nmeasure; k++) {
 	    catalog[i].measure[m+k].dbFlags = 0;
 	  }
Index: /trunk/Ohana/src/relastro/src/mkpolyterm.c
===================================================================
--- /trunk/Ohana/src/relastro/src/mkpolyterm.c	(revision 16809)
+++ /trunk/Ohana/src/relastro/src/mkpolyterm.c	(revision 16810)
@@ -20,5 +20,5 @@
 
   int i, Nx, Ny;
-  double R, Xo, Yo, dPos;
+  double R, Xo, Yo, dPos, dPosRef;
   double **XdX, **XdY, **YdX, **YdY, **alpha, **beta;
   double **xfit, **yfit;
@@ -51,4 +51,5 @@
      */
     dPos = tol + 1;
+    dPosRef = dPos;
     for (i = 0; (dPos > tol) && (i < 20); i++) {
       // NOTE: order for alpha is: [y][x]
@@ -66,4 +67,10 @@
       Yo -= beta[1][0];
       dPos = hypot(beta[0][0], beta[1][0]);
+      if (i == 0) {
+	dPosRef = dPos;
+      }
+    }
+    if (dPos > dPosRef) {
+      fprintf (stderr, "*** warning : non-convergence in model conversion (mkpolyterm.c;73) *** \n");
     }
     array_free (alpha, 2);
Index: /trunk/Ohana/src/relastro/src/plot_scatter.c
===================================================================
--- /trunk/Ohana/src/relastro/src/plot_scatter.c	(revision 16809)
+++ /trunk/Ohana/src/relastro/src/plot_scatter.c	(revision 16810)
@@ -12,5 +12,5 @@
   for (i = 0; i < Ncatalog; i++) {
     for (j = 0; j < catalog[i].Naverage; j++) {
-      Ntot += catalog[i].average[j].Nm;
+      Ntot += catalog[i].average[j].Nmeasure;
     }
   }
@@ -25,7 +25,7 @@
       /* calculate the average value for a single star */
       if (catalog[i].average[j].code & STAR_BAD) continue;  
-      m = catalog[i].average[j].offset;
+      m = catalog[i].average[j].measureOffset;
 
-      for (k = 0; k < catalog[i].average[j].Nm; k++, m++) {
+      for (k = 0; k < catalog[i].average[j].Nmeasure; k++, m++) {
 	if (catalog[i].measure[m].flags & MEAS_BAD) continue;
 
Index: /trunk/Ohana/src/relastro/src/relastro.c
===================================================================
--- /trunk/Ohana/src/relastro/src/relastro.c	(revision 16809)
+++ /trunk/Ohana/src/relastro/src/relastro.c	(revision 16810)
@@ -64,4 +64,20 @@
     save_catalogs (catalog, Ncatalog);
   } else {
+    // XXX for now, reload all catalogs at once; as memory use gets large, reload one-at-a-time
+
+    // load catalog data from region files : do not subselect
+    catalog = load_catalogs (skylist, &Ncatalog, FALSE);
+    
+    // match measurements with images
+    initImageBins (catalog, Ncatalog);
+    findImages (catalog, Ncatalog);
+
+    // update the detection coordinates using the new image parameters
+    UpdateMeasures (catalog, Ncatalog);
+
+    // write the updated detections to disk
+    save_catalogs (catalog, Ncatalog);
+
+    // save the updated image parameters
     dvo_image_update (&db, VERBOSE);
     dvo_image_unlock (&db); 
Index: /trunk/Ohana/src/relastro/src/setExclusions.c
===================================================================
--- /trunk/Ohana/src/relastro/src/setExclusions.c	(revision 16809)
+++ /trunk/Ohana/src/relastro/src/setExclusions.c	(revision 16810)
@@ -11,6 +11,6 @@
   for (i = 0; i < Ncatalog; i++) {
     for (j = 0; j < catalog[i].Naverage; j++) {
-      m = catalog[i].average[j].offset;
-      for (k = 0; k < catalog[i].average[j].Nm; k++, m++) {
+      m = catalog[i].average[j].measureOffset;
+      for (k = 0; k < catalog[i].average[j].Nmeasure; k++, m++) {
 
 	/* select measurements by photcode */
Index: /trunk/Ohana/src/relphot/src/ImageOps.c
===================================================================
--- /trunk/Ohana/src/relphot/src/ImageOps.c	(revision 16809)
+++ /trunk/Ohana/src/relphot/src/ImageOps.c	(revision 16810)
@@ -24,6 +24,6 @@
 
   for (i = 0; i < Nimage; i++) {
-    start[i] = image[i].tzero - MAX(0.05*image[i].trate*image[i].NY, 1);
-    stop[i]  = image[i].tzero + MAX(1.05*image[i].trate*image[i].NY, 1);
+    start[i] = image[i].tzero - MAX(0.01*image[i].trate*image[i].NY, 1);
+    stop[i]  = image[i].tzero + MAX(1.01*image[i].trate*image[i].NY, 1);
   }
 }
Index: /trunk/Ohana/src/relphot/src/MosaicOps.c
===================================================================
--- /trunk/Ohana/src/relphot/src/MosaicOps.c	(revision 16809)
+++ /trunk/Ohana/src/relphot/src/MosaicOps.c	(revision 16810)
@@ -41,6 +41,6 @@
 
     /* set image time range */
-    start = image[i].tzero - MAX(0.05*image[i].trate*image[i].NY, 1);
-    stop  = image[i].tzero + MAX(1.05*image[i].trate*image[i].NY, 1);
+    start = image[i].tzero - MAX(0.01*image[i].trate*image[i].NY, 1);
+    stop  = image[i].tzero + MAX(1.01*image[i].trate*image[i].NY, 1);
 
     /* find existing mosaic with this time range */
Index: /trunk/Ohana/src/relphot/src/StarOps.c
===================================================================
--- /trunk/Ohana/src/relphot/src/StarOps.c	(revision 16809)
+++ /trunk/Ohana/src/relphot/src/StarOps.c	(revision 16810)
@@ -12,5 +12,5 @@
   for (i = 0; i < Ncatalog; i++) {
     for (j = 0; j < catalog[i].Naverage; j++) {
-      Nmax = MAX (Nmax, catalog[i].average[j].Nm);
+      Nmax = MAX (Nmax, catalog[i].average[j].Nmeasure);
     }
   }
@@ -43,8 +43,8 @@
       /* calculate the average value for a single star */
       if (catalog[i].average[j].code & STAR_BAD) continue;  
-      m = catalog[i].average[j].offset;
+      m = catalog[i].average[j].measureOffset;
 
       N = 0;
-      for (k = 0; k < catalog[i].average[j].Nm; k++, m++) {
+      for (k = 0; k < catalog[i].average[j].Nmeasure; k++, m++) {
 	if (catalog[i].measure[m].dbFlags & MEAS_BAD) continue;
 	// XXX allow REF stars (no Image Entry) to be included in the calculation this
@@ -94,5 +94,5 @@
   for (i = 0; i < Ncatalog; i++) {
     for (j = 0; j < catalog[i].Naverage; j++) {
-      Nmax = MAX (Nmax, catalog[i].average[j].Nm);
+      Nmax = MAX (Nmax, catalog[i].average[j].Nmeasure);
     }
   }
@@ -107,6 +107,6 @@
 
       N = 0;
-      m = catalog[i].average[j].offset;
-      for (k = 0; k < catalog[i].average[j].Nm; k++, m++) {
+      m = catalog[i].average[j].measureOffset;
+      for (k = 0; k < catalog[i].average[j].Nmeasure; k++, m++) {
 	if (catalog[i].measure[m].dbFlags & MEAS_BAD) continue;
 	// XXX allow REF stars (no Image Entry) to be included in the calculation this
@@ -158,6 +158,6 @@
     for (j = 0; j < catalog[i].Naverage; j++) {
 
-      m = catalog[i].average[j].offset;
-      for (k = 0; k < catalog[i].average[j].Nm; k++, m++) {
+      m = catalog[i].average[j].measureOffset;
+      for (k = 0; k < catalog[i].average[j].Nmeasure; k++, m++) {
 	if (catalog[i].measure[m].dbFlags & MEAS_BAD) continue;
 	Mcal  = getMcal  (m, i);
@@ -247,5 +247,5 @@
   for (i = 0; i < Ncatalog; i++) {
     for (j = 0; j < catalog[i].Naverage; j++) {
-      Nmax = MAX (Nmax, catalog[i].average[j].Nm);
+      Nmax = MAX (Nmax, catalog[i].average[j].Nmeasure);
     }
   }
@@ -270,7 +270,7 @@
 
       /* accumulate list of valid measurements */
-      m = catalog[i].average[j].offset;
+      m = catalog[i].average[j].measureOffset;
       N = 0;
-      for (k = 0; k < catalog[i].average[j].Nm; k++, m++) {
+      for (k = 0; k < catalog[i].average[j].Nmeasure; k++, m++) {
 	/* if (catalog[i].measure[m].dbFlags & MEAS_BAD) continue; */
 	Mcal  = getMcal  (m, i);
@@ -305,7 +305,7 @@
       image_bad = IMAGE_BAD;
       IMAGE_BAD = ID_IMAGE_NOCAL;
-      m = catalog[i].average[j].offset;
+      m = catalog[i].average[j].measureOffset;
       N = 0;
-      for (k = 0; k < catalog[i].average[j].Nm; k++, m++) {
+      for (k = 0; k < catalog[i].average[j].Nmeasure; k++, m++) {
 	/* if (catalog[i].measure[m].dbFlags & MEAS_BAD) continue; */
 	Mcal  = getMcal  (m, i);
@@ -362,8 +362,8 @@
       /* calculate the average value for a single star */
       if (catalog[i].average[j].code & STAR_BAD) continue;  
-      m = catalog[i].average[j].offset;
+      m = catalog[i].average[j].measureOffset;
 
       N = 0;
-      for (k = 0; k < catalog[i].average[j].Nm; k++, m++) {
+      for (k = 0; k < catalog[i].average[j].Nmeasure; k++, m++) {
 	Mcal = getMcal  (m, i);
 	if (isnan(Mcal)) continue;
Index: /trunk/Ohana/src/relphot/src/bcatalog.c
===================================================================
--- /trunk/Ohana/src/relphot/src/bcatalog.c	(revision 16809)
+++ /trunk/Ohana/src/relphot/src/bcatalog.c	(revision 16810)
@@ -22,9 +22,9 @@
   /* exclude stars not in range or with too few measurements */
   for (i = 0; i < catalog[0].Naverage; i++) {
-    // if (catalog[0].average[i].Nm < 2) continue; 
+    // if (catalog[0].average[i].Nmeasure < 2) continue; 
 
     /* start with all stars good */
     subcatalog[0].average[Naverage] = catalog[0].average[i];
-    subcatalog[0].average[Naverage].offset = Nmeasure;
+    subcatalog[0].average[Naverage].measureOffset = Nmeasure;
     for (j = 0; j < PhotNsec; j++) {
       subcatalog[0].secfilt[PhotNsec*Naverage+j] = catalog[0].secfilt[PhotNsec*i+j];
@@ -39,7 +39,7 @@
 
     Nm = 0;
-    for (j = 0; j < catalog[0].average[i].Nm; j++) {
+    for (j = 0; j < catalog[0].average[i].Nmeasure; j++) {
 
-      offset = catalog[0].average[i].offset + j;
+      offset = catalog[0].average[i].measureOffset + j;
 
       /* select measurements by photcode */
@@ -96,5 +96,5 @@
     }
     # endif
-    subcatalog[0].average[Naverage].Nm = Nm;
+    subcatalog[0].average[Naverage].Nmeasure = Nm;
     Naverage ++;
     if (Naverage == NAVERAGE) {
Index: /trunk/Ohana/src/relphot/src/plot_scatter.c
===================================================================
--- /trunk/Ohana/src/relphot/src/plot_scatter.c	(revision 16809)
+++ /trunk/Ohana/src/relphot/src/plot_scatter.c	(revision 16810)
@@ -11,5 +11,5 @@
   for (i = 0; i < Ncatalog; i++) {
     for (j = 0; j < catalog[i].Naverage; j++) {
-      Ntot += catalog[i].average[j].Nm;
+      Ntot += catalog[i].average[j].Nmeasure;
     }
   }
@@ -24,7 +24,7 @@
       /* calculate the average value for a single star */
       if (catalog[i].average[j].code & STAR_BAD) continue;  
-      m = catalog[i].average[j].offset;
+      m = catalog[i].average[j].measureOffset;
 
-      for (k = 0; k < catalog[i].average[j].Nm; k++, m++) {
+      for (k = 0; k < catalog[i].average[j].Nmeasure; k++, m++) {
 	if (catalog[i].measure[m].dbFlags & MEAS_BAD) continue;
 	Mcal = getMcal  (m, i);
Index: /trunk/Ohana/src/relphot/src/setExclusions.c
===================================================================
--- /trunk/Ohana/src/relphot/src/setExclusions.c	(revision 16809)
+++ /trunk/Ohana/src/relphot/src/setExclusions.c	(revision 16810)
@@ -10,6 +10,6 @@
   for (i = 0; i < Ncatalog; i++) {
     for (j = 0; j < catalog[i].Naverage; j++) {
-      m = catalog[i].average[j].offset;
-      for (k = 0; k < catalog[i].average[j].Nm; k++, m++) {
+      m = catalog[i].average[j].measureOffset;
+      for (k = 0; k < catalog[i].average[j].Nmeasure; k++, m++) {
 
 	/* select measurements by photcode */
Index: /trunk/Ohana/src/relphot/src/setMrelFinal.c
===================================================================
--- /trunk/Ohana/src/relphot/src/setMrelFinal.c	(revision 16809)
+++ /trunk/Ohana/src/relphot/src/setMrelFinal.c	(revision 16810)
@@ -13,6 +13,6 @@
       catalog[0].secfilt[PhotNsec*i+PhotSec].Xm = NAN_S_SHORT;
 
-      m = catalog[0].average[i].offset;
-      for (j = 0; j < catalog[0].average[i].Nm; j++, m++) {
+      m = catalog[0].average[i].measureOffset;
+      for (j = 0; j < catalog[0].average[i].Nmeasure; j++, m++) {
 	
 	/* select measurements by photcode */
@@ -56,6 +56,6 @@
     catalog[0].average[i].code &= ~ID_STAR_FEW;
     catalog[0].average[i].code &= ~ID_STAR_POOR;
-    m = catalog[0].average[i].offset;
-    for (j = 0; j < catalog[0].average[i].Nm; j++, m++) {
+    m = catalog[0].average[i].measureOffset;
+    for (j = 0; j < catalog[0].average[i].Nmeasure; j++, m++) {
       catalog[0].measure[m].dbFlags &= ~ID_MEAS_NOCAL;
     }
@@ -80,9 +80,9 @@
   /* mark measures which should be ignored on second pass */
   for (i = 0; i < catalog[0].Naverage; i++) {
-    Ntot += catalog[0].average[i].Nm;
+    Ntot += catalog[0].average[i].Nmeasure;
     if (catalog[0].found[i]) continue;
 
-    m = catalog[0].average[i].offset;
-    for (k = 0; k < catalog[0].average[i].Nm; k++, m++) {
+    m = catalog[0].average[i].measureOffset;
+    for (k = 0; k < catalog[0].average[i].Nmeasure; k++, m++) {
       Ntry++;
 
Index: /trunk/Ohana/src/uniphot/src/update_catalog.c
===================================================================
--- /trunk/Ohana/src/uniphot/src/update_catalog.c	(revision 16809)
+++ /trunk/Ohana/src/uniphot/src/update_catalog.c	(revision 16810)
@@ -17,6 +17,6 @@
     }
 
-    m = catalog[0].average[i].offset;
-    for (j = 0; j < catalog[0].average[i].Nm; j++, m++) {
+    m = catalog[0].average[i].measureOffset;
+    for (j = 0; j < catalog[0].average[i].Nmeasure; j++, m++) {
       code = GetPhotcodebyCode (catalog[0].measure[m].photcode);
       if (code == NULL) continue;
