Index: /branches/eam_branches/ipp-ppmerge-20241229/Nebulous/bin/whichnode
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/Nebulous/bin/whichnode	(revision 42802)
+++ /branches/eam_branches/ipp-ppmerge-20241229/Nebulous/bin/whichnode	(revision 42803)
@@ -1,3 +1,3 @@
-#!/bin/env perl
+#!/usr/bin/env perl
 
 # This script is a temporary "solution" to allow a client to determine whether
Index: /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/addstar/src/grefstars.c
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/addstar/src/grefstars.c	(revision 42802)
+++ /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/addstar/src/grefstars.c	(revision 42803)
@@ -41,4 +41,8 @@
     catalog->average[N].R = ohana_normalize_angle (catalog->average[N].R);
 
+    catalog->measure[N].McalPSF  = 0.0;
+    catalog->measure[N].McalAPER = 0.0;
+    catalog->measure[N].dMcal    = 0.0;
+       
     catalog->measure[N].R = catalog->average[N].R;
     catalog->measure[N].D = catalog->average[N].D;
Index: /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libautocode/Makefile.Targets
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libautocode/Makefile.Targets	(revision 42802)
+++ /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libautocode/Makefile.Targets	(revision 42803)
@@ -18,4 +18,6 @@
 $(ASRC)/average-ps1-sim.$(ARCH).o \
 $(ASRC)/average-ps1-ref.$(ARCH).o \
+$(ASRC)/average-ps1-ref-v2.$(ARCH).o \
+$(ASRC)/average-ps1-ref-v3.$(ARCH).o \
 $(ASRC)/secfilt.$(ARCH).o \
 $(ASRC)/secfilt-loneos.$(ARCH).o \
@@ -34,4 +36,6 @@
 $(ASRC)/secfilt-ps1-sim.$(ARCH).o \
 $(ASRC)/secfilt-ps1-ref.$(ARCH).o \
+$(ASRC)/secfilt-ps1-ref-v2.$(ARCH).o \
+$(ASRC)/secfilt-ps1-ref-v3.$(ARCH).o \
 $(ASRC)/measure.$(ARCH).o \
 $(ASRC)/measure-loneos.$(ARCH).o \
@@ -50,4 +54,6 @@
 $(ASRC)/measure-ps1-sim.$(ARCH).o \
 $(ASRC)/measure-ps1-ref.$(ARCH).o \
+$(ASRC)/measure-ps1-ref-v2.$(ARCH).o \
+$(ASRC)/measure-ps1-ref-v3.$(ARCH).o \
 $(ASRC)/lensing.$(ARCH).o \
 $(ASRC)/lensing-ps1-v5-r0.$(ARCH).o \
@@ -86,4 +92,6 @@
 $(ASRC)/photcode-ps1-v5-ld.$(ARCH).o \
 $(ASRC)/photcode-ps1-ref.$(ARCH).o \
+$(ASRC)/photcode-ps1-ref-v2.$(ARCH).o \
+$(ASRC)/photcode-ps1-ref-v3.$(ARCH).o \
 $(ASRC)/image-loneos.$(ARCH).o \
 $(ASRC)/image-elixir.$(ARCH).o \
@@ -102,4 +110,6 @@
 $(ASRC)/image-ps1-sim.$(ARCH).o \
 $(ASRC)/image-ps1-ref.$(ARCH).o \
+$(ASRC)/image-ps1-ref-v2.$(ARCH).o \
+$(ASRC)/image-ps1-ref-v3.$(ARCH).o \
 $(ASRC)/regimage.$(ARCH).o \
 $(ASRC)/detreg.$(ARCH).o \
@@ -149,4 +159,6 @@
 $(AINC)/average-ps1-sim.h \
 $(AINC)/average-ps1-ref.h \
+$(AINC)/average-ps1-ref-v2.h \
+$(AINC)/average-ps1-ref-v3.h \
 $(AINC)/secfilt.h \
 $(AINC)/secfilt-loneos.h \
@@ -165,4 +177,6 @@
 $(AINC)/secfilt-ps1-sim.h \
 $(AINC)/secfilt-ps1-ref.h \
+$(AINC)/secfilt-ps1-ref-v2.h \
+$(AINC)/secfilt-ps1-ref-v3.h \
 $(AINC)/measure.h \
 $(AINC)/measure-loneos.h \
@@ -181,4 +195,6 @@
 $(AINC)/measure-ps1-sim.h \
 $(AINC)/measure-ps1-ref.h \
+$(AINC)/measure-ps1-ref-v2.h \
+$(AINC)/measure-ps1-ref-v3.h \
 $(AINC)/lensing.h \
 $(AINC)/lensing-ps1-v5-r0.h \
@@ -217,4 +233,6 @@
 $(AINC)/photcode-ps1-v5-ld.h \
 $(AINC)/photcode-ps1-ref.h \
+$(AINC)/photcode-ps1-ref-v2.h \
+$(AINC)/photcode-ps1-ref-v3.h \
 $(AINC)/image-loneos.h \
 $(AINC)/image-elixir.h \
@@ -233,4 +251,6 @@
 $(AINC)/image-ps1-sim.h \
 $(AINC)/image-ps1-ref.h \
+$(AINC)/image-ps1-ref-v2.h \
+$(AINC)/image-ps1-ref-v3.h \
 $(AINC)/regimage.h \
 $(AINC)/detreg.h \
Index: /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libautocode/def/average-ps1-ref-v2.d
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libautocode/def/average-ps1-ref-v2.d	(revision 42803)
+++ /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libautocode/def/average-ps1-ref-v2.d	(revision 42803)
@@ -0,0 +1,35 @@
+STRUCT       Average_PS1_REF_V2
+EXTNAME      DVO_AVERAGE_PS1_REF_V2
+TYPE         BINTABLE
+SIZE         72
+DESCRIPTION  DVO Average Object Table
+
+# elements of data structure / FITS table
+
+FIELD R,              RA,          double,          RA,                	       	  decimal degrees 
+FIELD D,              DEC,         double,          DEC,               	       	  decimal degrees 
+FIELD dR,             RA_ERR,      float,           RA error                      arcsec
+FIELD dD,             DEC_ERR,     float,           DEC error                     arcsec
+
+FIELD uR,             U_RA,        float,           RA*cos(D) proper-motion,      arcsec/year
+FIELD uD,             U_DEC,       float,           DEC proper-motion,            arcsec/year
+FIELD duR,            V_RA_ERR,    float,           RA*cos(D) p-m error,          arcsec/year
+FIELD duD,            V_DEC_ERR,   float,           DEC p-m error,                arcsec/year
+FIELD P,              PAR,         float,           parallax,                     arcsec
+FIELD dP,             PAR_ERR,     float,           parallax error,               arcsec
+
+FIELD measureOffset,  OFF_MEASURE, uint32_t,   	    offset to first psf measurement
+FIELD missingOffset,  OFF_MISSING, uint32_t,   	    offset to first missing obs
+
+# objID + catID gives a unique ID for all objects in the database
+FIELD objID,          OBJ_ID,      unsigned int,    unique ID for object in table
+FIELD catID,          CAT_ID,      unsigned int,    unique ID for table in which object was first realized
+
+# this limits us to a max of 64k measurements per object
+FIELD Nmeasure,       NMEASURE,    unsigned short,  number of psf measurements
+FIELD Nmissing,       NMISSING,    unsigned short,  number of missings
+FIELD pad,            PAD,         char[4],         padding
+
+# 2 double, 8 float, 2 int, 2 short, 4 char, 2 unit32_t
+# 2*8 +     8*4 +    2*4 +  2*2 +    4*1 +   2*4       = 72
+
Index: /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libautocode/def/average-ps1-ref-v3.d
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libautocode/def/average-ps1-ref-v3.d	(revision 42803)
+++ /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libautocode/def/average-ps1-ref-v3.d	(revision 42803)
@@ -0,0 +1,37 @@
+STRUCT       Average_PS1_REF_V3
+EXTNAME      DVO_AVERAGE_PS1_REF_V3
+TYPE         BINTABLE
+SIZE         80
+DESCRIPTION  DVO Average Object Table
+
+# elements of data structure / FITS table
+
+FIELD R,              RA,          double,          RA,                	       	  decimal degrees 
+FIELD D,              DEC,         double,          DEC,               	       	  decimal degrees 
+FIELD dR,             RA_ERR,      float,           RA error                      arcsec
+FIELD dD,             DEC_ERR,     float,           DEC error                     arcsec
+
+FIELD uR,             U_RA,        float,           RA*cos(D) proper-motion,      arcsec/year
+FIELD uD,             U_DEC,       float,           DEC proper-motion,            arcsec/year
+FIELD duR,            V_RA_ERR,    float,           RA*cos(D) p-m error,          arcsec/year
+FIELD duD,            V_DEC_ERR,   float,           DEC p-m error,                arcsec/year
+FIELD P,              PAR,         float,           parallax,                     arcsec
+FIELD dP,             PAR_ERR,     float,           parallax error,               arcsec
+
+FIELD measureOffset,  OFF_MEASURE, uint32_t,   	    offset to first psf measurement
+FIELD missingOffset,  OFF_MISSING, uint32_t,   	    offset to first missing obs
+FIELD lensingOffset,  OFF_LENSING, uint32_t,   	    offset to first lensing obs
+FIELD flags,          FLAGS,       uint32_t,        average object flags (star; ghost; etc)
+
+# objID + catID gives a unique ID for all objects in the database
+FIELD objID,          OBJ_ID,      unsigned int,    unique ID for object in table
+FIELD catID,          CAT_ID,      unsigned int,    unique ID for table in which object was first realized
+
+# this limits us to a max of 64k measurements per object
+FIELD Nmeasure,       NMEASURE,    unsigned short,  number of psf measurements
+FIELD Nmissing,       NMISSING,    unsigned short,  number of missings
+FIELD pad,            PAD,         char[4],         padding
+
+# 2 double, 8 float, 2 int, 2 short, 4 char, 2 unit32_t
+# 2*8 +     8*4 +    2*4 +  2*2 +    4*1 +   2*4       = 72
+
Index: /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libautocode/def/image-ps1-ref-v2.d
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libautocode/def/image-ps1-ref-v2.d	(revision 42803)
+++ /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libautocode/def/image-ps1-ref-v2.d	(revision 42803)
@@ -0,0 +1,77 @@
+STRUCT       Image_PS1_REF_V2
+EXTNAME      DVO_IMAGE_PS1_REF_V2
+TYPE         BINTABLE
+SIZE         344
+DESCRIPTION  DVO Image Table 
+
+# elements of the image structure
+
+SUBSTRUCT coords,           COORDS,               CoordsDisk,    astrometric data
+SUBFIELD  crval1,           CRVAL1,               double,   	 coordinate at reference pixel
+SUBFIELD  crval2,           CRVAL2,               double,  	 coordinate at reference pixel
+SUBFIELD  crpix1,           CRPIX1,               float,   	 coordinate of reference pixel
+SUBFIELD  crpix2,           CRPIX2,               float,   	 coordinate of reference pixel
+SUBFIELD  cdelt1,           CDELT1,               float,   	 degrees per pixel
+SUBFIELD  cdelt2,           CDELT2,               float,    	 degrees per pixel
+SUBFIELD  pc1_1,            PC1_1,                float,    	 rotation matrix
+SUBFIELD  pc1_2,            PC1_2,                float,    	 rotation matrix
+SUBFIELD  pc2_1,            PC2_1,                float,    	 rotation matrix
+SUBFIELD  pc2_2,            PC2_2,                float,    	 rotation matrix
+SUBFIELD  polyterms,        POLYTERMS,            float[7][2],	 higher order warping terms
+SUBFIELD  ctype,            CTYPE,                char[15],      coordinate type
+SUBFIELD  Npolyterms,       NPOLYTERMS,           char,     	 order of polynomial
+# 120 bytes
+# 2 double, 8 float, 15 char, 1 char
+# 2*8 +     8*4 +    15*1 +   1*1       = 72
+
+FIELD 	  tzero,            TZERO,                e_time,         readout time (row 0)
+FIELD 	  nstar,            NSTAR,                unsigned int,   number of stars on image
+FIELD 	  secz,             SECZ,                 float,      	  airmass,                   mag
+FIELD 	  NX,               NX,                   unsigned short, image width
+FIELD 	  NY,               NY,                   unsigned short, image height
+FIELD 	  apmifit,          APMIFIT,              float,      	  aperture correction,       mag
+FIELD 	  dapmifit,         DAPMIFIT,             float,      	  apmifit error,             mag
+FIELD 	  Mcal,             MCAL,                 float,      	  calibration mag,           mag
+FIELD 	  dMcal,            DMCAL,                float,      	  error on Mcal,             mag
+FIELD 	  Xm,               XM,                   short,      	  image chisq,               10*log(value)
+FIELD 	  photcode,         PHOTCODE,             short,      	  identifier for CCD,
+FIELD 	  exptime,          EXPTIME,              float,          exposure time,             seconds
+FIELD     sidtime,          ST,			  float,          sidereal time of exposure
+FIELD     latitude,         LAT,		  float,          observatory latitude,      degrees
+# 40 bytes
+# 1 int, 8 float, 4 short
+# 1*4 +  8*4 +    4*2    = 44
+
+# should we define the max length of name as a macro?
+FIELD 	  name,             NAME,                 char[121],      name of original image 
+FIELD 	  detection_limit,  DETECTION_LIMIT,      unsigned char,  detection limit,           10*mag
+FIELD 	  saturation_limit, SATURATION_LIMIT,     unsigned char,  saturation limit,          10*mag
+FIELD 	  cerror,           CERROR,               unsigned char,  astrometric error,         50*arcsec
+FIELD 	  fwhm_x,           FWHM_X,               unsigned char,  PSF x width,               25*arcsec
+FIELD 	  fwhm_y,           FWHM_Y,               unsigned char,  PSF y width,               25*arcsec
+FIELD 	  trate,            TRATE,                unsigned char,  scan rate,                 100 usec/pixel
+FIELD 	  ccdnum,           CCDNUM,               unsigned char,  CCD ID number
+FIELD 	  flags,            FLAGS,                unsigned int,   image quality flags
+FIELD 	  imageID,          IMAGE_ID,             unsigned int,   internal image ID
+FIELD 	  parentID,         PARENT_ID,            unsigned int,   associated ref image
+FIELD 	  externID,         EXTERN_ID,            unsigned int,   external image ID
+FIELD 	  sourceID,         SOURCE_ID,            unsigned short, analysis source ID
+# 48 bytes 
+
+# 40 bytes
+FIELD 	  nLinkAstrom,      NLINK_ASTROM,         short,      	  mean number of matched measurements for astrometry
+FIELD 	  nLinkPhotom,      NLINK_PHOTOM,         short,      	  mean number of matched measurements for astrometry
+FIELD 	  dummy3,           DUMMY3,               short,      	  place holder for byte boundaries
+
+FIELD 	  dXpixSys,         XPIX_SYS_ERR,         float,      	  systematic astrometry error in X
+FIELD 	  dYpixSys,         YPIX_SYS_ERR,         float,      	  systematic astrometry error in Y
+
+FIELD 	  dMagSys,          MAG_SYS_ERR,          float,      	  systematic photometry error
+FIELD 	  nFitAstrom,       N_FIT_ASTROM,         short,      	  number of stars used for astrometry cal
+FIELD 	  nFitPhotom,       N_FIT_PHOTOM,         short,      	  number of stars used for photometry cal
+
+FIELD 	  photom_map_id,    PHOTOM_MAP_ID,        unsigned int,   reference to 2D zero point map
+FIELD 	  astrom_map_id,    ASTROM_MAP_ID,        unsigned int,   reference to 2D astrometry map
+# nFitPhotom lands on the old location of Mxxxx, which was used to mean nFitPhotom in some cases
+
+
Index: /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libautocode/def/image-ps1-ref-v3.d
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libautocode/def/image-ps1-ref-v3.d	(revision 42803)
+++ /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libautocode/def/image-ps1-ref-v3.d	(revision 42803)
@@ -0,0 +1,77 @@
+STRUCT       Image_PS1_REF_V3
+EXTNAME      DVO_IMAGE_PS1_REF_V3
+TYPE         BINTABLE
+SIZE         344
+DESCRIPTION  DVO Image Table 
+
+# elements of the image structure
+
+SUBSTRUCT coords,           COORDS,               CoordsDisk,    astrometric data
+SUBFIELD  crval1,           CRVAL1,               double,   	 coordinate at reference pixel
+SUBFIELD  crval2,           CRVAL2,               double,  	 coordinate at reference pixel
+SUBFIELD  crpix1,           CRPIX1,               float,   	 coordinate of reference pixel
+SUBFIELD  crpix2,           CRPIX2,               float,   	 coordinate of reference pixel
+SUBFIELD  cdelt1,           CDELT1,               float,   	 degrees per pixel
+SUBFIELD  cdelt2,           CDELT2,               float,    	 degrees per pixel
+SUBFIELD  pc1_1,            PC1_1,                float,    	 rotation matrix
+SUBFIELD  pc1_2,            PC1_2,                float,    	 rotation matrix
+SUBFIELD  pc2_1,            PC2_1,                float,    	 rotation matrix
+SUBFIELD  pc2_2,            PC2_2,                float,    	 rotation matrix
+SUBFIELD  polyterms,        POLYTERMS,            float[7][2],	 higher order warping terms
+SUBFIELD  ctype,            CTYPE,                char[15],      coordinate type
+SUBFIELD  Npolyterms,       NPOLYTERMS,           char,     	 order of polynomial
+# 120 bytes
+# 2 double, 8 float, 15 char, 1 char
+# 2*8 +     8*4 +    15*1 +   1*1       = 72
+
+FIELD 	  tzero,            TZERO,                e_time,         readout time (row 0)
+FIELD 	  nstar,            NSTAR,                unsigned int,   number of stars on image
+FIELD 	  secz,             SECZ,                 float,      	  airmass,                   mag
+FIELD 	  NX,               NX,                   unsigned short, image width
+FIELD 	  NY,               NY,                   unsigned short, image height
+FIELD 	  apmifit,          APMIFIT,              float,      	  aperture correction,       mag
+FIELD 	  dapmifit,         DAPMIFIT,             float,      	  apmifit error,             mag
+FIELD 	  Mcal,             MCAL,                 float,      	  calibration mag,           mag
+FIELD 	  dMcal,            DMCAL,                float,      	  error on Mcal,             mag
+FIELD 	  Xm,               XM,                   short,      	  image chisq,               10*log(value)
+FIELD 	  photcode,         PHOTCODE,             short,      	  identifier for CCD,
+FIELD 	  exptime,          EXPTIME,              float,          exposure time,             seconds
+FIELD     sidtime,          ST,			  float,          sidereal time of exposure
+FIELD     latitude,         LAT,		  float,          observatory latitude,      degrees
+# 40 bytes
+# 1 int, 8 float, 4 short
+# 1*4 +  8*4 +    4*2    = 44
+
+# should we define the max length of name as a macro?
+FIELD 	  name,             NAME,                 char[121],      name of original image 
+FIELD 	  detection_limit,  DETECTION_LIMIT,      unsigned char,  detection limit,           10*mag
+FIELD 	  saturation_limit, SATURATION_LIMIT,     unsigned char,  saturation limit,          10*mag
+FIELD 	  cerror,           CERROR,               unsigned char,  astrometric error,         50*arcsec
+FIELD 	  fwhm_x,           FWHM_X,               unsigned char,  PSF x width,               25*arcsec
+FIELD 	  fwhm_y,           FWHM_Y,               unsigned char,  PSF y width,               25*arcsec
+FIELD 	  trate,            TRATE,                unsigned char,  scan rate,                 100 usec/pixel
+FIELD 	  ccdnum,           CCDNUM,               unsigned char,  CCD ID number
+FIELD 	  flags,            FLAGS,                unsigned int,   image quality flags
+FIELD 	  imageID,          IMAGE_ID,             unsigned int,   internal image ID
+FIELD 	  parentID,         PARENT_ID,            unsigned int,   associated ref image
+FIELD 	  externID,         EXTERN_ID,            unsigned int,   external image ID
+FIELD 	  sourceID,         SOURCE_ID,            unsigned short, analysis source ID
+# 48 bytes 
+
+# 40 bytes
+FIELD 	  nLinkAstrom,      NLINK_ASTROM,         short,      	  mean number of matched measurements for astrometry
+FIELD 	  nLinkPhotom,      NLINK_PHOTOM,         short,      	  mean number of matched measurements for astrometry
+FIELD 	  dummy3,           DUMMY3,               short,      	  place holder for byte boundaries
+
+FIELD 	  dXpixSys,         XPIX_SYS_ERR,         float,      	  systematic astrometry error in X
+FIELD 	  dYpixSys,         YPIX_SYS_ERR,         float,      	  systematic astrometry error in Y
+
+FIELD 	  dMagSys,          MAG_SYS_ERR,          float,      	  systematic photometry error
+FIELD 	  nFitAstrom,       N_FIT_ASTROM,         short,      	  number of stars used for astrometry cal
+FIELD 	  nFitPhotom,       N_FIT_PHOTOM,         short,      	  number of stars used for photometry cal
+
+FIELD 	  photom_map_id,    PHOTOM_MAP_ID,        unsigned int,   reference to 2D zero point map
+FIELD 	  astrom_map_id,    ASTROM_MAP_ID,        unsigned int,   reference to 2D astrometry map
+# nFitPhotom lands on the old location of Mxxxx, which was used to mean nFitPhotom in some cases
+
+
Index: /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libautocode/def/measure-ps1-ref-v2.d
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libautocode/def/measure-ps1-ref-v2.d	(revision 42803)
+++ /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libautocode/def/measure-ps1-ref-v2.d	(revision 42803)
@@ -0,0 +1,37 @@
+STRUCT       Measure_PS1_REF_V2
+EXTNAME      DVO_MEASURE_PS1_REF_V2
+TYPE         BINTABLE
+SIZE         48
+DESCRIPTION  DVO Detection Measurement Table 
+
+# this format is a stripped-down version of ps1-v1, appropriate to a static reference database
+# we make the trade-off towards small data volume vs detailed metadata
+
+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
+FIELD Mcal,           M_CAL,        float,          image cal mag,                mag
+FIELD dMcal,          MAG_CAL_ERR,  float,          systematic calibration error, mag
+FIELD dt,             M_TIME,       float,          exposure time,                2.5*log(exptime)
+
+FIELD t,              TIME,         int,   	    time in seconds (UNIX)
+FIELD averef,         AVE_REF,      unsigned int,   reference to average entry      
+
+# might be able to drop these:
+FIELD objID,          OBJ_ID,       unsigned int,   unique ID for object in table
+FIELD catID,          CAT_ID,       unsigned int,   unique ID for table in which object was first realized
+
+FIELD photcode,       PHOTCODE,     unsigned short, photcode
+
+FIELD pad,            PAD,          char[2],        padding
+
+# 7 x float 
+# 4 x int
+# 2 + 2
+# = 48 bytes
+
+# 7 float, 4 int, 1 short, 2 char
+# 7*4 +    4*4 +  1*2 +    2*1   = 48
+
+
Index: /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libautocode/def/measure-ps1-ref-v3.d
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libautocode/def/measure-ps1-ref-v3.d	(revision 42803)
+++ /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libautocode/def/measure-ps1-ref-v3.d	(revision 42803)
@@ -0,0 +1,40 @@
+STRUCT       Measure_PS1_REF_V3
+EXTNAME      DVO_MEASURE_PS1_REF_V3
+TYPE         BINTABLE
+SIZE         56
+DESCRIPTION  DVO Detection Measurement Table 
+
+# this format is a stripped-down version of ps1-v1, appropriate to a static reference database
+# we make the trade-off towards small data volume vs detailed metadata
+
+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
+FIELD Mcal,           M_CAL,        float,          image cal mag,                mag
+FIELD dMcal,          MAG_CAL_ERR,  float,          systematic calibration error, mag
+FIELD dt,             M_TIME,       float,          exposure time,                2.5*log(exptime)
+
+FIELD t,              TIME,         int,   	    time in seconds (UNIX)
+FIELD averef,         AVE_REF,      unsigned int,   reference to average entry      
+
+# might be able to drop these:
+FIELD objID,          OBJ_ID,       unsigned int,   unique ID for object in table
+FIELD catID,          CAT_ID,       unsigned int,   unique ID for table in which object was first realized
+FIELD dbFlags,        DB_FLAGS,     unsigned int,   flags supplied by analysis in database
+FIELD photFlags,      PHOT_FLAGS,   unsigned int,   flags supplied by photometry program
+
+
+FIELD photcode,       PHOTCODE,     unsigned short, photcode
+
+FIELD pad,            PAD,          char[2],        padding
+
+# 7 x float 
+# 4 x int
+# 2 + 2
+# = 48 bytes
+
+# 7 float, 4 int, 1 short, 2 char
+# 7*4 +    4*4 +  1*2 +    2*1   = 48
+
+
Index: /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libautocode/def/photcode-ps1-ref-v2.d
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libautocode/def/photcode-ps1-ref-v2.d	(revision 42803)
+++ /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libautocode/def/photcode-ps1-ref-v2.d	(revision 42803)
@@ -0,0 +1,33 @@
+STRUCT       PhotCode_PS1_REF_V2
+EXTNAME      DVO_PHOTCODE_PS1_REF_V2
+TYPE         BINTABLE
+SIZE         104
+DESCRIPTION  DVO Photcode Description Table 
+
+# elements of data structure / FITS table
+FIELD  code,         	  CODE,          	 unsigned short, code number (stored in Measure.source) 
+FIELD  name,         	  NAME,          	 char[32],       name for filter combination 
+FIELD  type,         	  TYPE,          	 char,           PRI/SEC/DEP/REF 
+FIELD  dummy,        	  DUMMY,         	 char[3],        padding
+FIELD  C,            	  C_LAM,         	 short,          primary phot calibration terms (millimags) 
+FIELD  dC,           	  C_LAM_ERR,     	 short,          primary phot calibration terms (millimags) 
+FIELD  dX,           	  X_ERR,         	 short,          primary phot calibration terms (millimags) 
+FIELD  K,            	  K,             	 float,          secondary phot calibration terms (millimags) 
+FIELD  c1,           	  C1,            	 int,            color is average.M[c1] - average.M[c2] 
+FIELD  c2,           	  C2,            	 int,            color is average.M[c1] - average.M[c2] 
+FIELD  equiv,        	  EQUIV,         	 int,            this dependent filter is equivalent to equiv PRI/SEC
+FIELD  Nc,           	  NC,            	 int,            number of color terms 
+FIELD  X,            	  X,             	 float[4],       color terms $X[0]*mc + X[1]*mc^2 + X[2]*mc^3$, etc 
+FIELD  astromErrSys,      ASTROM_ERR_SYS,  	 float,          systematic astrometry error (arcsec)
+FIELD  astromErrScale,    ASTROM_ERR_SCALE,  	 float,          astrometric error scale
+FIELD  astromErrMagScale, ASTROM_ERR_MAG_SCALE,  float,          astrometric error / mag error scale
+FIELD  astromPoorMask,    ASTROM_POOR_MASK,      short,          detections matching this mask should only be used in emergencies
+FIELD  astromBadMask,     ASTROM_BAD_MASK,       short,          detections matching this mask should not be used
+FIELD  photomErrSys,   	  PHOTOM_ERR_SYS,  	 float,          systematic photometric error
+FIELD  photomPoorMask, 	  PHOTOM_POOR_MASK,  	 short,          detections matching this mask should only be used in emergencies
+FIELD  photomBadMask,  	  PHOTOM_BAD_MASK,  	 short,          detections matching this mask should not be used
+
+#   dR_total^2 =  dR_sys^2 + AS * dR_obs^2 + MS * dM_obs^2
+#   dR_sys : systematicAstrometryError
+#   AS     : astrometryErrorScale
+#   MS     : astrometryErrorMagScale
Index: /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libautocode/def/photcode-ps1-ref-v3.d
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libautocode/def/photcode-ps1-ref-v3.d	(revision 42803)
+++ /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libautocode/def/photcode-ps1-ref-v3.d	(revision 42803)
@@ -0,0 +1,33 @@
+STRUCT       PhotCode_PS1_REF_V3
+EXTNAME      DVO_PHOTCODE_PS1_REF_V3
+TYPE         BINTABLE
+SIZE         104
+DESCRIPTION  DVO Photcode Description Table 
+
+# elements of data structure / FITS table
+FIELD  code,         	  CODE,          	 unsigned short, code number (stored in Measure.source) 
+FIELD  name,         	  NAME,          	 char[32],       name for filter combination 
+FIELD  type,         	  TYPE,          	 char,           PRI/SEC/DEP/REF 
+FIELD  dummy,        	  DUMMY,         	 char[3],        padding
+FIELD  C,            	  C_LAM,         	 short,          primary phot calibration terms (millimags) 
+FIELD  dC,           	  C_LAM_ERR,     	 short,          primary phot calibration terms (millimags) 
+FIELD  dX,           	  X_ERR,         	 short,          primary phot calibration terms (millimags) 
+FIELD  K,            	  K,             	 float,          secondary phot calibration terms (millimags) 
+FIELD  c1,           	  C1,            	 int,            color is average.M[c1] - average.M[c2] 
+FIELD  c2,           	  C2,            	 int,            color is average.M[c1] - average.M[c2] 
+FIELD  equiv,        	  EQUIV,         	 int,            this dependent filter is equivalent to equiv PRI/SEC
+FIELD  Nc,           	  NC,            	 int,            number of color terms 
+FIELD  X,            	  X,             	 float[4],       color terms $X[0]*mc + X[1]*mc^2 + X[2]*mc^3$, etc 
+FIELD  astromErrSys,      ASTROM_ERR_SYS,  	 float,          systematic astrometry error (arcsec)
+FIELD  astromErrScale,    ASTROM_ERR_SCALE,  	 float,          astrometric error scale
+FIELD  astromErrMagScale, ASTROM_ERR_MAG_SCALE,  float,          astrometric error / mag error scale
+FIELD  astromPoorMask,    ASTROM_POOR_MASK,      short,          detections matching this mask should only be used in emergencies
+FIELD  astromBadMask,     ASTROM_BAD_MASK,       short,          detections matching this mask should not be used
+FIELD  photomErrSys,   	  PHOTOM_ERR_SYS,  	 float,          systematic photometric error
+FIELD  photomPoorMask, 	  PHOTOM_POOR_MASK,  	 short,          detections matching this mask should only be used in emergencies
+FIELD  photomBadMask,  	  PHOTOM_BAD_MASK,  	 short,          detections matching this mask should not be used
+
+#   dR_total^2 =  dR_sys^2 + AS * dR_obs^2 + MS * dM_obs^2
+#   dR_sys : systematicAstrometryError
+#   AS     : astrometryErrorScale
+#   MS     : astrometryErrorMagScale
Index: /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libautocode/def/secfilt-ps1-ref-v2.d
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libautocode/def/secfilt-ps1-ref-v2.d	(revision 42803)
+++ /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libautocode/def/secfilt-ps1-ref-v2.d	(revision 42803)
@@ -0,0 +1,9 @@
+STRUCT       SecFilt_PS1_REF_V2
+EXTNAME      DVO_SECFILT_PS1_REF_V2
+TYPE         BINTABLE
+SIZE         8
+DESCRIPTION  DVO SecFilt : Secondary Filter Data 
+
+# elements of data structure / FITS table
+FIELD  M,     MAG,      float,                average mag in this band, mags
+FIELD  dM,    MAG_ERR,  float,                error on average mag,     mags
Index: /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libautocode/def/secfilt-ps1-ref-v3.d
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libautocode/def/secfilt-ps1-ref-v3.d	(revision 42803)
+++ /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libautocode/def/secfilt-ps1-ref-v3.d	(revision 42803)
@@ -0,0 +1,11 @@
+STRUCT       SecFilt_PS1_REF_V3
+EXTNAME      DVO_SECFILT_PS1_REF_V3
+TYPE         BINTABLE
+SIZE         12
+DESCRIPTION  DVO SecFilt : Secondary Filter Data 
+
+# elements of data structure / FITS table
+FIELD  M,     MAG,      float,                average mag in this band, mags
+FIELD  dM,    MAG_ERR,  float,                error on average mag,     mags
+FIELD  flags, FLAGS,    uint32_t,             photometry flags
+
Index: /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libdvo/Makefile
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libdvo/Makefile	(revision 42802)
+++ /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libdvo/Makefile	(revision 42803)
@@ -53,4 +53,6 @@
 $(DESTINC)/ps1_v5_ld_defs.h \
 $(DESTINC)/ps1_ref_defs.h \
+$(DESTINC)/ps1_ref_v2_defs.h \
+$(DESTINC)/ps1_ref_v3_defs.h \
 $(DESTINC)/ps1_sim_defs.h \
 $(DESTINC)/cmf-ps1-dv3.h \
@@ -105,4 +107,6 @@
 $(SRC)/dvo_convert_PS1_V5_LOAD.$(ARCH).o \
 $(SRC)/dvo_convert_PS1_REF.$(ARCH).o \
+$(SRC)/dvo_convert_PS1_REF_V2.$(ARCH).o \
+$(SRC)/dvo_convert_PS1_REF_V3.$(ARCH).o \
 $(SRC)/dvo_convert_PS1_SIM.$(ARCH).o \
 $(SRC)/flatcorr_io.$(ARCH).o    \
Index: /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libdvo/include/dvo.h
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libdvo/include/dvo.h	(revision 42802)
+++ /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libdvo/include/dvo.h	(revision 42803)
@@ -27,4 +27,6 @@
   DVO_FORMAT_PS1_DEV_3,
   DVO_FORMAT_PS1_REF,
+  DVO_FORMAT_PS1_REF_V2,
+  DVO_FORMAT_PS1_REF_V3,
   DVO_FORMAT_PS1_SIM,
   DVO_FORMAT_PS1_V1,
@@ -251,4 +253,9 @@
 
   ID_SECF_OBJ_EXT       	 = 0x01000000, // extended in this band
+
+  //ID_SECF_PHO_SYNTH            = 0x00000001, // this photcode has SYNTH photometry, turn on only for reference catalog
+  //ID_SECF_PHO_ATLAS            = 0x00000002, // this photcode has ATLAS photometry, turn on only for reference catalog
+  //ID_SECF_PHO_PV3              = 0x00000004, // this photcode has PV3   photometry, turn on only for reference catalog
+  //ID_SECF_PHO_SOUTH            = 0x00000008, // this photcode has SOUTH photometry, turn on only for reference catalog
 
   ID_SECF_CHIP_FLAGS    	 = 0x01003f1f, // all chip-related bits (used to reset the correct bits only)
@@ -1087,4 +1094,6 @@
 # include "ps1_v5_ld_defs.h"
 # include "ps1_ref_defs.h"
+# include "ps1_ref_v2_defs.h"
+# include "ps1_ref_v3_defs.h"
 # include "ps1_sim_defs.h"
 
Index: /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libdvo/include/ps1_ref_v2_defs.h
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libdvo/include/ps1_ref_v2_defs.h	(revision 42803)
+++ /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libdvo/include/ps1_ref_v2_defs.h	(revision 42803)
@@ -0,0 +1,11 @@
+Image 		       	*Image_PS1_REF_V2_ToInternal (Image_PS1_REF_V2 *in, off_t Nvalues, off_t Nalloc);
+Image_PS1_REF_V2    	*ImageInternalTo_PS1_REF_V2 (Image *in, off_t Nvalues);
+Average 	       	*Average_PS1_REF_V2_ToInternal (Average_PS1_REF_V2 *in, off_t Nvalues, SecFilt **primary);
+Average_PS1_REF_V2      *AverageInternalTo_PS1_REF_V2 (Average *in, off_t Nvalues, SecFilt *primary);
+Measure 	       	*Measure_PS1_REF_V2_ToInternal (Average *ave, Measure_PS1_REF_V2 *in, off_t Nvalues);
+Measure_PS1_REF_V2      *MeasureInternalTo_PS1_REF_V2 (Average *ave, Measure *in, off_t Nvalues);
+SecFilt 	       	*SecFilt_PS1_REF_V2_ToInternal (SecFilt_PS1_REF_V2 *in, off_t Nvalues);
+SecFilt_PS1_REF_V2      *SecFiltInternalTo_PS1_REF_V2 (SecFilt *in, off_t Nvalues);
+
+PhotCode                *PhotCode_PS1_REF_V2_To_Internal (PhotCode_PS1_REF_V2 *in, off_t Nvalues);
+PhotCode_PS1_REF_V2     *PhotCode_Internal_To_PS1_REF_V2 (PhotCode *in, off_t Nvalues);
Index: /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libdvo/include/ps1_ref_v3_defs.h
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libdvo/include/ps1_ref_v3_defs.h	(revision 42803)
+++ /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libdvo/include/ps1_ref_v3_defs.h	(revision 42803)
@@ -0,0 +1,11 @@
+Image 		       	*Image_PS1_REF_V3_ToInternal (Image_PS1_REF_V3 *in, off_t Nvalues, off_t Nalloc);
+Image_PS1_REF_V3    	*ImageInternalTo_PS1_REF_V3 (Image *in, off_t Nvalues);
+Average 	       	*Average_PS1_REF_V3_ToInternal (Average_PS1_REF_V3 *in, off_t Nvalues, SecFilt **primary);
+Average_PS1_REF_V3      *AverageInternalTo_PS1_REF_V3 (Average *in, off_t Nvalues, SecFilt *primary);
+Measure 	       	*Measure_PS1_REF_V3_ToInternal (Average *ave, Measure_PS1_REF_V3 *in, off_t Nvalues);
+Measure_PS1_REF_V3      *MeasureInternalTo_PS1_REF_V3 (Average *ave, Measure *in, off_t Nvalues);
+SecFilt 	       	*SecFilt_PS1_REF_V3_ToInternal (SecFilt_PS1_REF_V3 *in, off_t Nvalues);
+SecFilt_PS1_REF_V3      *SecFiltInternalTo_PS1_REF_V3 (SecFilt *in, off_t Nvalues);
+
+PhotCode                *PhotCode_PS1_REF_V3_To_Internal (PhotCode_PS1_REF_V3 *in, off_t Nvalues);
+PhotCode_PS1_REF_V3     *PhotCode_Internal_To_PS1_REF_V3 (PhotCode *in, off_t Nvalues);
Index: /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libdvo/src/LoadPhotcodesFITS.c
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libdvo/src/LoadPhotcodesFITS.c	(revision 42802)
+++ /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libdvo/src/LoadPhotcodesFITS.c	(revision 42803)
@@ -59,4 +59,6 @@
   CONVERT_FORMAT("DVO_PHOTCODE_PS1_DEV_3",   PS1_DEV_3);
   CONVERT_FORMAT("DVO_PHOTCODE_PS1_REF",     PS1_REF);
+  CONVERT_FORMAT("DVO_PHOTCODE_PS1_REF_V2",  PS1_REF_V2);
+  CONVERT_FORMAT("DVO_PHOTCODE_PS1_REF_V3",  PS1_REF_V3);
   CONVERT_FORMAT("DVO_PHOTCODE_PS1_V1",      PS1_V1);
   CONVERT_FORMAT("DVO_PHOTCODE_PS1_V2",      PS1_V2);
Index: /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libdvo/src/dvo_catalog.c
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libdvo/src/dvo_catalog.c	(revision 42802)
+++ /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libdvo/src/dvo_catalog.c	(revision 42803)
@@ -60,4 +60,6 @@
   if (!strcasecmp (catformat, "PS1_V5_LOAD"))     return (DVO_FORMAT_PS1_V5_LOAD);
   if (!strcasecmp (catformat, "PS1_REF"))         return (DVO_FORMAT_PS1_REF);
+  if (!strcasecmp (catformat, "PS1_REF_V2"))      return (DVO_FORMAT_PS1_REF_V2);
+  if (!strcasecmp (catformat, "PS1_REF_V3"))      return (DVO_FORMAT_PS1_REF_V3);
   if (!strcasecmp (catformat, "PS1_SIM"))         return (DVO_FORMAT_PS1_SIM);
   return (DVO_FORMAT_UNDEF);
Index: /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libdvo/src/dvo_catalog_raw.c
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libdvo/src/dvo_catalog_raw.c	(revision 42802)
+++ /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libdvo/src/dvo_catalog_raw.c	(revision 42803)
@@ -94,4 +94,6 @@
       FORMAT_CASE (PS1_V5_LOAD, PS1_V5_LOAD);
       FORMAT_CASE (PS1_REF,     PS1_REF);
+      FORMAT_CASE (PS1_REF_V2,  PS1_REF_V2);
+      FORMAT_CASE (PS1_REF_V3,  PS1_REF_V3);
       FORMAT_CASE (PS1_SIM,     PS1_SIM);
 
@@ -292,4 +294,6 @@
   if (catalog[0].catformat == DVO_FORMAT_PS1_V5_LOAD)     gfits_modify (&catalog[0].header, "FORMAT", "%s", 1, "PS1_V5_LOAD");
   if (catalog[0].catformat == DVO_FORMAT_PS1_REF)         gfits_modify (&catalog[0].header, "FORMAT", "%s", 1, "PS1_REF");
+  if (catalog[0].catformat == DVO_FORMAT_PS1_REF_V2)      gfits_modify (&catalog[0].header, "FORMAT", "%s", 1, "PS1_REF_V2");
+  if (catalog[0].catformat == DVO_FORMAT_PS1_REF_V3)      gfits_modify (&catalog[0].header, "FORMAT", "%s", 1, "PS1_REF_V3");
   if (catalog[0].catformat == DVO_FORMAT_PS1_SIM)         gfits_modify (&catalog[0].header, "FORMAT", "%s", 1, "PS1_SIM");
 
@@ -399,4 +403,6 @@
       FORMAT_CASE (PS1_V5_LOAD, PS1_V5_LOAD);
       FORMAT_CASE (PS1_REF,     PS1_REF);
+      FORMAT_CASE (PS1_REF_V2,  PS1_REF_V2);
+      FORMAT_CASE (PS1_REF_V3,  PS1_REF_V3);
       FORMAT_CASE (PS1_SIM,     PS1_SIM);
 
@@ -454,4 +460,6 @@
       FORMAT_CASE (PS1_V5_LOAD, PS1_V5_LOAD);
       FORMAT_CASE (PS1_REF,     PS1_REF);
+      FORMAT_CASE (PS1_REF_V2,  PS1_REF_V2);
+      FORMAT_CASE (PS1_REF_V3,  PS1_REF_V3);
       FORMAT_CASE (PS1_SIM,     PS1_SIM);
 
@@ -512,4 +520,6 @@
       FORMAT_CASE (PS1_V5_LOAD, PS1_V5_LOAD);
       FORMAT_CASE (PS1_REF,     PS1_REF);
+      FORMAT_CASE (PS1_REF_V2,  PS1_REF_V2);
+      FORMAT_CASE (PS1_REF_V3,  PS1_REF_V3);
       FORMAT_CASE (PS1_SIM,     PS1_SIM);
 
@@ -567,4 +577,6 @@
       FORMAT_CASE (PS1_V5_LOAD, PS1_V5_LOAD);
       FORMAT_CASE (PS1_REF,     PS1_REF);
+      FORMAT_CASE (PS1_REF_V2,  PS1_REF_V2);
+      FORMAT_CASE (PS1_REF_V3,  PS1_REF_V3);
       FORMAT_CASE (PS1_SIM,     PS1_SIM);
 
@@ -626,4 +638,6 @@
       FORMAT_CASE (PS1_V5_LOAD, PS1_V5_LOAD);
       FORMAT_CASE (PS1_REF,     PS1_REF);
+      FORMAT_CASE (PS1_REF_V2,  PS1_REF_V2);
+      FORMAT_CASE (PS1_REF_V3,  PS1_REF_V3);
       FORMAT_CASE (PS1_SIM,     PS1_SIM);
 
@@ -681,4 +695,6 @@
       FORMAT_CASE (PS1_V5_LOAD, PS1_V5_LOAD);
       FORMAT_CASE (PS1_REF,     PS1_REF);
+      FORMAT_CASE (PS1_REF_V2,  PS1_REF_V2);
+      FORMAT_CASE (PS1_REF_V3,  PS1_REF_V3);
       FORMAT_CASE (PS1_SIM,     PS1_SIM);
 
Index: /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libdvo/src/dvo_convert.c
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libdvo/src/dvo_convert.c	(revision 42802)
+++ /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libdvo/src/dvo_convert.c	(revision 42803)
@@ -45,4 +45,6 @@
   CONVERT_FORMAT ("DVO_AVERAGE_PS1_V5_LOAD",     PS1_V5_LOAD);
   CONVERT_FORMAT ("DVO_AVERAGE_PS1_REF",         PS1_REF);
+  CONVERT_FORMAT ("DVO_AVERAGE_PS1_REF_V2",      PS1_REF_V2);
+  CONVERT_FORMAT ("DVO_AVERAGE_PS1_REF_V3",      PS1_REF_V3);
   CONVERT_FORMAT ("DVO_AVERAGE_PS1_SIM",         PS1_SIM);
 # undef CONVERT_FORMAT
@@ -137,4 +139,6 @@
   CONVERT_FORMAT ("DVO_AVERAGE_PS1_V5_LOAD",     PS1_V5_LOAD,     PS1_V5_LOAD);
   CONVERT_FORMAT ("DVO_AVERAGE_PS1_REF",         PS1_REF,         PS1_REF);
+  CONVERT_FORMAT ("DVO_AVERAGE_PS1_REF_V2",      PS1_REF_V2,      PS1_REF_V2);
+  CONVERT_FORMAT ("DVO_AVERAGE_PS1_REF_V3",      PS1_REF_V3,      PS1_REF_V3);
   CONVERT_FORMAT ("DVO_AVERAGE_PS1_SIM",         PS1_SIM,         PS1_SIM);
 # undef CONVERT_FORMAT
@@ -176,4 +180,6 @@
       FORMAT_CASE (PS1_V5_LOAD,     PS1_V5_LOAD);
       FORMAT_CASE (PS1_REF,         PS1_REF);
+      FORMAT_CASE (PS1_REF_V2,      PS1_REF_V2);
+      FORMAT_CASE (PS1_REF_V3,      PS1_REF_V3);
       FORMAT_CASE (PS1_SIM,         PS1_SIM);
 # undef FORMAT_CASE
@@ -276,4 +282,6 @@
   CONVERT_FORMAT ("DVO_MEASURE_PS1_V5_LOAD",     PS1_V5_LOAD,     PS1_V5_LOAD,     TRUE);
   CONVERT_FORMAT ("DVO_MEASURE_PS1_REF",         PS1_REF,         PS1_REF,         FALSE);
+  CONVERT_FORMAT ("DVO_MEASURE_PS1_REF_V2",      PS1_REF_V2,      PS1_REF_V2,      FALSE);
+  CONVERT_FORMAT ("DVO_MEASURE_PS1_REF_V3",      PS1_REF_V3,      PS1_REF_V3,      FALSE);
   CONVERT_FORMAT ("DVO_MEASURE_PS1_SIM",         PS1_SIM,         PS1_SIM,         TRUE);
 # undef CONVERT_FORMAT
@@ -317,4 +325,6 @@
       FORMAT_CASE (PS1_V5_LOAD,     PS1_V5_LOAD,     TRUE);
       FORMAT_CASE (PS1_REF,         PS1_REF,         FALSE);
+      FORMAT_CASE (PS1_REF_V2,      PS1_REF_V2,      FALSE);
+      FORMAT_CASE (PS1_REF_V3,      PS1_REF_V3,      FALSE);
       FORMAT_CASE (PS1_SIM,         PS1_SIM,         TRUE);
 # undef FORMAT_CASE
@@ -385,4 +395,6 @@
   SKIPPING_FORMAT ("DVO_MISSING_PS1_SIM",         PS1_SIM,         PS1_SIM);
   SKIPPING_FORMAT ("DVO_MISSING_PS1_REF",         PS1_REF,         PS1_REF);
+  SKIPPING_FORMAT ("DVO_MISSING_PS1_REF_V2",      PS1_REF_V2,      PS1_REF_V2);
+  SKIPPING_FORMAT ("DVO_MISSING_PS1_REF_V3",      PS1_REF_V3,      PS1_REF_V3);
   SKIPPING_FORMAT ("DVO_MISSING_ELIXIR", 	  ELIXIR,  	   Elixir);
   SKIPPING_FORMAT ("DVO_MISSING_LONEOS", 	  LONEOS,          Loneos);
@@ -475,4 +487,6 @@
   CONVERT_FORMAT ("DVO_SECFILT_PS1_V5_LOAD",     PS1_V5_LOAD,     PS1_V5_LOAD);
   CONVERT_FORMAT ("DVO_SECFILT_PS1_REF",         PS1_REF,         PS1_REF);
+  CONVERT_FORMAT ("DVO_SECFILT_PS1_REF_V2",      PS1_REF_V2,      PS1_REF_V2);
+  CONVERT_FORMAT ("DVO_SECFILT_PS1_REF_V3",      PS1_REF_V3,      PS1_REF_V3);
   CONVERT_FORMAT ("DVO_SECFILT_PS1_SIM",         PS1_SIM,         PS1_SIM);
 # undef CONVERT_FORMAT
@@ -514,4 +528,6 @@
       FORMAT_CASE (PS1_V5_LOAD,     PS1_V5_LOAD);
       FORMAT_CASE (PS1_REF,         PS1_REF);
+      FORMAT_CASE (PS1_REF_V2,      PS1_REF_V2);
+      FORMAT_CASE (PS1_REF_V3,      PS1_REF_V3);
       FORMAT_CASE (PS1_SIM,         PS1_SIM);
 # undef FORMAT_CASE
@@ -609,4 +625,6 @@
 
   SKIPPING_FORMAT ("DVO_LENSING_PS1_REF",         PS1_REF,         PS1_REF);
+  SKIPPING_FORMAT ("DVO_LENSING_PS1_REF_V2",      PS1_REF_V2,      PS1_REF_V2);
+  SKIPPING_FORMAT ("DVO_LENSING_PS1_REF_V3",      PS1_REF_V3,      PS1_REF_V3);
   SKIPPING_FORMAT ("DVO_LENSING_ELIXIR", 	  ELIXIR,  	   Elixir);
   SKIPPING_FORMAT ("DVO_LENSING_LONEOS", 	  LONEOS,          Loneos);
@@ -650,4 +668,6 @@
 
 //    FORMAT_CASE (PS1_REF,         PS1_REF);
+//    FORMAT_CASE (PS1_REF_V2,      PS1_REF_V2);
+//    FORMAT_CASE (PS1_REF_V3,      PS1_REF_V3);
 //    FORMAT_CASE (ELIXIR, 	    Elixir);
 //    FORMAT_CASE (LONEOS, 	    Loneos);
@@ -731,4 +751,6 @@
 
   SKIPPING_FORMAT ("DVO_LENSOBJ_PS1_REF",         PS1_REF,         PS1_REF);
+  SKIPPING_FORMAT ("DVO_LENSOBJ_PS1_REF_V2",      PS1_REF_V2,      PS1_REF_V2);
+  SKIPPING_FORMAT ("DVO_LENSOBJ_PS1_REF_V3",      PS1_REF_V3,      PS1_REF_V3);
   SKIPPING_FORMAT ("DVO_LENSOBJ_ELIXIR", 	  ELIXIR,  	   Elixir);
   SKIPPING_FORMAT ("DVO_LENSOBJ_LONEOS", 	  LONEOS,          Loneos);
@@ -772,4 +794,6 @@
 
 //    FORMAT_CASE (PS1_REF,         PS1_REF);
+//    FORMAT_CASE (PS1_REF_V2,      PS1_REF_V2);
+//    FORMAT_CASE (PS1_REF_V3,      PS1_REF_V3);
 //    FORMAT_CASE (ELIXIR, 	    Elixir);
 //    FORMAT_CASE (LONEOS, 	    Loneos);
@@ -841,4 +865,6 @@
   CONVERT_FORMAT  ("DVO_STARPAR_PS1_SIM",         PS1_SIM,         PS1_SIM);
   SKIPPING_FORMAT ("DVO_STARPAR_PS1_REF",         PS1_REF,         PS1_REF);
+  SKIPPING_FORMAT ("DVO_STARPAR_PS1_REF_V2",      PS1_REF_V2,      PS1_REF_V2);
+  SKIPPING_FORMAT ("DVO_STARPAR_PS1_REF_V3",      PS1_REF_V3,      PS1_REF_V3);
   SKIPPING_FORMAT ("DVO_STARPAR_ELIXIR", 	  ELIXIR,  	   Elixir);
   SKIPPING_FORMAT ("DVO_STARPAR_LONEOS", 	  LONEOS,          Loneos);
@@ -882,4 +908,6 @@
       FORMAT_CASE (PS1_SIM,         PS1_SIM);
 //    FORMAT_CASE (PS1_REF,         PS1_REF);
+//    FORMAT_CASE (PS1_REF_V2,      PS1_REF_V2);
+//    FORMAT_CASE (PS1_REF_V3,      PS1_REF_V3);
 //    FORMAT_CASE (ELIXIR, 	    Elixir);
 //    FORMAT_CASE (LONEOS, 	    Loneos);
@@ -964,4 +992,6 @@
 
   SKIPPING_FORMAT ("DVO_GALPHOT_PS1_REF",         PS1_REF,         PS1_REF);
+  SKIPPING_FORMAT ("DVO_GALPHOT_PS1_REF_V2",      PS1_REF_V2,      PS1_REF_V2);
+  SKIPPING_FORMAT ("DVO_GALPHOT_PS1_REF_V3",      PS1_REF_V3,      PS1_REF_V3);
   SKIPPING_FORMAT ("DVO_GALPHOT_ELIXIR", 	  ELIXIR,  	   Elixir);
   SKIPPING_FORMAT ("DVO_GALPHOT_LONEOS", 	  LONEOS,          Loneos);
@@ -1005,4 +1035,6 @@
 
 //    FORMAT_CASE (PS1_REF,         PS1_REF);
+//    FORMAT_CASE (PS1_REF_V2,      PS1_REF_V2);
+//    FORMAT_CASE (PS1_REF_V3,      PS1_REF_V3);
 //    FORMAT_CASE (ELIXIR, 	    Elixir);
 //    FORMAT_CASE (LONEOS, 	    Loneos);
@@ -1094,4 +1126,6 @@
   CONVERT_FORMAT ("DVO_IMAGE_PS1_V5_LOAD",     PS1_V5_LOAD,     PS1_V5_LOAD);
   CONVERT_FORMAT ("DVO_IMAGE_PS1_REF",         PS1_REF,         PS1_REF);
+  CONVERT_FORMAT ("DVO_IMAGE_PS1_REF_V2",      PS1_REF_V2,      PS1_REF_V2);
+  CONVERT_FORMAT ("DVO_IMAGE_PS1_REF_V3",      PS1_REF_V3,      PS1_REF_V3);
   CONVERT_FORMAT ("DVO_IMAGE_PS1_SIM",         PS1_SIM,         PS1_SIM);
 
@@ -1135,4 +1169,6 @@
     FORMAT_CASE (PS1_V5_LOAD,     PS1_V5_LOAD);
     FORMAT_CASE (PS1_REF,         PS1_REF);
+    FORMAT_CASE (PS1_REF_V2,      PS1_REF_V2);
+    FORMAT_CASE (PS1_REF_V3,      PS1_REF_V3);
     FORMAT_CASE (PS1_SIM,         PS1_SIM);
 
@@ -1188,4 +1224,6 @@
     FORMAT_CASE (PS1_V5_LOAD,     PS1_V5_LOAD);
     FORMAT_CASE (PS1_REF,         PS1_REF);
+    FORMAT_CASE (PS1_REF_V2,      PS1_REF_V2);
+    FORMAT_CASE (PS1_REF_V3,      PS1_REF_V3);
     FORMAT_CASE (PS1_SIM,         PS1_SIM);
 
Index: /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libdvo/src/dvo_convert_PS1_REF_V2.c
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libdvo/src/dvo_convert_PS1_REF_V2.c	(revision 42803)
+++ /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libdvo/src/dvo_convert_PS1_REF_V2.c	(revision 42803)
@@ -0,0 +1,358 @@
+# include <dvo.h>
+
+/* convert PS1_REF_V2 formats to internal formats */
+
+Measure *Measure_PS1_REF_V2_ToInternal (Average *ave, Measure_PS1_REF_V2 *in, off_t Nvalues) {
+
+  off_t i;
+  Measure *out;
+
+  ALLOCATE_ZERO (out, Measure, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    dvo_measure_init (&out[i]);
+
+    int averef = in[i].averef;
+    out[i].R          = ave[averef].R - in[i].dR / 3600.0;
+    out[i].D          = ave[averef].D - in[i].dD / 3600.0;
+    out[i].M          = in[i].M;
+    out[i].dM         = in[i].dM;
+    out[i].dt         = in[i].dt;
+    out[i].t          = in[i].t;
+    out[i].McalPSF    = in[i].Mcal;
+    out[i].McalAPER   = in[i].Mcal;
+    out[i].dMcal      = in[i].dMcal;
+    out[i].averef     = in[i].averef;
+    out[i].objID      = in[i].objID;
+    out[i].catID      = in[i].catID;
+    out[i].psfQF      = 1.0; // we do not save a value, but some operations (relphot/average) filter on this value..
+    out[i].photcode   = in[i].photcode;
+  }
+  return (out);
+}
+
+Measure_PS1_REF_V2 *MeasureInternalTo_PS1_REF_V2 (Average *ave, Measure *in, off_t Nvalues) {
+
+  off_t i;
+  Measure_PS1_REF_V2 *out;
+
+  ALLOCATE_ZERO (out, Measure_PS1_REF_V2, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    int averef = in[i].averef;
+
+    out[i].dR         = 3600.0*(ave[averef].R - in[i].R);
+    out[i].dD         = 3600.0*(ave[averef].D - in[i].D);
+    out[i].M          = in[i].M;
+    out[i].dM         = in[i].dM;
+    out[i].dt         = in[i].dt;
+    out[i].t          = in[i].t;
+    out[i].Mcal       = in[i].McalPSF;
+    out[i].dMcal      = in[i].dMcal;
+    out[i].averef     = in[i].averef;
+    out[i].objID      = in[i].objID;
+    out[i].catID      = in[i].catID;
+    out[i].photcode   = in[i].photcode;
+  }
+  return (out);
+}
+
+// 'primary' is needed to conform with the API for Loneos and Elixir, but is not used
+Average *Average_PS1_REF_V2_ToInternal (Average_PS1_REF_V2 *in, off_t Nvalues, SecFilt **primary) {
+  OHANA_UNUSED_PARAM(primary);
+
+  off_t i;
+  Average *out;
+
+  ALLOCATE_ZERO (out, Average, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    dvo_average_init (&out[i]);
+
+    out[i].R        	 = in[i].R;      
+    out[i].D        	 = in[i].D;      
+    out[i].dR       	 = in[i].dR;
+    out[i].dD       	 = in[i].dD;
+    out[i].uR       	  = in[i].uR;
+    out[i].uD       	  = in[i].uD;
+    out[i].duR      	  = in[i].duR;
+    out[i].duD      	  = in[i].duD;
+    out[i].P        	  = in[i].P;
+    out[i].dP       	  = in[i].dP;
+    out[i].Nmeasure      = in[i].Nmeasure;     
+    out[i].Nmissing      = in[i].Nmissing;     
+    out[i].measureOffset = in[i].measureOffset; 
+    out[i].missingOffset = in[i].missingOffset;
+    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_REF_V2 *AverageInternalTo_PS1_REF_V2 (Average *in, off_t Nvalues, SecFilt *primary) {
+  OHANA_UNUSED_PARAM(primary);
+
+  off_t i;
+  Average_PS1_REF_V2 *out;
+
+  ALLOCATE_ZERO (out, Average_PS1_REF_V2, 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].Nmeasure      = in[i].Nmeasure;     
+    out[i].Nmissing      = in[i].Nmissing;     
+    out[i].measureOffset = in[i].measureOffset; 
+    out[i].missingOffset = in[i].missingOffset;
+    out[i].objID 	 = in[i].objID;
+    out[i].catID 	 = in[i].catID;
+    memset(out[i].pad, 0, sizeof(out[i].pad));
+  }
+  return (out);
+}
+
+SecFilt *SecFilt_PS1_REF_V2_ToInternal (SecFilt_PS1_REF_V2 *in, off_t Nvalues) {
+
+  off_t i;
+  SecFilt *out;
+
+  ALLOCATE_ZERO (out, SecFilt, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    dvo_secfilt_init (&out[i], SECFILT_RESET_ALL);
+
+    out[i].MpsfChp     = in[i].M;      
+    out[i].dMpsfChp    = in[i].dM;      
+ }
+  return (out);
+}
+
+SecFilt_PS1_REF_V2 *SecFiltInternalTo_PS1_REF_V2 (SecFilt *in, off_t Nvalues) {
+
+  off_t i;
+  SecFilt_PS1_REF_V2 *out;
+
+  ALLOCATE_ZERO (out, SecFilt_PS1_REF_V2, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    out[i].M             = in[i].MpsfChp;      
+    out[i].dM            = in[i].dMpsfChp;      
+  }
+  return (out);
+}
+
+# define RAW_IMAGE_NAME_LEN 121
+
+Image *Image_PS1_REF_V2_ToInternal (Image_PS1_REF_V2 *in, off_t Nvalues, off_t Nalloc) {
+
+  off_t i;
+  Image *out;
+
+  char *buffer;
+  ALLOCATE_ZERO (buffer, char, Nalloc);
+  out = (Image *) buffer;
+  // ALLOCATE_ZERO (out, Image, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    // this is only safe because the initial 120 bytes in Coords match CoordsDisk
+    memcpy (&out[i].coords, &in[i].coords, sizeof(CoordsDisk));
+    out[i].coords.mosaic   = NULL;
+    out[i].coords.offsetMap = NULL;
+
+    // RAW_IMAGE_NAME_LEN > DVO_IMAGE_NAME_LEN
+    strncpy (out[i].name, in[i].name, DVO_IMAGE_NAME_LEN - 1);
+    out[i].name[DVO_IMAGE_NAME_LEN - 1] = 0; // force termination
+
+    out[i].tzero    	    = in[i].tzero;
+    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].McalPSF    	    = in[i].Mcal;
+    out[i].McalAPER    	    = in[i].Mcal;
+    out[i].dMcal    	    = in[i].dMcal;
+    out[i].McalChiSq  	    = pow(10.0, 0.01*in[i].Xm);
+
+    out[i].photcode   	    = in[i].photcode;
+    out[i].exptime  	    = in[i].exptime;
+    out[i].sidtime  	    = in[i].sidtime;
+    out[i].latitude  	    = in[i].latitude;
+    out[i].detection_limit  = in[i].detection_limit;
+    out[i].saturation_limit = in[i].saturation_limit;
+    out[i].cerror	    = in[i].cerror;
+    out[i].fwhm_x	    = in[i].fwhm_x;
+    out[i].fwhm_y	    = in[i].fwhm_y;
+    out[i].trate	    = in[i].trate;
+    out[i].ccdnum	    = in[i].ccdnum;
+    out[i].flags	    = in[i].flags;
+    out[i].imageID	    = in[i].imageID;
+    out[i].parentID	    = in[i].parentID;
+    out[i].externID	    = in[i].externID;
+    out[i].sourceID	    = in[i].sourceID;
+
+    // as of 2011.02.03, the old Mx,My,..., Mxxxx,Myyyy have been deprecated and replaced
+    // with the following.  (no real databases used those values -- see
+    // libdvo/doc/dvo-images.txt)
+    out[i].nLinkAstrom	    = in[i].nLinkAstrom;
+    out[i].nLinkPhotom	    = in[i].nLinkPhotom;
+    out[i].ubercalDist	    = in[i].dummy3; // new name PS1_V3
+    out[i].dXpixSys	    = in[i].dXpixSys;
+    out[i].dYpixSys	    = in[i].dYpixSys;
+    out[i].dMagSys	    = in[i].dMagSys;
+    out[i].nFitAstrom       = in[i].nFitAstrom;
+    out[i].nFitPhotom       = in[i].nFitPhotom;
+    out[i].photom_map_id    = in[i].photom_map_id;
+    out[i].astrom_map_id    = in[i].astrom_map_id;
+
+    // changed or added for PS1_V2
+    out[i].RAo  	    = NAN;
+    out[i].DECo  	    = NAN;
+    out[i].Radius  	    = NAN;
+  }
+  return (out);
+}
+
+Image_PS1_REF_V2 *ImageInternalTo_PS1_REF_V2 (Image *in, off_t Nvalues) {
+
+  off_t i;
+  Image_PS1_REF_V2 *out;
+
+  ALLOCATE_ZERO (out, Image_PS1_REF_V2, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    // this is only safe because the initial 120 bytes in Coords match CoordsDisk
+    memcpy (&out[i].coords, &in[i].coords, sizeof(CoordsDisk));
+
+    // RAW_IMAGE_NAME_LEN > DVO_IMAGE_NAME_LEN
+    strncpy (out[i].name, in[i].name, DVO_IMAGE_NAME_LEN - 1);
+    out[i].name[DVO_IMAGE_NAME_LEN - 1] = 0; // force termination
+
+    out[i].tzero    	    = in[i].tzero;
+    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].McalPSF;
+    out[i].dMcal    	    = in[i].dMcal;
+    out[i].Xm	    	    = 100.0*log10(in[i].McalChiSq);
+
+    out[i].photcode   	    = in[i].photcode;
+    out[i].exptime  	    = in[i].exptime;
+    out[i].sidtime  	    = in[i].sidtime;
+    out[i].latitude  	    = in[i].latitude;
+    out[i].detection_limit  = in[i].detection_limit;
+    out[i].saturation_limit = in[i].saturation_limit;
+    out[i].cerror	    = in[i].cerror;
+    out[i].fwhm_x	    = in[i].fwhm_x;
+    out[i].fwhm_y	    = in[i].fwhm_y;
+    out[i].trate	    = in[i].trate;
+    out[i].ccdnum	    = in[i].ccdnum;
+    out[i].flags	    = in[i].flags;
+    out[i].imageID	    = in[i].imageID;
+    out[i].parentID	    = in[i].parentID;
+    out[i].externID	    = in[i].externID;
+    out[i].sourceID	    = in[i].sourceID;
+
+    // as of 2011.02.03, the old Mx,My,..., Mxxxx,Myyyy have been deprecated and replaced
+    // with the following.  (no real databases used those values -- see
+    // libdvo/doc/dvo-images.txt)
+    out[i].nLinkAstrom	    = in[i].nLinkAstrom;
+    out[i].nLinkPhotom	    = in[i].nLinkPhotom;
+    out[i].dummy3	    = in[i].ubercalDist; // new name PS1_V3
+    out[i].dXpixSys	    = in[i].dXpixSys;
+    out[i].dYpixSys	    = in[i].dYpixSys;
+    out[i].dMagSys	    = in[i].dMagSys;
+    out[i].nFitAstrom       = in[i].nFitAstrom;
+    out[i].nFitPhotom       = in[i].nFitPhotom;
+    out[i].photom_map_id    = in[i].photom_map_id;
+    out[i].astrom_map_id    = in[i].astrom_map_id;
+  }
+  return (out);
+}
+
+PhotCode *PhotCode_PS1_REF_V2_To_Internal (PhotCode_PS1_REF_V2 *in, off_t Nvalues) {
+
+  off_t i;
+  PhotCode *out;
+
+  ALLOCATE_ZERO (out, PhotCode, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    strncpy (out[i].name, in[i].name, 31); // out[32], in[32]
+    out[i].name[31] = 0; // force termination
+
+    out[i].code  = in[i].code;         
+    out[i].type  = in[i].type;         
+    out[i].C     = in[i].C;            
+    out[i].dC 	 = in[i].dC;           
+    out[i].dX 	 = in[i].dX;           
+    out[i].K  	 = in[i].K;            
+    out[i].c1 	 = in[i].c1;           
+    out[i].c2 	 = in[i].c2;           
+    out[i].equiv = in[i].equiv;        
+    out[i].Nc    = in[i].Nc;           
+    memcpy (out[i].X, in[i].X, 4*sizeof(float));            
+
+    out[i].astromErrSys      = in[i].astromErrSys;
+    out[i].astromErrScale    = in[i].astromErrScale;
+    out[i].astromErrMagScale = in[i].astromErrMagScale;
+    out[i].photomErrSys      = in[i].photomErrSys;
+
+    out[i].photomPoorMask      = in[i].photomPoorMask;
+    out[i].photomBadMask       = in[i].photomBadMask;
+    out[i].astromPoorMask      = in[i].astromPoorMask;
+    out[i].astromBadMask       = in[i].astromBadMask;
+  }
+  return (out);
+}
+
+PhotCode_PS1_REF_V2 *PhotCode_Internal_To_PS1_REF_V2 (PhotCode *in, off_t Nvalues) {
+
+  off_t i;
+  PhotCode_PS1_REF_V2 *out;
+
+  ALLOCATE_ZERO (out, PhotCode_PS1_REF_V2, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    strncpy (out[i].name, in[i].name, 31); // out[32], in[32]
+    out[i].name[31] = 0; // force termination
+
+    out[i].code  = in[i].code;         
+    out[i].type  = in[i].type;         
+    out[i].C     = in[i].C;            
+    out[i].dC 	 = in[i].dC;           
+    out[i].dX 	 = in[i].dX;           
+    out[i].K  	 = in[i].K;            
+    out[i].c1 	 = in[i].c1;           
+    out[i].c2 	 = in[i].c2;           
+    out[i].equiv = in[i].equiv;        
+    out[i].Nc    = in[i].Nc;           
+    memcpy (out[i].X, in[i].X, 4*sizeof(float));            
+
+    out[i].astromErrSys      = in[i].astromErrSys;
+    out[i].astromErrScale    = in[i].astromErrScale;
+    out[i].astromErrMagScale = in[i].astromErrMagScale;
+    out[i].photomErrSys      = in[i].photomErrSys;
+
+    out[i].photomPoorMask      = in[i].photomPoorMask;
+    out[i].photomBadMask       = in[i].photomBadMask;
+    out[i].astromPoorMask      = in[i].astromPoorMask;
+    out[i].astromBadMask       = in[i].astromBadMask;
+  }
+  return (out);
+}
Index: /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libdvo/src/dvo_convert_PS1_REF_V3.c
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libdvo/src/dvo_convert_PS1_REF_V3.c	(revision 42803)
+++ /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libdvo/src/dvo_convert_PS1_REF_V3.c	(revision 42803)
@@ -0,0 +1,364 @@
+# include <dvo.h>
+
+/* convert PS1_REF_V3 formats to internal formats */
+
+Measure *Measure_PS1_REF_V3_ToInternal (Average *ave, Measure_PS1_REF_V3 *in, off_t Nvalues) {
+
+  off_t i;
+  Measure *out;
+
+  ALLOCATE_ZERO (out, Measure, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    dvo_measure_init (&out[i]);
+
+    int averef = in[i].averef;
+    out[i].R          = ave[averef].R - in[i].dR / 3600.0;
+    out[i].D          = ave[averef].D - in[i].dD / 3600.0;
+    out[i].M          = in[i].M;
+    out[i].dM         = in[i].dM;
+    out[i].dt         = in[i].dt;
+    out[i].t          = in[i].t;
+    out[i].McalPSF    = in[i].Mcal;
+    out[i].McalAPER   = in[i].Mcal;
+    out[i].dMcal      = in[i].dMcal;
+    out[i].averef     = in[i].averef;
+    out[i].objID      = in[i].objID;
+    out[i].catID      = in[i].catID;
+    out[i].psfQF      = 1.0; // we do not save a value, but some operations (relphot/average) filter on this value..
+    out[i].photcode   = in[i].photcode;
+    out[i].dbFlags    = in[i].dbFlags;
+    out[i].photFlags  = in[i].photFlags;
+  }
+  return (out);
+}
+
+Measure_PS1_REF_V3 *MeasureInternalTo_PS1_REF_V3 (Average *ave, Measure *in, off_t Nvalues) {
+
+  off_t i;
+  Measure_PS1_REF_V3 *out;
+
+  ALLOCATE_ZERO (out, Measure_PS1_REF_V3, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    int averef = in[i].averef;
+
+    out[i].dR         = 3600.0*(ave[averef].R - in[i].R);
+    out[i].dD         = 3600.0*(ave[averef].D - in[i].D);
+    out[i].M          = in[i].M;
+    out[i].dM         = in[i].dM;
+    out[i].dt         = in[i].dt;
+    out[i].t          = in[i].t;
+    out[i].Mcal       = in[i].McalPSF;
+    out[i].dMcal      = in[i].dMcal;
+    out[i].averef     = in[i].averef;
+    out[i].objID      = in[i].objID;
+    out[i].catID      = in[i].catID;
+    out[i].photcode   = in[i].photcode;
+    out[i].dbFlags    = in[i].dbFlags;
+    out[i].photFlags  = in[i].photFlags;
+  }
+  return (out);
+}
+
+// 'primary' is needed to conform with the API for Loneos and Elixir, but is not used
+Average *Average_PS1_REF_V3_ToInternal (Average_PS1_REF_V3 *in, off_t Nvalues, SecFilt **primary) {
+  OHANA_UNUSED_PARAM(primary);
+
+  off_t i;
+  Average *out;
+
+  ALLOCATE_ZERO (out, Average, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    dvo_average_init (&out[i]);
+
+    out[i].R        	 = in[i].R;      
+    out[i].D        	 = in[i].D;      
+    out[i].dR       	 = in[i].dR;
+    out[i].dD       	 = in[i].dD;
+    out[i].uR       	  = in[i].uR;
+    out[i].uD       	  = in[i].uD;
+    out[i].duR      	  = in[i].duR;
+    out[i].duD      	  = in[i].duD;
+    out[i].P        	  = in[i].P;
+    out[i].dP       	  = in[i].dP;
+    out[i].Nmeasure      = in[i].Nmeasure;     
+    out[i].Nmissing      = in[i].Nmissing;     
+    out[i].measureOffset = in[i].measureOffset; 
+    out[i].missingOffset = in[i].missingOffset;
+    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_REF_V3 *AverageInternalTo_PS1_REF_V3 (Average *in, off_t Nvalues, SecFilt *primary) {
+  OHANA_UNUSED_PARAM(primary);
+
+  off_t i;
+  Average_PS1_REF_V3 *out;
+
+  ALLOCATE_ZERO (out, Average_PS1_REF_V3, 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].Nmeasure      = in[i].Nmeasure;     
+    out[i].Nmissing      = in[i].Nmissing;     
+    out[i].measureOffset = in[i].measureOffset; 
+    out[i].missingOffset = in[i].missingOffset;
+    out[i].objID 	 = in[i].objID;
+    out[i].catID 	 = in[i].catID;
+    memset(out[i].pad, 0, sizeof(out[i].pad));
+  }
+  return (out);
+}
+
+SecFilt *SecFilt_PS1_REF_V3_ToInternal (SecFilt_PS1_REF_V3 *in, off_t Nvalues) {
+
+  off_t i;
+  SecFilt *out;
+
+  ALLOCATE_ZERO (out, SecFilt, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    dvo_secfilt_init (&out[i], SECFILT_RESET_ALL);
+
+    out[i].MpsfChp     = in[i].M;      
+    out[i].dMpsfChp    = in[i].dM;      
+    out[i].flags         = in[i].flags;     
+ }
+  return (out);
+}
+
+SecFilt_PS1_REF_V3 *SecFiltInternalTo_PS1_REF_V3 (SecFilt *in, off_t Nvalues) {
+
+  off_t i;
+  SecFilt_PS1_REF_V3 *out;
+
+  ALLOCATE_ZERO (out, SecFilt_PS1_REF_V3, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    out[i].M             = in[i].MpsfChp;      
+    out[i].dM            = in[i].dMpsfChp;      
+    out[i].flags         = in[i].flags;     
+  }
+  return (out);
+}
+
+# define RAW_IMAGE_NAME_LEN 121
+
+Image *Image_PS1_REF_V3_ToInternal (Image_PS1_REF_V3 *in, off_t Nvalues, off_t Nalloc) {
+
+  off_t i;
+  Image *out;
+
+  char *buffer;
+  ALLOCATE_ZERO (buffer, char, Nalloc);
+  out = (Image *) buffer;
+  // ALLOCATE_ZERO (out, Image, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    // this is only safe because the initial 120 bytes in Coords match CoordsDisk
+    memcpy (&out[i].coords, &in[i].coords, sizeof(CoordsDisk));
+    out[i].coords.mosaic   = NULL;
+    out[i].coords.offsetMap = NULL;
+
+    // RAW_IMAGE_NAME_LEN > DVO_IMAGE_NAME_LEN
+    strncpy (out[i].name, in[i].name, DVO_IMAGE_NAME_LEN - 1);
+    out[i].name[DVO_IMAGE_NAME_LEN - 1] = 0; // force termination
+
+    out[i].tzero    	    = in[i].tzero;
+    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].McalPSF    	    = in[i].Mcal;
+    out[i].McalAPER    	    = in[i].Mcal;
+    out[i].dMcal    	    = in[i].dMcal;
+    out[i].McalChiSq  	    = pow(10.0, 0.01*in[i].Xm);
+
+    out[i].photcode   	    = in[i].photcode;
+    out[i].exptime  	    = in[i].exptime;
+    out[i].sidtime  	    = in[i].sidtime;
+    out[i].latitude  	    = in[i].latitude;
+    out[i].detection_limit  = in[i].detection_limit;
+    out[i].saturation_limit = in[i].saturation_limit;
+    out[i].cerror	    = in[i].cerror;
+    out[i].fwhm_x	    = in[i].fwhm_x;
+    out[i].fwhm_y	    = in[i].fwhm_y;
+    out[i].trate	    = in[i].trate;
+    out[i].ccdnum	    = in[i].ccdnum;
+    out[i].flags	    = in[i].flags;
+    out[i].imageID	    = in[i].imageID;
+    out[i].parentID	    = in[i].parentID;
+    out[i].externID	    = in[i].externID;
+    out[i].sourceID	    = in[i].sourceID;
+
+    // as of 2011.02.03, the old Mx,My,..., Mxxxx,Myyyy have been deprecated and replaced
+    // with the following.  (no real databases used those values -- see
+    // libdvo/doc/dvo-images.txt)
+    out[i].nLinkAstrom	    = in[i].nLinkAstrom;
+    out[i].nLinkPhotom	    = in[i].nLinkPhotom;
+    out[i].ubercalDist	    = in[i].dummy3; // new name PS1_V3
+    out[i].dXpixSys	    = in[i].dXpixSys;
+    out[i].dYpixSys	    = in[i].dYpixSys;
+    out[i].dMagSys	    = in[i].dMagSys;
+    out[i].nFitAstrom       = in[i].nFitAstrom;
+    out[i].nFitPhotom       = in[i].nFitPhotom;
+    out[i].photom_map_id    = in[i].photom_map_id;
+    out[i].astrom_map_id    = in[i].astrom_map_id;
+
+    // changed or added for PS1_V2
+    out[i].RAo  	    = NAN;
+    out[i].DECo  	    = NAN;
+    out[i].Radius  	    = NAN;
+  }
+  return (out);
+}
+
+Image_PS1_REF_V3 *ImageInternalTo_PS1_REF_V3 (Image *in, off_t Nvalues) {
+
+  off_t i;
+  Image_PS1_REF_V3 *out;
+
+  ALLOCATE_ZERO (out, Image_PS1_REF_V3, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    // this is only safe because the initial 120 bytes in Coords match CoordsDisk
+    memcpy (&out[i].coords, &in[i].coords, sizeof(CoordsDisk));
+
+    // RAW_IMAGE_NAME_LEN > DVO_IMAGE_NAME_LEN
+    strncpy (out[i].name, in[i].name, DVO_IMAGE_NAME_LEN - 1);
+    out[i].name[DVO_IMAGE_NAME_LEN - 1] = 0; // force termination
+
+    out[i].tzero    	    = in[i].tzero;
+    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].McalPSF;
+    out[i].dMcal    	    = in[i].dMcal;
+    out[i].Xm	    	    = 100.0*log10(in[i].McalChiSq);
+
+    out[i].photcode   	    = in[i].photcode;
+    out[i].exptime  	    = in[i].exptime;
+    out[i].sidtime  	    = in[i].sidtime;
+    out[i].latitude  	    = in[i].latitude;
+    out[i].detection_limit  = in[i].detection_limit;
+    out[i].saturation_limit = in[i].saturation_limit;
+    out[i].cerror	    = in[i].cerror;
+    out[i].fwhm_x	    = in[i].fwhm_x;
+    out[i].fwhm_y	    = in[i].fwhm_y;
+    out[i].trate	    = in[i].trate;
+    out[i].ccdnum	    = in[i].ccdnum;
+    out[i].flags	    = in[i].flags;
+    out[i].imageID	    = in[i].imageID;
+    out[i].parentID	    = in[i].parentID;
+    out[i].externID	    = in[i].externID;
+    out[i].sourceID	    = in[i].sourceID;
+
+    // as of 2011.02.03, the old Mx,My,..., Mxxxx,Myyyy have been deprecated and replaced
+    // with the following.  (no real databases used those values -- see
+    // libdvo/doc/dvo-images.txt)
+    out[i].nLinkAstrom	    = in[i].nLinkAstrom;
+    out[i].nLinkPhotom	    = in[i].nLinkPhotom;
+    out[i].dummy3	    = in[i].ubercalDist; // new name PS1_V3
+    out[i].dXpixSys	    = in[i].dXpixSys;
+    out[i].dYpixSys	    = in[i].dYpixSys;
+    out[i].dMagSys	    = in[i].dMagSys;
+    out[i].nFitAstrom       = in[i].nFitAstrom;
+    out[i].nFitPhotom       = in[i].nFitPhotom;
+    out[i].photom_map_id    = in[i].photom_map_id;
+    out[i].astrom_map_id    = in[i].astrom_map_id;
+  }
+  return (out);
+}
+
+PhotCode *PhotCode_PS1_REF_V3_To_Internal (PhotCode_PS1_REF_V3 *in, off_t Nvalues) {
+
+  off_t i;
+  PhotCode *out;
+
+  ALLOCATE_ZERO (out, PhotCode, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    strncpy (out[i].name, in[i].name, 31); // out[32], in[32]
+    out[i].name[31] = 0; // force termination
+
+    out[i].code  = in[i].code;         
+    out[i].type  = in[i].type;         
+    out[i].C     = in[i].C;            
+    out[i].dC 	 = in[i].dC;           
+    out[i].dX 	 = in[i].dX;           
+    out[i].K  	 = in[i].K;            
+    out[i].c1 	 = in[i].c1;           
+    out[i].c2 	 = in[i].c2;           
+    out[i].equiv = in[i].equiv;        
+    out[i].Nc    = in[i].Nc;           
+    memcpy (out[i].X, in[i].X, 4*sizeof(float));            
+
+    out[i].astromErrSys      = in[i].astromErrSys;
+    out[i].astromErrScale    = in[i].astromErrScale;
+    out[i].astromErrMagScale = in[i].astromErrMagScale;
+    out[i].photomErrSys      = in[i].photomErrSys;
+
+    out[i].photomPoorMask      = in[i].photomPoorMask;
+    out[i].photomBadMask       = in[i].photomBadMask;
+    out[i].astromPoorMask      = in[i].astromPoorMask;
+    out[i].astromBadMask       = in[i].astromBadMask;
+  }
+  return (out);
+}
+
+PhotCode_PS1_REF_V3 *PhotCode_Internal_To_PS1_REF_V3 (PhotCode *in, off_t Nvalues) {
+
+  off_t i;
+  PhotCode_PS1_REF_V3 *out;
+
+  ALLOCATE_ZERO (out, PhotCode_PS1_REF_V3, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    strncpy (out[i].name, in[i].name, 31); // out[32], in[32]
+    out[i].name[31] = 0; // force termination
+
+    out[i].code  = in[i].code;         
+    out[i].type  = in[i].type;         
+    out[i].C     = in[i].C;            
+    out[i].dC 	 = in[i].dC;           
+    out[i].dX 	 = in[i].dX;           
+    out[i].K  	 = in[i].K;            
+    out[i].c1 	 = in[i].c1;           
+    out[i].c2 	 = in[i].c2;           
+    out[i].equiv = in[i].equiv;        
+    out[i].Nc    = in[i].Nc;           
+    memcpy (out[i].X, in[i].X, 4*sizeof(float));            
+
+    out[i].astromErrSys      = in[i].astromErrSys;
+    out[i].astromErrScale    = in[i].astromErrScale;
+    out[i].astromErrMagScale = in[i].astromErrMagScale;
+    out[i].photomErrSys      = in[i].photomErrSys;
+
+    out[i].photomPoorMask      = in[i].photomPoorMask;
+    out[i].photomBadMask       = in[i].photomBadMask;
+    out[i].astromPoorMask      = in[i].astromPoorMask;
+    out[i].astromBadMask       = in[i].astromBadMask;
+  }
+  return (out);
+}
Index: /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libdvo/src/dvo_image.c
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libdvo/src/dvo_image.c	(revision 42802)
+++ /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libdvo/src/dvo_image.c	(revision 42803)
@@ -226,4 +226,6 @@
   if (db[0].format == DVO_FORMAT_PS1_V5_LOAD)     gfits_modify (&db[0].header, "FORMAT", "%s", 1, "PS1_V5_LOAD");
   if (db[0].format == DVO_FORMAT_PS1_REF)         gfits_modify (&db[0].header, "FORMAT", "%s", 1, "PS1_REF");
+  if (db[0].format == DVO_FORMAT_PS1_REF_V2)      gfits_modify (&db[0].header, "FORMAT", "%s", 1, "PS1_REF_V2");
+  if (db[0].format == DVO_FORMAT_PS1_REF_V3)      gfits_modify (&db[0].header, "FORMAT", "%s", 1, "PS1_REF_V3");
   if (db[0].format == DVO_FORMAT_PS1_SIM)         gfits_modify (&db[0].header, "FORMAT", "%s", 1, "PS1_SIM");
   
Index: /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libdvo/src/dvo_image_raw.c
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libdvo/src/dvo_image_raw.c	(revision 42802)
+++ /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/libdvo/src/dvo_image_raw.c	(revision 42803)
@@ -63,4 +63,6 @@
   if (db[0].format == DVO_FORMAT_PS1_V5_LOAD)     ImageSize = sizeof(Image_PS1_V5_LOAD);
   if (db[0].format == DVO_FORMAT_PS1_REF)         ImageSize = sizeof(Image_PS1_REF);
+  if (db[0].format == DVO_FORMAT_PS1_REF_V2)      ImageSize = sizeof(Image_PS1_REF_V2);
+  if (db[0].format == DVO_FORMAT_PS1_REF_V3)      ImageSize = sizeof(Image_PS1_REF_V3);
   if (db[0].format == DVO_FORMAT_PS1_SIM)         ImageSize = sizeof(Image_PS1_SIM);
 
@@ -97,4 +99,6 @@
   if (db[0].format == DVO_FORMAT_PS1_V5_LOAD)     gfits_table_mkheader_Image_PS1_V5_LOAD (&db[0].theader);
   if (db[0].format == DVO_FORMAT_PS1_REF)         gfits_table_mkheader_Image_PS1_REF (&db[0].theader);
+  if (db[0].format == DVO_FORMAT_PS1_REF_V2)      gfits_table_mkheader_Image_PS1_REF_V2 (&db[0].theader);
+  if (db[0].format == DVO_FORMAT_PS1_REF_V3)      gfits_table_mkheader_Image_PS1_REF_V3 (&db[0].theader);
   if (db[0].format == DVO_FORMAT_PS1_SIM)         gfits_table_mkheader_Image_PS1_SIM (&db[0].theader);
     
Index: /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/relphot/Makefile
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/relphot/Makefile	(revision 42802)
+++ /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/relphot/Makefile	(revision 42803)
@@ -82,6 +82,7 @@
 $(SRC)/setExclusions.$(ARCH).o 	 \
 $(SRC)/setMrelFinal.$(ARCH).o 	 \
-$(SRC)/setMrelCatalog.$(ARCH).o 	 \
-$(SRC)/BoundaryTreeOps.$(ARCH).o 	 \
+$(SRC)/setMrelCatalog.$(ARCH).o   \
+$(SRC)/BoundaryTreeOps.$(ARCH).o  \
+$(SRC)/DumpAllMags.$(ARCH).o      \
 $(SRC)/write_coords.$(ARCH).o
 
Index: /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/relphot/include/relphot.h
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/relphot/include/relphot.h	(revision 42802)
+++ /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/relphot/include/relphot.h	(revision 42803)
@@ -160,4 +160,7 @@
   float dY; // bin = int(Ychip * dY), dY = Ny / NyChip
   // NxChip, NyChip = 4900,4900 for now
+
+    int **nAlloc; // allocated vector length
+  double ***dMval; // values used to calculate corrections
 } GridCorrectionType;
 
@@ -607,4 +610,5 @@
 void          initGridBins        PROTO((void));
 GridCorrectionType *getGridCorrByCode PROTO((int code));
+GridCorrectionType *newGridCorrByCode PROTO((int code));
 GridCorrectionType *getGridCorrNext   PROTO((int *Nlast));
 int           GridCorrectionSave  PROTO((void));
@@ -894,2 +898,4 @@
 double get_median_zpt_tgroups (short photcode);
 void   set_median_zpt_tgroups (short photcode, double zpt);
+
+int DumpAllMags(char *filename, Catalog *catalog, int Ncatalog);
Index: /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/relphot/src/DumpAllMags.c
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/relphot/src/DumpAllMags.c	(revision 42803)
+++ /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/relphot/src/DumpAllMags.c	(revision 42803)
@@ -0,0 +1,231 @@
+# include "relphot.h"
+
+// STATUS is value expected for success
+# define CHECK_STATUS(STATUS,MSG,...)					\
+  if (!(STATUS)) {							\
+    fprintf (stderr, MSG, __VA_ARGS__);					\
+    return FALSE;							\
+  }
+
+int DumpAllMags(char *filename, Catalog *catalog, int Ncatalog) {
+
+  Header header;
+  Header theader;
+  Matrix matrix;
+  FTable ftable;
+
+  gfits_init_header (&header);
+  header.extend = TRUE;
+  gfits_create_header (&header);
+  gfits_create_matrix (&header, &matrix);
+
+  gfits_create_table_header (&theader, "BINTABLE", "DATA");
+
+  gfits_define_bintable_column (&theader, "D", "RA",       "ra",                         "degree", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "D", "DEC",      "dec",                        "degree", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E", "MCAL",     "", "", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E", "MGRP",     "", "", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E", "MMOS",     "", "", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E", "MFLT",     "", "", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E", "MGRD",     "", "", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E", "MREL",     "", "", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E", "MSYS",     "", "", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E", "MOFF",     "", "", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E", "AIRMASS",  "", "unitless", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "D", "MJD",      "", "unitless", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E", "EXPTIME",  "", "unitless", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "J", "PHOTCODE", "", "unitless", 1.0, FT_BZERO_INT32);
+  gfits_define_bintable_column (&theader, "J", "IX",       "", "unitless", 1.0, FT_BZERO_INT32);
+  gfits_define_bintable_column (&theader, "J", "IY",       "", "unitless", 1.0, FT_BZERO_INT32);
+  gfits_define_bintable_column (&theader, "J", "XCCD",     "", "unitless", 1.0, FT_BZERO_INT32);
+  gfits_define_bintable_column (&theader, "J", "YCCD",     "", "unitless", 1.0, FT_BZERO_INT32);
+
+  // generate the output array that carries the data
+  gfits_create_table (&theader, &ftable);
+
+  // count the max number of measurements:
+  int NptsMax = 0;
+  for (int nc = 0; nc < Ncatalog; nc++) {
+    for (int na = 0; na < catalog[nc].Naverage; na++) {
+
+      int nm = catalog[nc].averageT[na].measureOffset;
+      for (int k = 0; k < catalog[nc].averageT[na].Nmeasure; k++, nm++) {
+	NptsMax++;
+      }
+    }
+  }
+
+  // create intermediate storage arrays
+  ALLOCATE_PTR (Rs,       double, NptsMax);
+  ALLOCATE_PTR (Ds,       double, NptsMax);
+  ALLOCATE_PTR (Mcal,     float,  NptsMax);
+  ALLOCATE_PTR (Mgrp,     float,  NptsMax);
+  ALLOCATE_PTR (Mmos,     float,  NptsMax);
+  ALLOCATE_PTR (Mflt,     float,  NptsMax);
+  ALLOCATE_PTR (Mgrd,     float,  NptsMax);
+  ALLOCATE_PTR (Mrel,     float,  NptsMax);
+  ALLOCATE_PTR (Msys,     float,  NptsMax);
+  ALLOCATE_PTR (Moff,     float,  NptsMax);
+  ALLOCATE_PTR (airmass,  float,  NptsMax);
+  ALLOCATE_PTR (mjd,      double, NptsMax);
+  ALLOCATE_PTR (exptime,  float,  NptsMax);
+  ALLOCATE_PTR (photcode, int,    NptsMax);
+  ALLOCATE_PTR (iX,       int,    NptsMax);
+  ALLOCATE_PTR (iY,       int,    NptsMax);
+  ALLOCATE_PTR (Xccd,     int,    NptsMax);
+  ALLOCATE_PTR (Yccd,     int,    NptsMax);
+
+  // XXXX fill in the vectors here
+  int Nsecfilt = GetPhotcodeNsecfilt ();
+
+  int Npts = 0;
+  for (int nc = 0; nc < Ncatalog; nc++) {
+    for (int na = 0; na < catalog[nc].Naverage; na++) {
+
+      int nm = catalog[nc].averageT[na].measureOffset;
+      for (int k = 0; k < catalog[nc].averageT[na].Nmeasure; k++, nm++) {
+
+	// skip measurements marked by AREA or TIME
+	if (catalog[nc].measureT[nm].dbFlags & MEAS_BAD) continue;
+
+	Mcal[Npts] = getMcal  (nm, nc, MAG_CLASS_PSF);
+	if (isnan(Mcal[Npts])) continue;
+
+	Mgrp[Npts] = getMgrp  (nm, nc, catalog[nc].measureT[nm].airmass, NULL);
+	if (isnan(Mgrp[Npts])) continue;
+
+	Mmos[Npts]  = getMmos  (nm, nc);
+	if (isnan(Mmos[Npts])) continue;
+
+	Mflt[Npts] = getMflat (nm, nc, catalog);
+	if (isnan(Mflt[Npts])) continue;
+
+	// Mrel* is the average magnitude for this star.  For PS1 stacks, we have too much
+	// PSF variability.  We need to calibrate the PSF magnitudes separately from the
+	// Aperture-like magnitues.  (We have an option to use the kron magnitudes or the
+	// other apertures here).  I basically need to do this analysis separately for each
+	// magnitude type
+    
+	// XXX works if we stop loop here
+	// Npts ++;
+	// continue;
+
+	Mrel[Npts] = getMrel  (catalog, nm, nc, MAG_CLASS_PSF, MAG_SRC_CHP);
+	if (isnan(Mrel[Npts])) continue;
+      
+	Msys[Npts] = PhotSysTiny (&catalog[nc].measureT[nm], &catalog[nc].averageT[na], &catalog[nc].secfilt[na*Nsecfilt], MAG_CLASS_PSF);
+	if (isnan(Msys[Npts])) continue;
+
+	Mgrd[Npts] = getMgridTiny (&catalog[nc].measureT[nm]); 
+	if (isnan(Mgrd[Npts])) continue;
+
+	Moff[Npts] = Mcal[Npts] + Mgrp[Npts] + Mmos[Npts] + Mflt[Npts] + Mgrd[Npts];
+
+	photcode[Npts] = catalog[nc].measureT[nm].photcode;
+
+	if (GRID_ZEROPT) {
+	  GridCorrectionType *grid = getGridCorrByCode(photcode[Npts]);
+	  if (!grid) continue; // does not match one of our images, skip
+
+	  // edge effects could cause some positions to be slightly out of range
+	  // probably should trap extreme outliers
+	  iX[Npts] = MIN(MAX(0, (int)(catalog[nc].measureT[nm].Xccd * grid->dX)), grid->Nx - 1);
+	  iY[Npts] = MIN(MAX(0, (int)(catalog[nc].measureT[nm].Yccd * grid->dY)), grid->Ny - 1);
+	} else {
+	  iX[Npts] = 0;
+	  iY[Npts] = 0;
+	}
+
+	Xccd[Npts] = catalog[nc].measureT[nm].Xccd;
+	Yccd[Npts] = catalog[nc].measureT[nm].Yccd;
+
+	Rs[Npts] = catalog[nc].measureT[nm].R;
+	Ds[Npts] = catalog[nc].measureT[nm].D;
+
+	airmass[Npts] = catalog[nc].measureT[nm].airmass;
+
+	exptime[Npts] = 0.0; // catalog[nc].measureT[nm].dt;
+	mjd[Npts]     = 0.0; // ohana_sec_to_mjd (catalog[nc].measureT[nm].tzero);
+
+	Npts ++;
+      }
+    }
+  }
+
+  // add the columns to the output array
+  gfits_set_bintable_column (&theader, &ftable, "RA",       Rs,       Npts);
+  gfits_set_bintable_column (&theader, &ftable, "DEC",      Ds,       Npts);
+  gfits_set_bintable_column (&theader, &ftable, "MCAL",     Mcal,     Npts);
+  gfits_set_bintable_column (&theader, &ftable, "MGRP",     Mgrp,     Npts);
+  gfits_set_bintable_column (&theader, &ftable, "MMOS",     Mmos,     Npts);
+  gfits_set_bintable_column (&theader, &ftable, "MFLT",     Mflt,     Npts);
+  gfits_set_bintable_column (&theader, &ftable, "MGRD",     Mgrd,     Npts);
+  gfits_set_bintable_column (&theader, &ftable, "MREL",     Mrel,     Npts);
+  gfits_set_bintable_column (&theader, &ftable, "MSYS",     Msys,     Npts);
+  gfits_set_bintable_column (&theader, &ftable, "MOFF",     Moff,     Npts);
+  gfits_set_bintable_column (&theader, &ftable, "AIRMASS",  airmass,  Npts);
+  gfits_set_bintable_column (&theader, &ftable, "MJD",      mjd,      Npts);
+  gfits_set_bintable_column (&theader, &ftable, "EXPTIME",  exptime,  Npts);
+  gfits_set_bintable_column (&theader, &ftable, "PHOTCODE", photcode, Npts);
+  gfits_set_bintable_column (&theader, &ftable, "IX",       iX,       Npts);
+  gfits_set_bintable_column (&theader, &ftable, "IY",       iY,       Npts);
+  gfits_set_bintable_column (&theader, &ftable, "XCCD",     Xccd,     Npts);
+  gfits_set_bintable_column (&theader, &ftable, "YCCD",     Yccd,     Npts);
+
+  free (Rs);
+  free (Ds);
+  free (Mcal);
+  free (Mgrp);
+  free (Mmos);
+  free (Mflt);
+  free (Mgrd);
+  free (Mrel);
+  free (Msys);
+  free (Moff);
+  free (airmass);
+  free (mjd);
+  free (exptime);
+  free (photcode);
+  free (iX);
+  free (iY);
+  free (Xccd);
+  free (Yccd);
+
+  FILE *f = fopen (filename, "w");
+  if (!f) {
+    fprintf (stderr, "ERROR: cannot open meanmag file for output %s\n", filename);
+    return FALSE;
+  }
+
+  int status;
+  status = gfits_fwrite_header  (f, &header);
+  CHECK_STATUS (status, "ERROR: cannot write header for meanmags %s\n", filename);
+
+  status = gfits_fwrite_matrix  (f, &matrix);
+  CHECK_STATUS (status, "ERROR: cannot write matrix for meanmags %s\n", filename);
+
+  status = gfits_fwrite_Theader (f, &theader);
+  CHECK_STATUS (status, "ERROR: cannot write table header for meanmags %s\n", filename);
+
+  status = gfits_fwrite_table  (f, &ftable);
+  CHECK_STATUS (status, "ERROR: cannot write table data for meanmags %s\n", filename);
+
+  gfits_free_header (&header);
+  gfits_free_matrix (&matrix);
+  gfits_free_header (&theader);
+  gfits_free_table (&ftable);
+
+  int fd = fileno (f);
+
+  status = fflush (f);
+  CHECK_STATUS (!status, "ERROR: cannot flush file mags %s\n", filename);
+
+  status = fsync (fd);
+  CHECK_STATUS (!status, "ERROR: cannot flush file mags %s\n", filename);
+
+  status = fclose (f);
+  CHECK_STATUS (!status, "ERROR: problem closing mags file %s\n", filename);
+
+  return TRUE;
+}
+
Index: /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/relphot/src/GridIO.c
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/relphot/src/GridIO.c	(revision 42802)
+++ /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/relphot/src/GridIO.c	(revision 42803)
@@ -151,5 +151,5 @@
 
     if (!gfits_scan (&header, "PHOTCODE", "%d", 1, &photcode))    myAbort ("failed to get PHOTCODE");
-    GridCorrectionType *GridCorr = getGridCorrByCode (photcode);
+    GridCorrectionType *GridCorr = newGridCorrByCode (photcode);
     GridCorr->photcode = photcode;
 
Index: /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/relphot/src/GridOps.c
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/relphot/src/GridOps.c	(revision 42802)
+++ /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/relphot/src/GridOps.c	(revision 42803)
@@ -30,6 +30,6 @@
 # define NX_CHIP_DEFAULT 1000
 # define NY_CHIP_DEFAULT 1000
-# define NX_BIN_DEFAULT 2
-# define NY_BIN_DEFAULT 2
+# define NX_BIN_DEFAULT 4
+# define NY_BIN_DEFAULT 4
 
 void initGridBins (void) {
@@ -76,4 +76,11 @@
       if (GridCorr[code]->dMgrid) FREE (GridCorr[code]->dMgrid[ix]);
       if (GridCorr[code]->nMgrid) FREE (GridCorr[code]->nMgrid[ix]);
+      if (GridCorr[code]->nAlloc) FREE (GridCorr[code]->nAlloc[ix]);
+
+      // dMval is a 2D array of vectors
+      for (int iy = 0; iy < GridCorr[code]->Ny; iy++) {
+	FREE (GridCorr[code]->dMval[ix][iy]);
+      }
+      FREE (GridCorr[code]->dMval[ix]);
     }      
 
@@ -81,4 +88,6 @@
     FREE (GridCorr[code]->dMgrid);
     FREE (GridCorr[code]->nMgrid);
+    FREE (GridCorr[code]->nAlloc);
+    FREE (GridCorr[code]-> dMval);
 
     FREE(GridCorr[code]);
@@ -109,5 +118,6 @@
 }
 
-GridCorrectionType *getGridCorrByCode (int code) {
+// generate a new GridCorr structure in the array
+GridCorrectionType *newGridCorrByCode (int code) {
 
   if (GridCorr == NULL) return NULL;
@@ -116,5 +126,18 @@
   if (code <          0) return NULL;
 
+  myAssert (GridCorr[code] == NULL, "oops, should not already be allocated!");
   ALLOCATE(GridCorr[code], GridCorrectionType, 1)
+  GridCorrectionType *result = GridCorr[code];
+  return result;
+}
+
+// return the GridCode structure corresponding to 'code'
+GridCorrectionType *getGridCorrByCode (int code) {
+
+  if (GridCorr == NULL) return NULL;
+
+  if (code >= NGridCorr) return NULL;
+  if (code <          0) return NULL;
+
   GridCorrectionType *result = GridCorr[code];
   return result;
@@ -163,11 +186,18 @@
     // we are normally accessing this array randomly, so there is no advantage to
     // doing Mgrid[y][x] vs Mgrid[x][y]
+    ALLOCATE (GridCorr[code]-> dMval, double **, NX_BIN);
     ALLOCATE (GridCorr[code]-> Mgrid, float *, NX_BIN);
     ALLOCATE (GridCorr[code]->dMgrid, float *, NX_BIN);
     ALLOCATE (GridCorr[code]->nMgrid,   int *, NX_BIN);
+    ALLOCATE (GridCorr[code]->nAlloc,   int *, NX_BIN);
     for (int ix = 0; ix < NX_BIN; ix++) {
       ALLOCATE (GridCorr[code]-> Mgrid[ix], float, NY_BIN);
       ALLOCATE (GridCorr[code]->dMgrid[ix], float, NY_BIN);
       ALLOCATE (GridCorr[code]->nMgrid[ix],   int, NY_BIN);
+      ALLOCATE (GridCorr[code]->nAlloc[ix],   int, NY_BIN);
+
+      // when we first allocate this array, set the elements to 0 (NULL)
+      // these arrays will be allocated or reallocated in resetMgrid
+      ALLOCATE_ZERO (GridCorr[code]-> dMval[ix], double *, NX_BIN);
     }      
   }
@@ -190,4 +220,12 @@
 	GridCorr[code]->dMgrid[ix][iy] = 0.0;
 	GridCorr[code]->nMgrid[ix][iy] =   0;
+	GridCorr[code]->nAlloc[ix][iy] = 100;
+
+	// allocate or reset vector length to default
+	if (GridCorr[code]->dMval[ix][iy]) {
+	  REALLOCATE (GridCorr[code]->dMval[ix][iy], double, GridCorr[code]->nAlloc[ix][iy]);
+	} else {
+	  ALLOCATE (GridCorr[code]->dMval[ix][iy], double, GridCorr[code]->nAlloc[ix][iy]);
+	}
       }
     }      
@@ -263,10 +301,49 @@
 	if (fabs(dM) > 0.5) continue;
 
-	grid-> Mgrid[ix][iy] += dM;
-	grid->dMgrid[ix][iy] += dM*dM;
+	int ival = grid->nMgrid[ix][iy];
+	grid-> dMval[ix][iy][ival] = dM;
 	grid->nMgrid[ix][iy] ++;
+	CHECK_REALLOCATE (grid-> dMval[ix][iy], double, grid->nAlloc[ix][iy], grid->nMgrid[ix][iy], 100);
+
+	/* XXX old code to calculate simple means:
+	   grid-> Mgrid[ix][iy] += dM;
+	   grid->dMgrid[ix][iy] += dM*dM;
+	   grid->nMgrid[ix][iy] ++;
+	*/
       }
     }
   }
+
+  StatType stats;
+  liststats_setmode (&stats, "MEDIAN");
+
+  // now calculate Mgrid, dMgrid, nMgrid from Sum, Sum, Npt
+  for (int code = 0; code < NGridCorr; code++) {
+    if (!GridCorr[code]) continue;
+
+    for (int ix = 0; ix < GridCorr[code]->Nx; ix++) {
+      for (int iy = 0; iy < GridCorr[code]->Ny; iy++) {
+
+	// cells without sufficient coverage stay at 0.0
+	if (GridCorr[code]->nMgrid[ix][iy] < 5) {
+	  GridCorr[code]-> Mgrid[ix][iy] = 0.0;
+	  GridCorr[code]->dMgrid[ix][iy] = 0.0;
+	  continue;
+	}
+
+	liststats_init (&stats);
+
+	liststats (GridCorr[code]->dMval[ix][iy], NULL, NULL, GridCorr[code]->nMgrid[ix][iy], &stats);
+	double altSigma = (stats.Upper80 - stats.Lower20) / 1.6;  // 20% to 80% encompasses 60% of the values, corresponds to the range (-0.85 sigma : +0.85 sigma)
+
+	GridCorr[code]-> Mgrid[ix][iy] = stats.median;
+	GridCorr[code]->dMgrid[ix][iy] = altSigma; // sample stdev
+      }
+    }
+  }
+  return;
+}
+
+# if (0)
 
   // now calculate Mgrid, dMgrid, nMgrid from Sum, Sum, Npt
@@ -300,7 +377,5 @@
     // float GridAve = GridSum / GridCnt;
     // fprintf (stderr, "grid average: %f\n", GridAve);
-  }
-  return;
-}
+# endif
 
 float getMgrid (Measure *measure) {
Index: /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/relphot/src/MagResidSave.c
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/relphot/src/MagResidSave.c	(revision 42802)
+++ /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/relphot/src/MagResidSave.c	(revision 42803)
@@ -54,18 +54,18 @@
   gfits_create_table_header (&theader, "BINTABLE", "MAG_PSF_RESID");
 
-  gfits_define_bintable_column (&theader, "D", "RA",       "ra",                         "degree", 1.0, 0.0);
-  gfits_define_bintable_column (&theader, "D", "DEC",      "dec",                        "degree", 1.0, 0.0);
-  gfits_define_bintable_column (&theader, "E", "MAG_RESID", "magnitude residual", "magnitudes", 1.0, 0.0);
-  gfits_define_bintable_column (&theader, "E", "MAG_ERROR", "magnitude error", "magnitudes", 1.0, 0.0);
-  gfits_define_bintable_column (&theader, "E", "MAG_CHISQ", "magnitude resid chisq", "unitless", 1.0, 0.0);
-  gfits_define_bintable_column (&theader, "E", "MAG_MEDIAN", "median magnitude residual", "magnitudes", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "D", "RA",         "ra",                           "degree",     1.0, 0.0);
+  gfits_define_bintable_column (&theader, "D", "DEC",        "dec",                          "degree",     1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E", "MAG_RESID",  "magnitude residual",           "magnitudes", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E", "MAG_ERROR",  "magnitude error",              "magnitudes", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E", "MAG_CHISQ",  "magnitude resid chisq",        "unitless",   1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E", "MAG_MEDIAN", "median magnitude residual",    "magnitudes", 1.0, 0.0);
   gfits_define_bintable_column (&theader, "E", "MAG_ALTSIG", "68 percentile range as sigma", "magnitudes", 1.0, 0.0);
-  gfits_define_bintable_column (&theader, "E", "AIRMASS",   "", "unitless", 1.0, 0.0);
-  gfits_define_bintable_column (&theader, "D", "MJD",       "", "unitless", 1.0, 0.0);
-  gfits_define_bintable_column (&theader, "E", "EXPTIME",   "", "unitless", 1.0, 0.0);
-  gfits_define_bintable_column (&theader, "J", "PHOTCODE",  "", "unitless", 1.0, 0.0);
-  gfits_define_bintable_column (&theader, "J", "FLAGS",     "image flags", "unitless",   1.0, 0.0);
-  gfits_define_bintable_column (&theader, "J", "NFIT",      "number of stars fitted", NULL, 1.0, FT_BZERO_INT32);
-  gfits_define_bintable_column (&theader, "J", "NMEAS",     "number of stars on image", NULL, 1.0, FT_BZERO_INT32);
+  gfits_define_bintable_column (&theader, "E", "AIRMASS",    "",                             "unitless",   1.0, 0.0);
+  gfits_define_bintable_column (&theader, "D", "MJD",        "",                             "unitless",   1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E", "EXPTIME",    "",                             "unitless",   1.0, 0.0);
+  gfits_define_bintable_column (&theader, "J", "PHOTCODE",   "",                             "unitless",   1.0, 0.0);
+  gfits_define_bintable_column (&theader, "J", "FLAGS",      "image flags",                  "unitless",   1.0, 0.0);
+  gfits_define_bintable_column (&theader, "J", "NFIT",       "number of stars fitted",       NULL,         1.0, 0.0);
+  gfits_define_bintable_column (&theader, "J", "NMEAS",      "number of stars on image",     NULL,         1.0, 0.0);
 
   // generate the output array that carries the data
Index: /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/relphot/src/relphot_images.c
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/relphot/src/relphot_images.c	(revision 42802)
+++ /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/relphot/src/relphot_images.c	(revision 42803)
@@ -147,4 +147,6 @@
     MagResidSave ("mag.resid.fits", catalog);
 
+    // DumpAllMags ("all.mags.fits", catalog, Ncatalog);
+
     save_images_updates (&db);
 
Index: /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/relphot/src/setMrelCatalog.c
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/relphot/src/setMrelCatalog.c	(revision 42802)
+++ /branches/eam_branches/ipp-ppmerge-20241229/Ohana/src/relphot/src/setMrelCatalog.c	(revision 42803)
@@ -412,4 +412,9 @@
       secfilt[Nsec].flags |= ID_SECF_HAS_CFH;
     }
+//  secfilt[Nsec].flags |= ID_SECF_AST_GAIA ; // for building reference catalog only, STAR_FEW need to comment out
+//  secfilt[Nsec].flags |= ID_SECF_PHO_SYNTH; // for building reference catalog only, STAR_FEW need to comment out
+//  secfilt[Nsec].flags |= ID_SECF_PHO_ATLAS; // for building reference catalog only, STAR_FEW need to comment out
+//  secfilt[Nsec].flags |= ID_SECF_PHO_PV3  ; // for building reference catalog only, STAR_FEW need to comment out
+//  secfilt[Nsec].flags |= ID_SECF_PHO_SOUTH; // for building reference catalog only, STAR_FEW need to comment out
 
     // if -preserve-ps1 is set and this object has PS1 data, skip the rest of the steps:
Index: /branches/eam_branches/ipp-ppmerge-20241229/PS-IPP-Config/lib/PS/IPP/Config.pm
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/PS-IPP-Config/lib/PS/IPP/Config.pm	(revision 42802)
+++ /branches/eam_branches/ipp-ppmerge-20241229/PS-IPP-Config/lib/PS/IPP/Config.pm	(revision 42803)
@@ -1368,4 +1368,28 @@
 
 
+# Return array of the instances for this nebulous file
+sub find_instances
+{
+    my $self = shift;
+    my $file = shift;
+
+    my $scheme = file_scheme($file);
+    if (!$scheme or ($scheme ne 'neb')) {
+	# if not nebulous, the instance is the file
+	my @result;
+        push @result, $file;
+	return (\@result);
+    }
+
+    my $neb = $self->nebulous;
+    my $uris;
+    eval { $uris = $neb->find_instances($file); };
+    if ($@) { 
+	carp "failed to set user.copies for $file";
+        return 0;
+    }
+    return $uris;
+}
+
 # Return catdir for tessellation, from TESSELLATIONS within the site configuration
 sub tessellation_catdir
Index: /branches/eam_branches/ipp-ppmerge-20241229/extsrc/gpcsw/gpcsrc/fits/burntool/persistio.c
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/extsrc/gpcsw/gpcsrc/fits/burntool/persistio.c	(revision 42802)
+++ /branches/eam_branches/ipp-ppmerge-20241229/extsrc/gpcsw/gpcsrc/fits/burntool/persistio.c	(revision 42803)
@@ -312,4 +312,5 @@
 		    cell[j].burn[k].fiterr != FIT_TOP_ERROR) continue;
 	       if(cell[j].burn[k].nfit <= 0) continue;
+	       /*kick out burns which are single pixels*/
 	     }
 	    } else {
@@ -317,4 +318,6 @@
 	       cell[j].burn[k].fiterr != FIT_TOP_ERROR) continue;
 	     if(cell[j].burn[k].nfit <= 0) continue;
+	     /*kick out burns which are single pixels*/
+
 	    }
 
Index: /branches/eam_branches/ipp-ppmerge-20241229/extsrc/gpcsw/gpcsrc/fits/burntool/stardetect.c
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/extsrc/gpcsw/gpcsrc/fits/burntool/stardetect.c	(revision 42802)
+++ /branches/eam_branches/ipp-ppmerge-20241229/extsrc/gpcsw/gpcsrc/fits/burntool/stardetect.c	(revision 42803)
@@ -34,8 +34,14 @@
    starcut = STAR_THRESH/2 + cell->sky + cell->bias;
 
-   /*try a new value for thresh_lo which is 1 sigmas above the background, but with a safety limit of 1000 counts*/
+   /*try a new value for thresh_lo which is 10 sigmas above the background, but with a safety limit of 1000 counts*/
 	trailthresh = cell->sky + (10*cell->rms);
 	if(trailthresh <= 1000) trailthresh = 1000;
 	trailthresh = trailthresh + cell->bias;
+	thresh_lo = trailthresh;
+
+   /*try a new value for burnthresh which is twice the bias above the sky background, but with a safety limit of 30000 counts*/
+	burnthresh = cell->sky + (2*cell->bias);
+	if(burnthresh <= BURN_THRESH) burnthresh = BURN_THRESH;
+	thresh_hi = burnthresh;
 
 /* Look at all the pixels which pass the burn threshold */
@@ -81,4 +87,5 @@
 	        boxbuf[nbox].ey = k-1;
 	        grow_box(nx, ny, NX, data, thresh_lo, boxbuf+nbox);
+		
            /* Fill in max and center info */
 	        boxbuf[nbox].max = 0;
@@ -100,4 +107,22 @@
 			     boxbuf[nbox].ex, boxbuf[nbox].ey,
 			     boxbuf[nbox].max);
+		        fflush(stdout);
+	          }
+/* Mark the veto mask so as not to trigger on this one again */
+	          for(l=boxbuf[nbox].sy; l<=boxbuf[nbox].ey; l++) {
+		         for(k=boxbuf[nbox].sx; k<=boxbuf[nbox].ex; k++) {
+		          veto[k+l*NX] = boxbuf[nbox].max;
+		         }
+	          }
+	          xon = -1;
+	          continue;
+	        }
+
+/* A box that is composed of a single pixel should not be considered a burn */
+	        if((boxbuf[nbox].ex - boxbuf[nbox].sx) <= 2 && (boxbuf[nbox].ey - boxbuf[nbox].sy) <= 2) {
+	          if(VERBOSE & VERB_DETECT) {
+		        printf("Ditching box %d %d %d %d  for being too small\n",
+			     boxbuf[nbox].sx, boxbuf[nbox].sy,
+			     boxbuf[nbox].ex, boxbuf[nbox].ey);
 		        fflush(stdout);
 	          }
Index: /branches/eam_branches/ipp-ppmerge-20241229/extsrc/gpcsw/gpcsrc/fits/burntool/trailfit.c
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/extsrc/gpcsw/gpcsrc/fits/burntool/trailfit.c	(revision 42802)
+++ /branches/eam_branches/ipp-ppmerge-20241229/extsrc/gpcsw/gpcsrc/fits/burntool/trailfit.c	(revision 42803)
@@ -290,5 +290,4 @@
 
    if(!strcmp(camera,"gpc2")) {
-
      /*Conpute the mean and standard deviation of the trail along x*/
      for(i=xs; i<=xe; i++) {
@@ -384,5 +383,5 @@
      }
      /* Update fit ranges */
-     if(box->nfit > 0) {
+     if(box->nfit > 1) {
         box->sxfit = box->xfit[0];
         box->exfit = box->xfit[box->nfit-1];
Index: /branches/eam_branches/ipp-ppmerge-20241229/ippMonitor/INSTALL
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/ippMonitor/INSTALL	(revision 42802)
+++ /branches/eam_branches/ipp-ppmerge-20241229/ippMonitor/INSTALL	(revision 42803)
@@ -39,5 +39,9 @@
 # $CZARPLOTDIR and $METRICSPLOTDIR will be generated as links in the same folder as ippMonitor  
 # the structure of the names for these two directories are defined in Makefile.in a
-psconfigure --htdocs /var/www/localhost/htdocs --wwwbin /var/www/localhost/wwwbin --pltdir /some/path --site ~/ippconfig/ippmonitor.config 
+# pltdir is for ippMetrics and czartool_plots hyperlinked from /export/ipp113.0/ipp/ in /var/www/localhost/htdocs/ippMonitor
+# pltdir in ipp117 is /var/www/localhost/htdocs/ippMonitor
+# ippMetrics -> /export/ipp113.0/ipp/ippMetrics/
+# czartool_plots -> /export/ipp113.0/ipp/czartool_plots/
+psconfigure --htdocs /var/www/localhost/htdocs --wwwbin /var/www/localhost/wwwbin --pltdir /var/www/localhost/htdocs/ippMonitor --site ~/ippconfig/ippmonitor.config 
 
 ## NOTES:
Index: /branches/eam_branches/ipp-ppmerge-20241229/ippMonitor/Makefile.in
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/ippMonitor/Makefile.in	(revision 42802)
+++ /branches/eam_branches/ipp-ppmerge-20241229/ippMonitor/Makefile.in	(revision 42803)
@@ -92,4 +92,6 @@
 $(DESTWWW)/scatterPlotAirmassMcal.php \
 $(DESTWWW)/scatterPlotDataQuality.php \
+$(DESTWWW)/dataquality.php \
+$(DESTWWW)/pointing.php \
 $(DESTWWW)/loader.js
 
Index: /branches/eam_branches/ipp-ppmerge-20241229/ippMonitor/czartool/czarpoll.pl
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/ippMonitor/czartool/czarpoll.pl	(revision 42802)
+++ /branches/eam_branches/ipp-ppmerge-20241229/ippMonitor/czartool/czarpoll.pl	(revision 42803)
@@ -380,4 +380,9 @@
         }
 
+        # check ippdb host IPP-2338
+        print "* Checking ippdb hosts\n";
+        my @hosts = qw(ipphome0 ipphome1 ippdb01 ippdb05 ippdb06 ippdb09 ippdb11 ippdb12 ippdb13 ippdb14);
+        if($dbupdate == 1) {check_disk_usage_and_update($czarDb, @hosts);}
+
         # check pantasks status
         if($dbupdate == 1) {updateServerStatus();}
@@ -604,2 +609,48 @@
 }
 
+###########################################################################
+#
+# Loops through given host and update to the host list
+#
+###########################################################################
+sub check_disk_usage_and_update {
+    my ($czarDb, @hosts) = @_;
+
+    foreach my $host (@hosts) {
+        print "Checking $host...\n";
+
+        for my $suffix (0, 1) {
+            my $mount_point = "/export/$host.$suffix";
+
+            # Use SSH to get disk stats
+            my $df_output = `ssh $host df -k $mount_point 2>/dev/null`;
+
+            #if (!$df_output || $df_output !~ /\d/) {
+            #    warn "Failed to get disk usage for $host on $mount_point\n";
+            #    next;
+            #}
+
+            my @lines = split /\n/, $df_output;
+            my $line = $lines[1] || next;
+
+            my ($filesystem, $blocks, $used, $available, $percent, $mount) = split /\s+/, $line;
+
+            # Convert KB to TB
+            my $total_tb     = sprintf("%.1f", $blocks    / 1024 / 1024 / 1024);
+            my $used_tb      = sprintf("%.1f", $used      / 1024 / 1024 / 1024);
+            my $available_tb = sprintf("%.1f", $available / 1024 / 1024 / 1024);
+
+            my $used_percent      = sprintf("%.3f", $used / $blocks * 100);
+            my $available_percent = sprintf("%.3f", $available / $blocks * 100);
+
+            my $readable = 1;
+            my $writable = 1;
+
+            #print "Mount $mount_point: total=${total_tb}TB, used=${used_tb}TB (${used_percent}%), available=${available_tb}TB (${available_percent}%)\n";
+
+            # Example: ippdb01.0(3.5T)
+            my $host_label = "$host.$suffix(${total_tb}T)";
+            $czarDb->updateHost($host_label, 100, $available_percent, $used_percent, $readable, $writable);
+        }
+    }
+}
Index: /branches/eam_branches/ipp-ppmerge-20241229/ippMonitor/czartool/czartool/Nebulous.pm
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/ippMonitor/czartool/czartool/Nebulous.pm	(revision 42802)
+++ /branches/eam_branches/ipp-ppmerge-20241229/ippMonitor/czartool/czartool/Nebulous.pm	(revision 42803)
@@ -111,5 +111,5 @@
 
             next;
-        } elsif (($line =~ m/(ipp[0-9]+\.[0-9]{1})\s.+[0-9]+\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)%.*/i)||
+        } elsif (($line =~ m/(ipp[0-9]+(?:_bck)?\.[0-9]{1})\s.+[0-9]+\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)%.*/i)||
                ($line =~ m/(ippb[0-9]+\.[0-9]{1})\s.+[0-9]+\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)%.*/i)
 # these nodes are gone
Index: /branches/eam_branches/ipp-ppmerge-20241229/ippMonitor/czartool/czartool/Pantasks.pm
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/ippMonitor/czartool/czartool/Pantasks.pm	(revision 42802)
+++ /branches/eam_branches/ipp-ppmerge-20241229/ippMonitor/czartool/czartool/Pantasks.pm	(revision 42803)
@@ -10,5 +10,5 @@
         "cleanup", 
         "distribution", 
-        "pstamp", 
+        "ippitc:pstamp", 
         "registration", 
         "stack", 
@@ -22,4 +22,5 @@
         "ippqub:stdscience_ws",
         "ippqub2:stdscience_ws",
+        "ippsky:stdscience_ipp138",
         "publishing", 
         "replication", 
@@ -27,5 +28,5 @@
         );
 # current home dir of gpc1 and gpc2 
-my $ipphome1 = "/home/panstarrs/ippitc";
+my $ipphome1 = "/home/panstarrs/ippps1";
 my $ipphome2 = "/home/panstarrs/ippps2";
 
Index: /branches/eam_branches/ipp-ppmerge-20241229/ippMonitor/czartool/extra_labels.dat
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/ippMonitor/czartool/extra_labels.dat	(revision 42802)
+++ /branches/eam_branches/ipp-ppmerge-20241229/ippMonitor/czartool/extra_labels.dat	(revision 42803)
@@ -1,4 +1,6 @@
 ## TdB20190626: add extra labels for processing in this file. Syntax is as follows: [labelname] [telescope]
 ## Priorities for the labels must be added to the priorities mySQL table for the relevant telescope, if desired.
-PV3.Pole.Reprocess.20180510 gpc1
+## PV3.Pole.Reprocess.20180510 gpc1
 ps_ud_QUB gpc1
+## update.ipp138.fix gpc1
+## update.ipp138.fix gpc2
Index: /branches/eam_branches/ipp-ppmerge-20241229/ippMonitor/raw/czartool_labels.php
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/ippMonitor/raw/czartool_labels.php	(revision 42802)
+++ /branches/eam_branches/ipp-ppmerge-20241229/ippMonitor/raw/czartool_labels.php	(revision 42803)
@@ -87,5 +87,5 @@
         "distribution",
         "ippqub:stdscience_ws",
-        "pstamp",
+        "ippitc:pstamp",
         "registration",
 //        "stack",
@@ -1668,4 +1668,9 @@
     $qry = $db->query($sql);
     if (dberror($qry)) {echo "<b>error with $sql </b><br>\n";}
+
+    // Set environment variables
+    putenv("PATH=/usr/local/bin:/usr/bin:/bin:/data/ippc65.0/ipp/src/psconfig//ipp-20210708-gentoo.lin64/bin");
+    putenv("PERL5LIB=/data/ippc65.0/ipp/src/psconfig//ipp-20210708-gentoo.lin64/lib");
+
     # not sure why neb-host doesn't work on ipp113 CCL.20210216
     exec("neb-host |cut -b 17-30,86-", $hostnoteall);
Index: /branches/eam_branches/ipp-ppmerge-20241229/ippMonitor/raw/dataquality.php
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/ippMonitor/raw/dataquality.php	(revision 42803)
+++ /branches/eam_branches/ipp-ppmerge-20241229/ippMonitor/raw/dataquality.php	(revision 42803)
@@ -0,0 +1,522 @@
+<?php
+include 'ipp.php';
+include 'site.php';
+
+$ID = checkID();
+
+// require an explicit project
+if (! $ID['proj']) { projectform ($ID); }
+
+// connect to czarDb 
+$czardb = dbconnect($CZARDBNAME); 
+$projectdb = dbconnect($ID['proj']);
+
+if ($ID['menu']) {$myMenu = $ID['menu'];}
+else {$myMenu = "ipp.czar.dat";}
+
+menu($myMenu, 'Czartool on '.$lastUpdateTime, 'ipp.css', $ID['link'], $ID['proj']);
+
+$pass = $ID['pass'];
+$proj = $ID['proj'];
+$menu = $ID['menu'];
+
+// Fetch data based on range selection
+$range = isset($_GET['range']) ? $_GET['range'] : 'yday';
+
+echo "<table border=\"0\">";
+echo "<tr>";
+echo "  <td style=width:1240>";
+echo "    <h1 align=\"middle\">Data Quality Report</h1>";
+echo "  <center>";
+echo '    <a href="?pass=' . urlencode($pass) . '&proj=' . urlencode($proj) . '&range=yday">Last night (default)</a> | ';
+echo '    <a href="?pass=' . urlencode($pass) . '&proj=' . urlencode($proj) . '&range=day">Today (MJD '.getMJD().')</a> | ';
+echo '    <a href="?pass=' . urlencode($pass) . '&proj=' . urlencode($proj) . '&range=week">Past 7 days</a> | ';
+echo '    <a href="?pass=' . urlencode($pass) . '&proj=' . urlencode($proj) . '&range=month">Past 30 days</a> | ';
+echo '    <a href="?pass=' . urlencode($pass) . '&proj=' . urlencode($proj) . '&range=year">Past 365 days</a> | ';
+echo '    <a href="?pass=' . urlencode($pass) . '&proj=' . urlencode($proj) . '&range=all">All </a>   ';
+echo "  </td>";
+echo "</tr>";
+echo "</table>";
+echo getDataQuality($projectdb, $range);
+
+menu_end();
+
+/////////////////////////////////////////////////////////////////////////////
+//                                                                         //
+//                               Functions                                 //
+//                                                                         //
+/////////////////////////////////////////////////////////////////////////////
+
+###########################################################################
+#
+# Get data quality
+#
+###########################################################################
+function getDataQuality($db, $range = 'yday') {
+    // Start timer
+    $start = microtime(true);
+
+    $mjdDay  = getMJD();
+    $mjdDay_yearback = $mjdDay - 366;
+    $mjdDay_monthback = $mjdDay - 32;
+    $min_exp_id = 0;
+
+    // Determine the reference exp_name based on the selected range
+    switch ($range) {
+        case 'year':
+            $expname = "o" . $mjdDay_yearback . "%";
+            break;
+        case 'month':
+            $expname = "o" . $mjdDay_monthback . "%";
+            break;
+        case 'week':
+            $expname = "o" . ($mjdDay - 7) . "%";
+            break;
+        case 'day':
+            $expname = "o" . $mjdDay . "%";
+            break;
+        default:
+            $expname = "o" . ($mjdDay - 1) . "%"; // Default: last night
+            break;
+    }
+
+    // Query to get the minimum exp_id
+    $expIdQuery = "SELECT MIN(exp_id) AS min_exp_id FROM rawExp WHERE rawExp.exp_name LIKE '$expname'";
+    $result = $db->query($expIdQuery);
+
+    if (DB::isError($result)) {
+        die("Database error: " . $result->getMessage());
+    }
+
+    $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
+
+    if (!empty($row['min_exp_id'])) {
+        $min_exp_id = $row['min_exp_id'];
+    //    echo "Minimum exp_id: " . $min_exp_id;
+    } else {
+        echo "No results found.";
+    }
+
+    //echo "<br><br>";
+
+    // Determine the date constraint based on the range
+    switch ($range) {
+        case 'year':
+            $dateConstraint = "dateobs >= NOW() - INTERVAL 365 DAY AND rawExp.exp_id >= $min_exp_id";
+            break;
+        case 'month':
+            $dateConstraint = "dateobs >= NOW() - INTERVAL 30 DAY AND rawExp.exp_id >= $min_exp_id";
+            break;
+        case 'week':
+            $expnames = array();
+            for ($i = 0; $i < 7; $i++) {
+                $expnames[] = "rawExp.exp_name LIKE 'o" . ($mjdDay - $i) . "%'";
+            }
+            $dateConstraint = "(" . implode(" OR ", $expnames) . ") AND rawExp.exp_id >= $min_exp_id";
+            break;
+        case 'yday':
+            $dateConstraint = "rawExp.exp_name LIKE 'o" . ($mjdDay - 1) . "%' AND rawExp.exp_id >= $min_exp_id";
+            break;
+        case 'day':
+            $dateConstraint = "rawExp.exp_name LIKE 'o$mjdDay%' AND rawExp.exp_id >= $min_exp_id";
+            break;
+        case 'all':
+            $dateConstraint = "rawExp.exp_id >= 0";
+            break;
+        default: // Default to last night
+            $dateConstraint = "rawExp.exp_name LIKE 'o" . ($mjdDay - 1) . "%' AND rawExp.exp_id >= $min_exp_id";
+            break;
+    }
+
+    // Updated SQL query
+    $sql = "select * from (SELECT SUBTIME(dateobs, '10:00:00') AS time,
+                   round(( 367*YEAR(dateobs)- FLOOR((7 * (YEAR(dateobs) + FLOOR((MONTH(dateobs) + 9) / 12))) / 4) + FLOOR(275 * MONTH(dateobs) / 9)
+                   + DAY(dateobs) + 1721013.5 + (HOUR(dateobs) / 24.0) + (MINUTE(dateobs) / 1440.0) + (SECOND(dateobs) / 86400.0) - 2400000.5), 5) AS MJD,
+                   filter, comment, ra*180/pi() as RA, decl*180/pi() as DECL, exp_name, alt, az, fwhm_major, fwhm_minor, zpt_obs, zpt_stdev, rawExp.exp_id, camRun.label
+            FROM rawExp 
+            JOIN chipRun USING (exp_id) 
+            JOIN camRun USING (chip_id) 
+            JOIN camProcessedExp USING (cam_id)
+            WHERE $dateConstraint
+              AND exp_type = 'OBJECT'
+              AND camRun.state LIKE 'full'
+              AND camProcessedExp.fault = 0
+              AND camProcessedExp.zpt_obs != 0 ORDER BY RAND() limit 5000) as sub order by time;";
+
+    $DQarray = array();
+    $qry = $db->query($sql);
+    if (dberror($qry)) {
+        echo "<b>Error with $sql</b><br>\n";
+        return;
+    }
+    //    echo "$sql<br><br>\n";
+
+    while ($qry->fetchInto($row)) {
+        $DQarray[] = $row;
+    }
+
+    // Ensure $DQarray is not empty
+    if (empty($DQarray)) {
+        echo "<center><b> No data for MJD: $mjdDay </b></center>";
+        return; // Stop execution if no data to encode
+    }
+
+    // Convert data array to JSON for easier handling in JavaScript
+    $dataJson = json_encode($DQarray);
+
+    if ($dataJson === false) {
+        echo "<b>Error encoding JSON:</b> " . json_last_error_msg(); // Display any JSON encoding errors
+        return; // Stop execution if JSON encoding fails
+    }
+
+    echo "<script>console.log(" . json_encode($dataJson) . ");</script>"; // Log JSON output to console for debugging
+echo <<<HTML
+<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js" onerror="loadLocalGoogleCharts()"></script>
+
+<script type="text/javascript">
+    // Check if Google Charts library loaded successfully
+    window.addEventListener("load", function() {
+        if (typeof google === "undefined" || typeof google.charts === "undefined") {
+            loadLocalGoogleCharts();
+        }
+    });
+
+    // Function to load local version of Google Charts if CDN fails
+    function loadLocalGoogleCharts() {
+        console.warn("Google Charts CDN failed, loading local loader.js instead.");
+        var script = document.createElement("script");
+        script.src = "loader.js"; // Path to your local loader.js file
+        document.head.appendChild(script);
+    }
+</script>
+
+<script type="text/javascript">
+    google.charts.load('current', {packages: ['corechart']});
+
+    // Use the encoded JSON directly in JavaScript
+    const dataArray = JSON.parse('{$dataJson}'); // Directly parse the PHP JSON string
+
+    // draw FWHM vs MJD
+    function drawFWHMChart() {
+        var data = new google.visualization.DataTable();
+            data.addColumn('number', 'MJD');
+            data.addColumn('number', 'FWHM_major');
+            data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});
+            data.addColumn('number', 'FWHM_minor');
+            data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});
+            data.addColumn('number', 'seeing ~ 1"');
+            data.addColumn('number', 'seeing ~ 3"');
+
+        const rows = dataArray.map(row => {
+            const [timestamp, mjd, filter, comment, ra, dec, exp_name, alt, az, iq_fwhm_maj, iq_fwhm_min, zpt_obs, zpt_stdev, exp_id, cam_label] = row;
+
+            return [
+                parseFloat(mjd),      // Position Angle
+                parseFloat(iq_fwhm_maj),         // RA_offset (AST_R0)
+                "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label,
+                parseFloat(iq_fwhm_min),        // Dec_offset (AST_D0)
+                "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label,
+                4,
+                12
+            ];
+        });
+
+        data.addRows(rows);
+
+        // Extract the first MJD value from dataArray
+        //const firstMJD = dataArray.length > 0 ? parseFloat(dataArray[0][1]) : "N/A"; 
+        const firstMJD = dataArray.length > 0 ? Math.floor(parseFloat(dataArray[0][1])) : "N/A";
+        console.log("First MJD Value:", firstMJD);
+
+        const options = {
+            title: 'FWHM (MJD: '+firstMJD+')',
+            titleTextStyle: {color: 'black', fontSize: 15},
+            width: '100%',
+            height: 480,
+            legend: { position: 'top', alignment: 'center' },
+            series: {
+                0: { color: '#0000ff', pointSize: 2, lineWidth: 0. },
+                1: { color: '#33a532', pointSize: 2, lineWidth: 0. },
+                2: { color: 'red', lineWidth: 2, pointSize: 0 },
+                3: { color: 'red', lineWidth: 2, lineDashStyle: [8, 4], pointSize: 0 }
+            },
+            intervals: { color: 'red', lineWidth: 2, style: 'sticks' },
+            hAxis: {
+                title: 'MJD',
+                gridlines: {count: -1}
+            },
+            vAxis: {
+                title: 'FWHM (pixels)',
+            },
+            tooltip: { isHtml: true }, // Render tooltips as HTML
+            chartArea: {left: '8%', top: 60, right: '5%', bottom: 50}, // Adjust left and right
+            fontSize: 12,
+        };
+
+        const chart = new google.visualization.ScatterChart(document.getElementById('dq_div_fwhm'));
+        chart.draw(data, options);
+    }
+
+    // draw zoomed zerpoint vs mjd
+    function drawZOOMZPTChart() {
+        var data = new google.visualization.DataTable();
+        data.addColumn('number', 'MJD');
+
+        // Add columns for each filter type to handle separate colors
+        data.addColumn('number', 'g (24.563, 25.013)');
+        data.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});
+        data.addColumn({type: 'number', role: 'interval'});
+        data.addColumn({type: 'number', role: 'interval'});
+        data.addColumn('number', 'r (24.750, 24.840)');
+        data.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});
+        data.addColumn({type: 'number', role: 'interval'});
+        data.addColumn({type: 'number', role: 'interval'});
+        data.addColumn('number', 'i (24.611, 24.711)');
+        data.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});
+        data.addColumn({type: 'number', role: 'interval'});
+        data.addColumn({type: 'number', role: 'interval'});
+        data.addColumn('number', 'z (24.240, 24.300)');
+        data.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});
+        data.addColumn({type: 'number', role: 'interval'});
+        data.addColumn({type: 'number', role: 'interval'});
+        data.addColumn('number', 'y (23.320, 23.570)');
+        data.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});
+        data.addColumn({type: 'number', role: 'interval'});
+        data.addColumn({type: 'number', role: 'interval'});
+        data.addColumn('number', 'w (26.000, 26.300)');
+        data.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});
+        data.addColumn({type: 'number', role: 'interval'});
+        data.addColumn({type: 'number', role: 'interval'});
+
+        const rows = dataArray.map(row => {
+            const [timestamp, mjd, filter, comment, ra, dec, exp_name, alt, az, iq_fwhm_maj, iq_fwhm_min, zpt_obs, zpt_stdev, exp_id, cam_label] = row;
+
+            // Initialize all filter values as null
+            let zp_g = null, zp_r = null, zp_i = null, zp_z = null, zp_y = null, zp_w = null;
+
+            // Set the zeropoint offset based on filter and assign it to the correct series
+            switch (filter[0]) {
+                case 'g':
+                    zp_g = zpt_obs - 24.563;
+                    break;
+                case 'r':
+                    zp_r = zpt_obs - 24.750;
+                    break;
+                case 'i':
+                    zp_i = zpt_obs - 24.611;
+                    break;
+                case 'z':
+                    zp_z = zpt_obs - 24.240;
+                    break;
+                case 'y':
+                   zp_y = zpt_obs - 23.320;
+                    break;
+                case 'w':
+                    zp_w = zpt_obs - 26.000;
+                    break;
+            }
+
+            return [
+                parseFloat(mjd), // MJD value
+                zp_g, "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label,  
+parseFloat(zp_g - zpt_stdev), parseFloat(zp_g - zpt_stdev*-1),
+                zp_r, "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label,  
+parseFloat(zp_r - zpt_stdev), parseFloat(zp_r - zpt_stdev*-1),
+                zp_i, "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label,  
+parseFloat(zp_i - zpt_stdev), parseFloat(zp_i - zpt_stdev*-1),
+                zp_z, "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label,  
+parseFloat(zp_z - zpt_stdev), parseFloat(zp_z - zpt_stdev*-1),
+                zp_y, "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label,  
+parseFloat(zp_y - zpt_stdev), parseFloat(zp_y - zpt_stdev*-1),
+                zp_w, "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label,  
+parseFloat(zp_w - zpt_stdev), parseFloat(zp_w - zpt_stdev*-1)
+            ];
+        });
+
+        data.addRows(rows);
+
+        const options = {
+            title: 'Zeropoint zoom-in (MJD)',
+            titleTextStyle: { color: 'black', fontSize: 15 },
+            width: '100%',
+            height: 480,
+            legend: { position: 'top', alignment: 'start', maxLines: 3 },
+            series: {
+                0: { color: '#00f000', pointSize: 5, pointShape: 'circle',   linewidth: .0},  // 'g' filter
+                1: { color: '#f00000', pointSize: 5, pointShape: 'triangle', linewidth: .0},  // 'r' filter
+                2: { color: '#f05000', pointSize: 5, pointShape: 'square',   linewidth: .0},  // 'i' filter
+                3: { color: '#0050a0', pointSize: 5, pointShape: 'diamond',  linewidth: .0},  // 'z' filter
+                4: { color: '#ffe000', pointSize: 5, pointShape: 'star',     linewidth: .0},  // 'y' filter
+                5: { color: '#808080', pointSize: 5, pointShape: 'polygon',  linewidth: .0},  // 'w' filter
+            },
+            intervals: { color: 'red', lineWidth: .0, style: 'sticks' },
+            hAxis: {
+                title: 'MJD',
+                gridlines: { count: -1 }
+            },
+            vAxis: {
+                title: 'Zeropoint (mag)',
+                viewWindow: {   min: -1.00, max: .5    },
+            },
+            tooltip: { isHtml: true },
+            chartArea: { left: '9%', top: 60, right: '5%', bottom: 50 },
+            fontSize: 12,
+        };
+
+        const chart = new google.visualization.ScatterChart(document.getElementById('dq_div_zoomzpt'));
+        chart.draw(data, options);
+    }
+
+    // draw zeropoint vs mjd
+    function drawZPTChart() {
+        var data = new google.visualization.DataTable();
+        data.addColumn('number', 'MJD');
+
+        // Add columns for each filter type to handle separate colors
+        data.addColumn('number', 'g' );
+        data.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});
+        data.addColumn({type: 'number', role: 'interval'});
+        data.addColumn({type: 'number', role: 'interval'});
+        data.addColumn('number', 'r' );
+        data.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});
+        data.addColumn({type: 'number', role: 'interval'});
+        data.addColumn({type: 'number', role: 'interval'});
+        data.addColumn('number', 'i' );
+        data.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});
+        data.addColumn({type: 'number', role: 'interval'});
+        data.addColumn({type: 'number', role: 'interval'});
+        data.addColumn('number', 'z' );
+        data.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});
+        data.addColumn({type: 'number', role: 'interval'});
+        data.addColumn({type: 'number', role: 'interval'});
+        data.addColumn('number', 'y' );
+        data.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});
+        data.addColumn({type: 'number', role: 'interval'});
+        data.addColumn({type: 'number', role: 'interval'});
+        data.addColumn('number', 'w' );
+        data.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});
+        data.addColumn({type: 'number', role: 'interval'});
+        data.addColumn({type: 'number', role: 'interval'});
+
+        // Count occurrences of each filter
+        const filterCounts = { g: 0, r: 0, i: 0, z: 0, y: 0, w: 0 };
+       const rows = dataArray.map(row => {
+            const [timestamp, mjd, filter, comment, ra, dec, exp_name, alt, az, iq_fwhm_maj, iq_fwhm_min, zpt_obs, zpt_stdev, exp_id, cam_label] = row;
+
+            // Initialize all filter values as null
+            let zp_g = null, zp_r = null, zp_i = null, zp_z = null, zp_y = null, zp_w = null;
+
+            // Increment the count for the filter
+            if (filterCounts.hasOwnProperty(filter[0])) {
+                filterCounts[filter[0]] += 1;
+            }
+
+            // Set the zeropoint offset based on filter and assign it to the correct series
+            switch (filter[0]) {
+                case 'g':
+                    zp_g = zpt_obs - 0.0;
+                    break;
+                case 'r':
+                    zp_r = zpt_obs - 0.0;
+                    break;
+                case 'i':
+                    zp_i = zpt_obs - 0.0;
+                    break;
+                case 'z':
+                    zp_z = zpt_obs - 0.0;
+                    break;
+                case 'y':
+                    zp_y = zpt_obs - 0.0;
+                    break;
+                case 'w':
+                    zp_w = zpt_obs - 0.0;
+                    break;
+            }
+
+            return [
+                parseFloat(mjd), // MJD value
+                zp_g, "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label,  
+parseFloat(zp_g - zpt_stdev), parseFloat(zp_g - zpt_stdev*-1),
+                zp_r, "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label,  
+parseFloat(zp_r - zpt_stdev), parseFloat(zp_r - zpt_stdev*-1),
+                zp_i, "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label,  
+parseFloat(zp_i - zpt_stdev), parseFloat(zp_i - zpt_stdev*-1),
+                zp_z, "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label,  
+parseFloat(zp_z - zpt_stdev), parseFloat(zp_z - zpt_stdev*-1),
+                zp_y, "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label,  
+parseFloat(zp_y - zpt_stdev), parseFloat(zp_y - zpt_stdev*-1),
+                zp_w, "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label,  
+parseFloat(zp_w - zpt_stdev), parseFloat(zp_w - zpt_stdev*-1),
+            ];
+        });
+      data.addRows(rows);
+
+        // Include counts in the title using string concatenation
+        const countsTitle = 'Zeropoint (MJD) g: ' + filterCounts.g + ', r: ' + filterCounts.r + ', i: ' + filterCounts.i + ', z: ' + filterCounts.z + ', y: ' + filterCounts.y + ', w: ' + filterCounts.w;
+
+
+        console.log(countsTitle);
+
+        const options = {
+            title: countsTitle,
+            titleTextStyle: { color: 'black', fontSize: 15 },
+            width: '100%',
+            height: 480,
+            legend: { position: 'top', alignment: 'center' },
+            series: {
+                0: { color: '#00f000', pointSize: 5, pointShape: 'circle',   linewidth: 1},  // 'g' filter
+                1: { color: '#f00000', pointSize: 5, pointShape: 'triangle', linewidth: 1},  // 'r' filter
+                2: { color: '#f05000', pointSize: 5, pointShape: 'square',   linewidth: 1},  // 'i' filter
+                3: { color: '#0050a0', pointSize: 5, pointShape: 'diamond',  linewidth: 1},  // 'z' filter
+                4: { color: '#ffe000', pointSize: 5, pointShape: 'star',     linewidth: 1},  // 'y' filter
+                5: { color: '#808080', pointSize: 5, pointShape: 'polygon',  linewidth: 1},  // 'w' filter
+            },
+            intervals: { color: 'red', lineWidth: 0, style: 'sticks' },
+            hAxis: {
+                title: 'MJD',
+                gridlines: { count: -1 }
+            },
+            vAxis: {
+                title: 'Zeropoint (mag)'
+            },
+            tooltip: { isHtml: true },
+            chartArea: { left: '9%', top: 60, right: '5%', bottom: 50 },
+            fontSize: 12,
+        };
+
+        const chart = new google.visualization.ScatterChart(document.getElementById('dq_div_zpt'));
+        chart.draw(data, options);
+    }
+
+    google.charts.setOnLoadCallback(drawFWHMChart);
+    google.charts.setOnLoadCallback(drawZPTChart);
+    google.charts.setOnLoadCallback(drawZOOMZPTChart);
+
+</script>
+
+<div class="chartWithOverlay" style="position: relative; width: 1240px; height:500px;">
+    <div id="dq_div_fwhm" style="width:100%;"></div>
+    <div class="overlay" style="position: absolute; width: 400px; bottom: 60px; left: 85px;"></div>
+</div>
+
+<div class="chartWithOverlay" style="position: relative; width: 1240px; height:500px;">
+    <div id="dq_div_zpt" style="width:100%;"></div>
+    <div class="overlay" style="position: absolute; width: 400px; bottom: 60px; left: 85px;"></div>
+</div>
+
+<div class="chartWithOverlay" style="position: relative; width: 1240px; height:500px;">
+    <div id="dq_div_zoomzpt" style="width:100%;"></div>
+    <div class="overlay" style="position: absolute; width: 400px; bottom: 60px; left: 85px;"></div>
+</div>
+
+HTML;
+    // End timer
+    $total_time = round(microtime(true) - $start, 3);
+    echo "<center>loading plot in $total_time seconds<br></center>";
+
+}
+
+
+
+?>
+
Index: /branches/eam_branches/ipp-ppmerge-20241229/ippMonitor/raw/ipp.czar.dat
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/ippMonitor/raw/ipp.czar.dat	(revision 42802)
+++ /branches/eam_branches/ipp-ppmerge-20241229/ippMonitor/raw/ipp.czar.dat	(revision 42803)
@@ -5,4 +5,6 @@
 menulink   | menuselect      | link    | czartool               | czartool_labels.php
 menulink   | menuselect      | link    | storage status         | storage.php
+menulink   | menuselect      | link    | pointing               | pointing.php
+menulink   | menuselect      | link    | data quality           | dataquality.php
 menulink   | menuselect      | link    | mask stats             | maskStats.php
 menulink   | menuselect      | link    | night summary          | nightSummary.php
Index: /branches/eam_branches/ipp-ppmerge-20241229/ippMonitor/raw/ipp.php
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/ippMonitor/raw/ipp.php	(revision 42802)
+++ /branches/eam_branches/ipp-ppmerge-20241229/ippMonitor/raw/ipp.php	(revision 42803)
@@ -982,5 +982,3 @@
 }
 
-
-
 ?>
Index: /branches/eam_branches/ipp-ppmerge-20241229/ippMonitor/raw/pointing.php
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/ippMonitor/raw/pointing.php	(revision 42803)
+++ /branches/eam_branches/ipp-ppmerge-20241229/ippMonitor/raw/pointing.php	(revision 42803)
@@ -0,0 +1,505 @@
+<?php
+include 'ipp.php';
+include 'site.php';
+
+$ID = checkID();
+
+// require an explicit project
+if (! $ID['proj']) { projectform ($ID); }
+
+// connect to czarDb 
+$czardb = dbconnect($CZARDBNAME); 
+$projectdb = dbconnect($ID['proj']);
+
+if ($ID['menu']) {$myMenu = $ID['menu'];}
+else {$myMenu = "ipp.czar.dat";}
+
+menu($myMenu, 'Czartool on '.$lastUpdateTime, 'ipp.css', $ID['link'], $ID['proj']);
+
+$pass = $ID['pass'];
+$proj = $ID['proj'];
+$menu = $ID['menu'];
+
+// Fetch data based on range selection
+$range = isset($_GET['range']) ? $_GET['range'] : 'yday';
+
+echo "<table border=\"0\">";
+echo "<tr>";
+echo "  <td style=width:1240>";
+echo "    <h1 align=\"middle\">Pointing Report</h1>";
+echo "  <center>";
+echo '    <a href="?pass=' . urlencode($pass) . '&proj=' . urlencode($proj) . '&range=yday">Last night (default)</a> | ';
+echo '    <a href="?pass=' . urlencode($pass) . '&proj=' . urlencode($proj) . '&range=day">Today (MJD '.getMJD().')</a> | ';
+echo '    <a href="?pass=' . urlencode($pass) . '&proj=' . urlencode($proj) . '&range=week">Past 7 days</a> | ';
+echo '    <a href="?pass=' . urlencode($pass) . '&proj=' . urlencode($proj) . '&range=month">Past 30 days</a> | ';
+echo '    <a href="?pass=' . urlencode($pass) . '&proj=' . urlencode($proj) . '&range=year">Past 365 days</a> | ';
+echo '    <a href="?pass=' . urlencode($pass) . '&proj=' . urlencode($proj) . '&range=all">All </a>   ';
+echo "  </td>";
+echo "</tr>";
+echo "</table>";
+echo getPointing($projectdb, $range);
+
+menu_end();
+
+
+/////////////////////////////////////////////////////////////////////////////
+//                                                                         //
+//                               Functions                                 //
+//                                                                         //
+/////////////////////////////////////////////////////////////////////////////
+###########################################################################
+#
+# Get data quality
+#
+###########################################################################
+function getPointing($db, $range = 'yday') {
+    // Start timer
+    $start = microtime(true);
+
+    $mjdDay  = getMJD();
+    $mjdDay_yearback = $mjdDay - 366;
+    $mjdDay_monthback = $mjdDay - 32;
+    $min_exp_id = 0;
+
+    // Determine the reference exp_name based on the selected range
+    switch ($range) {
+        case 'year':
+            $expname = "o" . $mjdDay_yearback . "%";
+            break;
+        case 'month':
+            $expname = "o" . $mjdDay_monthback . "%";
+            break;
+        case 'week':
+            $expname = "o" . ($mjdDay - 7) . "%";
+            break;
+        case 'day':
+            $expname = "o" . $mjdDay . "%";
+            break;
+        default:
+            $expname = "o" . ($mjdDay - 1) . "%"; // Default: last night
+            break;
+    }
+
+    // Query to get the minimum exp_id
+    $expIdQuery = "SELECT MIN(exp_id) AS min_exp_id FROM rawExp WHERE rawExp.exp_name LIKE '$expname'";
+    $result = $db->query($expIdQuery);
+
+    if (DB::isError($result)) {
+        die("Database error: " . $result->getMessage());
+    }
+
+    $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
+
+    if (!empty($row['min_exp_id'])) {
+        $min_exp_id = $row['min_exp_id'];
+    //    echo "Minimum exp_id: " . $min_exp_id;
+    } else {
+        echo "No results found.";
+    }
+
+    //echo "<br><br>";
+
+    // Determine the date constraint based on the range
+    switch ($range) {
+        case 'year':
+            $dateConstraint = "dateobs >= NOW() - INTERVAL 365 DAY AND rawExp.exp_id >= $min_exp_id";
+            break;
+        case 'month':
+            $dateConstraint = "dateobs >= NOW() - INTERVAL 30 DAY AND rawExp.exp_id >= $min_exp_id";
+            break;
+        case 'week':
+            $expnames = array();
+            for ($i = 0; $i < 7; $i++) {
+                $expnames[] = "rawExp.exp_name LIKE 'o" . ($mjdDay - $i) . "%'";
+            }
+            $dateConstraint = "(" . implode(" OR ", $expnames) . ") AND rawExp.exp_id >= $min_exp_id";
+            break;
+        case 'yday':
+            $dateConstraint = "rawExp.exp_name LIKE 'o" . ($mjdDay - 1) . "%' AND rawExp.exp_id >= $min_exp_id";
+            break;
+        case 'day':
+            $dateConstraint = "rawExp.exp_name LIKE 'o$mjdDay%' AND rawExp.exp_id >= $min_exp_id";
+            break;
+        case 'all':
+            $dateConstraint = "rawExp.exp_id >= 0";
+            break;
+        default: // Default to last night
+            $dateConstraint = "rawExp.exp_name LIKE 'o" . ($mjdDay - 1) . "%' AND rawExp.exp_id >= $min_exp_id";
+            break;
+    }
+ 
+    // Updated SQL query
+    $sql = "select * from (SELECT SUBTIME(dateobs, '10:00:00') AS time, AST_R0, AST_D0,
+                   round(( 367*YEAR(dateobs)- FLOOR((7 * (YEAR(dateobs) + FLOOR((MONTH(dateobs) + 9) / 12))) / 4) + FLOOR(275 * MONTH(dateobs) / 9)
+                   + DAY(dateobs) + 1721013.5 + (HOUR(dateobs) / 24.0) + (MINUTE(dateobs) / 1440.0) + (SECOND(dateobs) / 86400.0) - 2400000.5), 5) AS MJD,
+                   filter, exp_time, comment, ra*180/pi() as RA, decl*180/pi() as DECL, AST_RS, AST_DS, AST_T0, posang, exp_name, alt, az, rawExp.exp_id, camRun.label
+            FROM rawExp
+            JOIN chipRun USING (exp_id)
+            JOIN camRun USING (chip_id)
+            JOIN camProcessedExp USING (cam_id)
+            WHERE $dateConstraint
+              AND exp_type = 'OBJECT'
+              AND camRun.state LIKE 'full'
+              AND camProcessedExp.fault = 0
+              AND camProcessedExp.zpt_obs != 0 ORDER BY RAND() limit 5000) as sub order by time;";
+
+    $DQarray = array();
+    $qry = $db->query($sql);
+    if (dberror($qry)) {
+        echo "<b>Error with $sql</b><br>\n";
+        return;
+    }
+    //    echo "$sql<br><br>\n";
+    
+    while ($qry->fetchInto($row)) {
+        $DQarray[] = $row;
+    }
+    
+    // Ensure $DQarray is not empty
+    if (empty($DQarray)) {
+        echo "<center><b> No data for MJD: $mjdDay </b></center>";
+        return; // Stop execution if no data to encode
+    }
+    
+    // Convert data array to JSON for easier handling in JavaScript
+    $dataJson = json_encode($DQarray);
+    
+    if ($dataJson === false) {
+        echo "<b>Error encoding JSON:</b> " . json_last_error_msg(); // Display any JSON encoding errors
+        return; // Stop execution if JSON encoding fails
+    }
+    
+    echo "<script>console.log(" . json_encode($dataJson) . ");</script>"; // Log JSON output to console for debugging
+echo <<<HTML
+<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js" onerror="loadLocalGoogleCharts()"></script>
+
+<script type="text/javascript">
+    // Check if Google Charts library loaded successfully
+    window.addEventListener("load", function() {
+        if (typeof google === "undefined" || typeof google.charts === "undefined") {
+            loadLocalGoogleCharts();
+        }
+    });
+
+    // Function to load local version of Google Charts if CDN fails
+    function loadLocalGoogleCharts() {
+        console.warn("Google Charts CDN failed, loading local loader.js instead.");
+        var script = document.createElement("script");
+        script.src = "loader.js"; // Path to your local loader.js file
+        document.head.appendChild(script);
+    }
+</script>
+
+<script type="text/javascript">
+    google.charts.load('current', {packages: ['corechart']});
+
+    // Use the encoded JSON directly in JavaScript
+    const dataArray = JSON.parse('{$dataJson}'); // Directly parse the PHP JSON string
+
+    // draw pointing vs mjd
+    function drawMJDChart() {
+        var data = new google.visualization.DataTable();
+            data.addColumn('number', 'MJD');
+            data.addColumn('number', 'RA_offset (AST_R0)');
+            data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});
+            data.addColumn('number', 'Dec_offset (AST_D0)');
+            data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});
+            data.addColumn('number', '20 TP unit ~5.1"');
+            data.addColumn('number', '-20 TP unit ~5.1"');
+
+        const rows = dataArray.map(row => {
+            const [timestamp, ra_offset, dec_offset, mjd, filter, exp_time, comment, ra, dec, ra_offset_sig, dec_offset_sig, boresite_ang, position_ang, exp_name, alt, az, exp_id, cam_label] = row;
+
+            return [
+                parseFloat(mjd),               // MJD
+                parseFloat(ra_offset),         // RA_offset (AST_R0)
+                "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>timestamp: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label,
+                parseFloat(dec_offset),        // Dec_offset (AST_D0)
+                "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>timestamp: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label,
+                20,                            // Dummy value for 20 TP unit
+                -20                            // Dummy value for -20 TP unit
+            ];
+        });
+
+        data.addRows(rows);
+
+        // Extract the first MJD value from dataArray
+        //const firstMJD = dataArray.length > 0 ? parseFloat(dataArray[0][1]) : "N/A";
+        const firstMJD = dataArray.length > 0 ? Math.floor(parseFloat(dataArray[0][3])) : "N/A";
+        console.log("First MJD Value:", firstMJD);
+
+        const options = {
+            title: 'Pointing Offset (MJD: '+firstMJD+')',
+            titleTextStyle: {color: 'black', fontSize: 15},
+            width: '100%',
+            height: 480,
+            legend: { position: 'top', alignment: 'center' },
+            series: {
+                0: { color: '#0000ff', pointSize: 3, lineWidth: 0 }, // RA_offset series
+                1: { color: '#33a532', pointSize: 3, lineWidth: 0 }, // Dec_offset series
+                2: { color: 'red', lineWidth: 2, lineDashStyle: [8, 4], pointSize: 0 }, // Line at y = 20
+                3: { color: 'red', lineWidth: 2, lineDashStyle: [8, 4], pointSize: 0 }  // Line at y = -20
+            },
+            intervals: { color: 'red', lineWidth: 2, style: 'sticks' },
+            hAxis: {
+                title: 'MJD',
+                gridlines: {count: -1}
+            },
+            vAxis: {
+                title: 'Offset (TP units)',
+            },
+            tooltip: { isHtml: true }, // Render tooltips as HTML
+            chartArea: {left: '7%', top: 60, right: '4%', bottom: 50}, // Adjust left and right
+            fontSize: 15,
+        };
+
+        const chart = new google.visualization.ScatterChart(document.getElementById('dq_div_mjd'));
+        chart.draw(data, options);
+    }
+
+    // draw pointing scatter
+    function drawSIGChart() {
+        var data = new google.visualization.DataTable();
+            data.addColumn('number', 'MJD');
+            data.addColumn('number', 'RA_offset_scatter (AST_RS)');
+            data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});
+            data.addColumn('number', 'Dec_offset_scatter (AST_DS)');
+            data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});
+
+        const rows = dataArray.map(row => {
+            const [timestamp, ra_offset, dec_offset, mjd, filter, exp_time, comment, ra, dec, ra_offset_sig, dec_offset_sig, boresite_ang, position_ang, exp_name, alt, az, exp_id, cam_label] = row;
+
+            return [
+                parseFloat(mjd),               // MJD
+                parseFloat(ra_offset_sig),     // RA_offset_scatter (AST_RS)
+                "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>timestamp: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label,
+                parseFloat(dec_offset_sig),    // Dec_offset_scatter (AST_DS)
+                "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>timestamp: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label,
+            ];
+        });
+
+        data.addRows(rows);
+
+        const options = {
+            title: 'Pointing Offset Scatter (MJD)',
+            titleTextStyle: {color: 'black', fontSize: 15},
+            width: '100%',
+            height: 480,
+            legend: { position: 'top', alignment: 'center' },
+            series: {
+                0: { color: '#0000ff', pointSize: 3, lineWidth: 0 }, // RA_offset series
+                1: { color: '#33a532', pointSize: 3, lineWidth: 0 }, // Dec_offset series
+                2: { color: 'red', lineWidth: 2, lineDashStyle: [8, 4], pointSize: 0 }, // Line at y = 20
+                3: { color: 'red', lineWidth: 2, lineDashStyle: [8, 4], pointSize: 0 }  // Line at y = -20
+            },
+            intervals: { color: 'red', lineWidth: 2, style: 'sticks' },
+            hAxis: {
+                title: 'MJD',
+                gridlines: {count: -1}
+            },
+            vAxis: {
+                title: 'Offset Scatter (TP units)',
+            },
+            tooltip: { isHtml: true }, // Render tooltips as HTML
+            chartArea: {left: '7%', top: 60, right: '4%', bottom: 50}, // Adjust left and right
+            fontSize: 15,
+        };
+
+        const chart = new google.visualization.ScatterChart(document.getElementById('dq_div_sig'));
+        chart.draw(data, options);
+    }
+
+
+    // position angle
+    function drawPOSChart() {
+        var data = new google.visualization.DataTable();
+            data.addColumn('number', 'MJD');
+            data.addColumn('number', 'RA_offset (AST_R0)');
+            data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});
+            data.addColumn('number', 'Dec_offset (AST_D0)');
+            data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});
+
+        const rows = dataArray.map(row => {
+            const [timestamp, ra_offset, dec_offset, mjd, filter, exp_time, comment, ra, dec, ra_offset_sig, dec_offset_sig, boresite_ang, position_ang, exp_name, alt, az, exp_id, cam_label] = row;
+
+            return [
+                parseFloat(position_ang),      // Position Angle
+                parseFloat(ra_offset),         // RA_offset (AST_R0)
+                "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>timestamp: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label,
+                parseFloat(dec_offset),        // Dec_offset (AST_D0)
+                "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>timestamp: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label,
+            ];
+        });
+
+        data.addRows(rows);
+
+        const options = {
+            title: 'Pointing Offset (Position Angle)',
+            titleTextStyle: {color: 'black', fontSize: 15},
+            width: '100%',
+            height: 480,
+            legend: { position: 'top', alignment: 'center' },
+            // pointSize: 5, // Point size for scatter plot
+            // lineWidth: 2,
+            series: {
+                0: { color: '#0000ff', pointSize: 3, lineWidth: 0 }, // RA_offset series
+                1: { color: '#33a532', pointSize: 3, lineWidth: 0 }, // Dec_offset series
+            },
+            intervals: { color: 'red', lineWidth: 2, style: 'sticks' },
+            hAxis: {
+                title: 'Position Angle',
+                gridlines: {count: -1}
+            },
+            vAxis: {
+                title: 'Offset (TP units)',
+            },
+            tooltip: { isHtml: true }, // Render tooltips as HTML
+            chartArea: {left: '7%', top: 60, right: '4%', bottom: 50}, // Adjust left and right
+            fontSize: 15,
+        };
+
+        const chart = new google.visualization.ScatterChart(document.getElementById('dq_div_pos'));
+        chart.draw(data, options);
+    }
+
+    function drawALTChart() {
+        var data = new google.visualization.DataTable();
+            data.addColumn('number', 'Altitute');
+            data.addColumn('number', 'RA_offset (AST_R0)');
+            data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});
+            data.addColumn('number', 'Dec_offset (AST_D0)');
+            data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});
+
+        const rows = dataArray.map(row => {
+            const [timestamp, ra_offset, dec_offset, mjd, filter, exp_time, comment, ra, dec, ra_offset_sig, dec_offset_sig, boresite_ang, position_ang, exp_name, alt, az, exp_id, cam_label] = row;
+
+            return [
+                parseFloat(alt),      // Position Angle
+                parseFloat(ra_offset),         // RA_offset (AST_R0)
+                "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>timestamp: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label,
+                parseFloat(dec_offset),        // Dec_offset (AST_D0)
+                "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>timestamp: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label,
+            ];
+        });
+
+        data.addRows(rows);
+
+        const options = {
+            title: 'Pointing Offset (Altitude)',
+            titleTextStyle: {color: 'black', fontSize: 15},
+            width: '100%',
+            height: 480,
+            legend: { position: 'top', alignment: 'center' },
+            series: {
+                0: { color: '#0000ff', pointSize: 3, lineWidth: 0 }, // RA_offset series
+                1: { color: '#33a532', pointSize: 3, lineWidth: 0 }, // Dec_offset series
+            },
+            intervals: { color: 'red', lineWidth: 2, style: 'sticks' },
+            hAxis: {
+                title: 'Altitude',
+                gridlines: {count: -1}
+            },
+            vAxis: {
+                title: 'Offset (TP units)',
+            },
+            tooltip: { isHtml: true }, // Render tooltips as HTML
+            //chartArea: {left: 80, top: 50, right: 20, bottom: 50},
+            chartArea: {left: '7%', top: 60, right: '4%', bottom: 50}, // Adjust left and right
+            fontSize: 15,
+        };
+
+        const chart = new google.visualization.ScatterChart(document.getElementById('dq_div_alt'));
+        chart.draw(data, options);
+    }
+
+   function drawAZChart() {
+        var data = new google.visualization.DataTable();
+            data.addColumn('number', 'Azumith');
+            data.addColumn('number', 'RA_offset (AST_R0)');
+            data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});
+            data.addColumn('number', 'Dec_offset (AST_D0)');
+            data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});
+
+        const rows = dataArray.map(row => {
+            const [timestamp, ra_offset, dec_offset, mjd, filter, exp_time, comment, ra, dec, ra_offset_sig, dec_offset_sig, boresite_ang, position_ang, exp_name, alt, az, exp_id, cam_label] = row;
+
+            return [
+                parseFloat(az),      // Position Angle
+                parseFloat(ra_offset),         // RA_offset (AST_R0)
+                "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>timestamp: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label,
+                parseFloat(dec_offset),        // Dec_offset (AST_D0)
+                "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>timestamp: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label,
+            ];
+        });
+
+        data.addRows(rows);
+
+        const options = {
+            title: 'Pointing Offset (Azumith)',
+            titleTextStyle: {color: 'black', fontSize: 15},
+            width: '100%',
+            height: 480,
+            legend: { position: 'top', alignment: 'center' },
+            series: {
+                0: { color: '#0000ff', pointSize: 3, lineWidth: 0 }, // RA_offset series
+                1: { color: '#33a532', pointSize: 3, lineWidth: 0 }, // Dec_offset series
+            },
+            intervals: { color: 'red', lineWidth: 2, style: 'sticks' },
+            hAxis: {
+                title: 'Azumith',
+                gridlines: {count: -1}
+            },
+            vAxis: {
+                title: 'Offset (TP units)',
+            },
+            tooltip: { isHtml: true }, // Render tooltips as HTML
+            //chartArea: {left: 80, top: 50, right: 20, bottom: 50},
+            chartArea: {left: '7%', top: 60, right: '4%', bottom: 50}, // Adjust left and right
+            fontSize: 15,
+        };
+
+        const chart = new google.visualization.ScatterChart(document.getElementById('dq_div_az'));
+        chart.draw(data, options);
+    }
+
+    google.charts.setOnLoadCallback(drawMJDChart);
+    google.charts.setOnLoadCallback(drawSIGChart);
+    google.charts.setOnLoadCallback(drawPOSChart);
+    google.charts.setOnLoadCallback(drawALTChart);
+    google.charts.setOnLoadCallback(drawAZChart);
+</script>
+
+<div class="chartWithOverlay" style="position: relative; width: 1240px; height:500px;">
+    <div id="dq_div_mjd" style="width:1240px;"></div>
+    <div class="overlay" style="position: absolute; width: 800px; bottom: 60px; left: 85px;"></div>
+</div>
+
+<div class="chartWithOverlay" style="position: relative; width: 1240px; height:500px;">
+    <div id="dq_div_sig" style="width:1240px;"></div>
+    <div class="overlay" style="position: absolute; width: 800px; bottom: 60px; left: 85px;"></div>
+</div>
+
+<div class="chartWithOverlay" style="position: relative; width: 1240px; height:500px;">
+    <div id="dq_div_pos" style="width:1240px;"></div>
+    <div class="overlay" style="position: absolute; width: 800px; bottom: 60px; left: 85px;"></div>
+</div>
+
+<div class="chartWithOverlay" style="position: relative; width: 1240px; height:500px;">
+    <div id="dq_div_alt" style="width:1240px;"></div>
+    <div class="overlay" style="position: absolute; width: 800px; bottom: 60px; left: 85px;"></div>
+</div>
+
+<div class="chartWithOverlay" style="position: relative; width: 1240px; height:500px;">
+    <div id="dq_div_az" style="width:1240px;"></div>
+    <div class="overlay" style="position: absolute; width: 800px; bottom: 60px; left: 85px;"></div>
+</div>
+HTML;
+
+// End timer
+$total_time = round(microtime(true) - $start, 3);
+echo "<center>Loading plot in $total_time seconds<br></center>";
+
+}
+
+?>
+
Index: /branches/eam_branches/ipp-ppmerge-20241229/ippMonitor/scripts/czartool_getServerStatus.pl
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/ippMonitor/scripts/czartool_getServerStatus.pl	(revision 42802)
+++ /branches/eam_branches/ipp-ppmerge-20241229/ippMonitor/scripts/czartool_getServerStatus.pl	(revision 42803)
@@ -19,7 +19,14 @@
 
 if ($proj eq 'gpc1') {
-  $user = 'ippitc';
+  $user = 'ippps1';
 } else {
   $user = 'ippps2';
+}
+
+my @cmdOut3 = `grep PANTASKS_SERVER ~$user/$server/ptolemy.rc |grep -v std | grep -v PORT 2>&1`;
+my $line3;
+foreach $line3 (@cmdOut3) {
+    chomp($line3);
+    print "$line3 \n";
 }
 
@@ -40,4 +47,5 @@
     my @fields = split /\s+/, $line2;
 
+
 #    run job example 
 # field0      1        2       3         4      5       6           7       8 
@@ -50,2 +58,4 @@
     $nline = $nline + 1;
 }
+
+
Index: /branches/eam_branches/ipp-ppmerge-20241229/ippTasks/mergedvodb.pro
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/ippTasks/mergedvodb.pro	(revision 42802)
+++ /branches/eam_branches/ipp-ppmerge-20241229/ippTasks/mergedvodb.pro	(revision 42803)
@@ -7,5 +7,5 @@
 
 
-#There is a book for each task, because I don't use labels. 
+#There is a book for each task, because I dont use labels. 
 
 if (not($?havemergedvodbBooks))
@@ -44,5 +44,5 @@
 end
 
-## you get no choice - you add all of them in at the same time. you can always turn off the tasks you don't want to run.
+## you get no choice - you add all of them in at the same time. you can always turn off the tasks you dont want to run.
 macro add.mergedvodb
   if ($0 != 2)
Index: /branches/eam_branches/ipp-ppmerge-20241229/ippTasks/summit.copy.pro
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/ippTasks/summit.copy.pro	(revision 42802)
+++ /branches/eam_branches/ipp-ppmerge-20241229/ippTasks/summit.copy.pro	(revision 42803)
@@ -49,4 +49,17 @@
 macro summitcopy.reset
     summitcopy.reset
+end
+
+# pzgetexp is loading exposure files to summitExp 
+macro pzgetexp.on
+  task pzgetexp
+    active true
+  end
+end
+
+macro pzgetexp.off
+  task pzgetexp
+    active false
+  end
 end
 
Index: /branches/eam_branches/ipp-ppmerge-20241229/ippTools/src/pxtools.c
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/ippTools/src/pxtools.c	(revision 42802)
+++ /branches/eam_branches/ipp-ppmerge-20241229/ippTools/src/pxtools.c	(revision 42803)
@@ -36,4 +36,5 @@
     if (!strcmp(state, "wait")) return true;
     if (!strcmp(state, "keep")) return true;
+    if (!strcmp(state, "ignore")) return true;
     if (!strcmp(state, "goto_cleaned")) return true;
     if (!strcmp(state, "error_cleaned")) return true;
Index: /branches/eam_branches/ipp-ppmerge-20241229/ippconfig/Makefile.am
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/ippconfig/Makefile.am	(revision 42802)
+++ /branches/eam_branches/ipp-ppmerge-20241229/ippconfig/Makefile.am	(revision 42803)
@@ -1,2 +1,4 @@
+TGT  = $(PSCONFDIR)/$(PSCONFIG)/etc/compress.mgc
+
 SUBDIRS = \
 	recipes \
@@ -36,5 +38,6 @@
 built_files = \
 	ipprc.config \
-	dvo.site
+	dvo.site \
+	$(TGT)
 
 installdir = $(datadir)/ippconfig
@@ -64,10 +67,4 @@
 
 
-TGTDIR  = $(PSCONFDIR)/$(PSCONFIG)/etc
-SRC	= 	compress
-TGT	= 	$(TGTDIR)/compress.mgc
-
-install: $(TGT)
-build:   $(MGC)
 
 if HAVE_LINUX
Index: /branches/eam_branches/ipp-ppmerge-20241229/ppImage/src/ppImageBurntoolApply.c
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/ppImage/src/ppImageBurntoolApply.c	(revision 42802)
+++ /branches/eam_branches/ipp-ppmerge-20241229/ppImage/src/ppImageBurntoolApply.c	(revision 42803)
@@ -226,5 +226,5 @@
         /* do separate masking strategy for old (14 and lower) and new burntool tables*/
         if (BURNTOOL_STATE_GOOD >= 15) {
-	 printf("DET: New burntool style %d\n",BURNTOOL_STATE_GOOD);
+	 /*printf("DET: New burntool style %d\n",BURNTOOL_STATE_GOOD);*/
           for (int i = box->sxfit; i<= box->exfit; i++) {
               if (box->up == 0) {
@@ -248,5 +248,5 @@
 
         } else {
-	 printf("DET: Old burntool style %d\n",BURNTOOL_STATE_GOOD);
+	/* printf("DET: Old burntool style %d\n",BURNTOOL_STATE_GOOD);*/
           for (int i = box->sxfit; i<= box->exfit; i++) {
               if (box->up == 0) {
Index: /branches/eam_branches/ipp-ppmerge-20241229/psLib/src/db/psDB.c
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/psLib/src/db/psDB.c	(revision 42802)
+++ /branches/eam_branches/ipp-ppmerge-20241229/psLib/src/db/psDB.c	(revision 42803)
@@ -1039,5 +1039,5 @@
     fieldCount = mysql_num_fields(result);
 
-    psTrace("psLib.db", PS_LOG_INFO, "query returned %lu rows with %d fields",             rowCount, fieldCount);
+    psTrace("psLib.db", PS_LOG_INFO, "query returned %lu rows with %d fields", (long unsigned int) rowCount, fieldCount);
 
     while ((row = mysql_fetch_row(result))) {
Index: /branches/eam_branches/ipp-ppmerge-20241229/psconfig/tagsets/ipp-ubuntu.dist
===================================================================
--- /branches/eam_branches/ipp-ppmerge-20241229/psconfig/tagsets/ipp-ubuntu.dist	(revision 42802)
+++ /branches/eam_branches/ipp-ppmerge-20241229/psconfig/tagsets/ipp-ubuntu.dist	(revision 42803)
@@ -68,5 +68,5 @@
   YYYYY  ippScripts             ipp-2-9          -0
   YYYYY  ippTasks               ipp-2-9          -0
-# YNYYY  ippToPsps              ipp-2-9          -0 : moved to $svn/psps
+  YNYYY  ippToPsps              ipp-2-9          -0 : moved to $svn/psps
           
   YNYYN  psconfig               ipp-2-9          -0
@@ -81,8 +81,8 @@
 
   YYYYY  extsrc/gpcsw           ipp-2-9          -0
-# YYYYY  magic                  ipp-2-9          -0
-# YYYYY  magic/censorObjects    ipp-2-9          -0
-# YYYYY  magic/remove           ipp-2-9          -0
-  YYYYY  console                ipp-2-9          -0
+  YNYYY  magic                  ipp-2-9          -0
+  YNYYY  magic/censorObjects    ipp-2-9          -0
+  YNYYY  magic/remove           ipp-2-9          -0
+  YNYYY  console                ipp-2-9          -0
 
 # there are externally required C libraries and perl modules (see INSTALL)
