Index: trunk/Ohana/src/libdvo/Makefile
===================================================================
--- trunk/Ohana/src/libdvo/Makefile	(revision 34088)
+++ trunk/Ohana/src/libdvo/Makefile	(revision 34260)
@@ -35,4 +35,5 @@
 $(DESTINC)/ps1_v2_defs.h \
 $(DESTINC)/ps1_v3_defs.h \
+$(DESTINC)/ps1_v4_defs.h \
 $(DESTINC)/ps1_ref_defs.h
 
@@ -73,4 +74,5 @@
 $(SRC)/dvo_convert_PS1_V2.$(ARCH).o \
 $(SRC)/dvo_convert_PS1_V3.$(ARCH).o \
+$(SRC)/dvo_convert_PS1_V4.$(ARCH).o \
 $(SRC)/dvo_convert_PS1_REF.$(ARCH).o \
 $(SRC)/flatcorr_io.$(ARCH).o    \
@@ -100,5 +102,6 @@
 $(SRC)/db_utils.$(ARCH).o		\
 $(SRC)/convert.$(ARCH).o                \
-$(SRC)/HostTable.$(ARCH).o
+$(SRC)/HostTable.$(ARCH).o              \
+$(SRC)/BoundaryTree.$(ARCH).o
 
 
Index: trunk/Ohana/src/libdvo/doc/notes.txt
===================================================================
--- trunk/Ohana/src/libdvo/doc/notes.txt	(revision 34088)
+++ trunk/Ohana/src/libdvo/doc/notes.txt	(revision 34260)
@@ -25,8 +25,10 @@
    include the new STRUCT name.
 
-7) create a new conversion file dvo_convert_foo.c and define the
+7) create a new conversion file libdvo/src/dvo_convert_foo.c and define the
    internal to Foo conversions.
 
-8) add the new format to the list of FORMAT conversion in dvo_convert.c.
+8a) add the new dvo_convert_foo.c to libdvo/Makefile
+
+8b) add the new format to the list of FORMAT conversion in dvo_convert.c.
 
 9) any changes to the internal format need to be reflected in the
@@ -44,4 +46,8 @@
 
 13) Add the conversion functions to the header file libdvo/include/foo_defs.h
+
+14) Add the above foo_defs.h to libdvo/include/dvo.h
+
+14) Add the above foo_defs.h to libdvo/Makefile
 
 * Note some esoteric format issues:  
Index: trunk/Ohana/src/libdvo/include/dvo.h
===================================================================
--- trunk/Ohana/src/libdvo/include/dvo.h	(revision 34088)
+++ trunk/Ohana/src/libdvo/include/dvo.h	(revision 34260)
@@ -27,4 +27,5 @@
   DVO_FORMAT_PS1_V2,
   DVO_FORMAT_PS1_V3,
+  DVO_FORMAT_PS1_V4,
 } DVOTableFormat;
 
@@ -292,4 +293,26 @@
 } DVOTinyValueMode;
 
+# define BOUNDARY_TREE_NAME_LENGTH 128
+
+typedef struct {
+  int FixedGridDEC;	      // is the DEC sequence linear?
+  int FixedGridRA;	      // in the RA sequence in a zone linear?
+
+  double DEC_origin;
+  double DEC_offset;
+
+  int Nzone;
+  double *RA_origin;
+  double *RA_offset;
+
+  int *Nband;
+  int *NBAND;
+
+  double   **ra;
+  double  **dec;
+  int    **cell;
+  char  ***name;
+} BoundaryTree;
+
 // XXX DROP? // a reduced-subset structure for relastro
 // XXX DROP? typedef struct {
@@ -448,4 +471,5 @@
 float PhotCat (Measure *measure);
 float PhotAper (Measure *measure);
+float PhotKron (Measure *measure);
 float PhotSys (Measure *measure, Average *average, SecFilt *secfilt);
 float PhotRel (Measure *measure, Average *average, SecFilt *secfilt);
@@ -456,8 +480,19 @@
 float PhotdM (PhotCode *code, Average *average, SecFilt *secfilt);
 
+float PhotAperInst (Measure *measure);
+float PhotKronInst (Measure *measure);
+float PhotKronAve (PhotCode *code, Average *average, SecFilt *secfilt);
+
+float PhotZeroPoint (Measure *measure, Average *average, SecFilt *secfilt);
+float PhotAveFluxPSF (PhotCode *code, Average *average, SecFilt *secfilt);
+float PhotAvedFluxPSF (PhotCode *code, Average *average, SecFilt *secfilt);
+float PhotAveFluxKron (PhotCode *code, Average *average, SecFilt *secfilt);
+float PhotAvedFluxKron (PhotCode *code, Average *average, SecFilt *secfilt);
+
 float PhotMstdev (PhotCode *code, Average *average, SecFilt *secfilt);
 float PhotM20 (PhotCode *code, Average *average, SecFilt *secfilt);
 float PhotM80 (PhotCode *code, Average *average, SecFilt *secfilt);
 float PhotUCdist (PhotCode *code, Average *average, SecFilt *secfilt);
+unsigned int PhotStackID (PhotCode *code, Average *average, SecFilt *secfilt);
 
 float PhotColorForCode (Average *average, SecFilt *secfilt, Measure *measure, PhotCode *code);
@@ -571,4 +606,5 @@
 # include "ps1_v2_defs.h"
 # include "ps1_v3_defs.h"
+# include "ps1_v4_defs.h"
 # include "ps1_ref_defs.h"
 
@@ -648,4 +684,11 @@
 int free_tiny_values (Catalog *catalog);
 
+int BoundaryTreeCellCoords (BoundaryTree *tree, int *zone, int *band, double ra, double dec);
+int BoundaryTreeSave(char *filename, BoundaryTree *tree);
+BoundaryTree *BoundaryTreeLoad(char *filename);
+
+void dvo_average_init (Average *average);
+void dvo_secfilt_init (SecFilt *secfilt);
+void dvo_measure_init (Measure *measure);
+
 # endif // DVO_H
-
Index: trunk/Ohana/src/libdvo/include/dvodb.h
===================================================================
--- trunk/Ohana/src/libdvo/include/dvodb.h	(revision 34088)
+++ trunk/Ohana/src/libdvo/include/dvodb.h	(revision 34260)
@@ -26,4 +26,8 @@
       MAG_CAT, 
       MAG_APER, 
+      MAG_APER_INST, 
+      MAG_KRON, 
+      MAG_KRON_INST, 
+      MAG_KRON_ERR, 
       MAG_SYS, 
       MAG_REL, 
@@ -41,4 +45,9 @@
       MAG_80, 
       MAG_UC_DIST, 
+      MAG_STACK_ID, 
+      MAG_FLUX_PSF,
+      MAG_FLUX_PSF_ERR,
+      MAG_FLUX_KRON,
+      MAG_FLUX_KRON_ERR,
 };
 
@@ -132,4 +141,9 @@
       MEAS_MCAL_OFFSET,
       MEAS_FLAT,
+      MEAS_CENTER_OFFSET,
+      MEAS_FLUX_PSF,
+      MEAS_FLUX_PSF_ERR,
+      MEAS_FLUX_KRON,
+      MEAS_FLUX_KRON_ERR,
 };
 
Index: trunk/Ohana/src/libdvo/include/ps1_v4_defs.h
===================================================================
--- trunk/Ohana/src/libdvo/include/ps1_v4_defs.h	(revision 34260)
+++ trunk/Ohana/src/libdvo/include/ps1_v4_defs.h	(revision 34260)
@@ -0,0 +1,11 @@
+Image 		       	*Image_PS1_V4_ToInternal (Image_PS1_V4 *in, off_t Nvalues);
+Image_PS1_V4    	*ImageInternalTo_PS1_V4 (Image *in, off_t Nvalues);
+Average 	       	*Average_PS1_V4_ToInternal (Average_PS1_V4 *in, off_t Nvalues, SecFilt **primary);
+Average_PS1_V4          *AverageInternalTo_PS1_V4 (Average *in, off_t Nvalues, SecFilt *primary);
+Measure 	       	*Measure_PS1_V4_ToInternal (Measure_PS1_V4 *in, off_t Nvalues);
+Measure_PS1_V4          *MeasureInternalTo_PS1_V4 (Measure *in, off_t Nvalues);
+SecFilt 	       	*SecFilt_PS1_V4_ToInternal (SecFilt_PS1_V4 *in, off_t Nvalues);
+SecFilt_PS1_V4          *SecFiltInternalTo_PS1_V4 (SecFilt *in, off_t Nvalues);
+
+PhotCode                *PhotCode_PS1_V4_To_Internal (PhotCode_PS1_V4 *in, off_t Nvalues);
+PhotCode_PS1_V4         *PhotCode_Internal_To_PS1_V4 (PhotCode *in, off_t Nvalues);
Index: trunk/Ohana/src/libdvo/src/BoundaryTree.c
===================================================================
--- trunk/Ohana/src/libdvo/src/BoundaryTree.c	(revision 34260)
+++ trunk/Ohana/src/libdvo/src/BoundaryTree.c	(revision 34260)
@@ -0,0 +1,293 @@
+# include "dvo.h"
+
+# define GET_COLUMN_NEW(OUT,NAME,TYPE)					\
+  TYPE *OUT = gfits_get_bintable_column_data (&theader, &ftable, NAME, type, &Nrow, &Ncol); \
+  myAssert (!strcmp(type, #TYPE), "wrong column type");
+
+# define GET_COLUMN_RAW(OUT,NAME,TYPE)					\
+  OUT = gfits_get_bintable_column_data (&theader, &ftable, NAME, type, &Nrow, &Ncol); \
+  myAssert (!strcmp(type, #TYPE), "wrong column type");
+
+# define DEBUG 0
+
+BoundaryTree *BoundaryTreeLoad(char *filename) {
+
+  int i, j, nz, nb, Ncol;
+  off_t Nrow;
+  char type[16];
+  Header header;
+  Header theader;
+  Matrix matrix;
+  FTable ftable;
+
+  header.buffer = NULL;
+  matrix.buffer = NULL;
+  ftable.buffer = NULL;
+  theader.buffer = NULL;
+  BoundaryTree *tree = NULL;
+
+  FILE *f = fopen (filename, "r");
+  if (!f) {
+    fprintf (stderr, "ERROR: cannot open image subset file %s\n", filename);
+    return NULL;
+  }
+
+  /* load in PHU segment (ignore) */
+  if (!gfits_fread_header (f, &header)) {
+    if (DEBUG) fprintf (stderr, "can't read image subset header\n");
+    goto escape;
+  }
+  if (!gfits_fread_matrix (f, &matrix, &header)) {
+    if (DEBUG) fprintf (stderr, "can't read image subset matrix\n");
+    goto escape;
+  }
+
+  ALLOCATE (tree, BoundaryTree, 1);
+
+  gfits_scan (&header, "DEC_ORI", "%lf", 1, &tree->DEC_origin);
+  gfits_scan (&header, "DEC_OFF", "%lf", 1, &tree->DEC_offset);
+
+  ftable.header = &theader;
+
+  /*** zone information table ***/
+  { 
+    // load data for this header 
+    if (!gfits_load_header (f, &theader)) goto escape;
+
+    // read the fits table bytes
+    if (!gfits_fread_ftable_data (f, &ftable, FALSE)) goto escape;
+ 
+    // need to create and assign to flat-field correction
+    GET_COLUMN_RAW(tree->Nband,     "NBAND",  	 int);
+    GET_COLUMN_RAW(tree->RA_origin, "RA_ORIGIN", double);
+    GET_COLUMN_RAW(tree->RA_offset, "RA_OFFSET", double);
+    gfits_free_header (&theader);
+    gfits_free_table  (&ftable);
+
+    fprintf (stderr, "loaded data for %lld zones\n", (long long) Nrow);
+    tree->Nzone = Nrow;
+
+    // allocate the storage arrays
+    ALLOCATE (tree->ra,   double *, tree->Nzone);
+    ALLOCATE (tree->dec,  double *, tree->Nzone);
+    ALLOCATE (tree->cell, int *, tree->Nzone);
+    ALLOCATE (tree->name, char **, tree->Nzone);
+    for (i = 0; i < tree->Nzone; i++) {
+      ALLOCATE (tree->ra[i],   double, tree->Nband[i]);
+      ALLOCATE (tree->dec[i],  double, tree->Nband[i]);
+      ALLOCATE (tree->cell[i], int,    tree->Nband[i]);
+      ALLOCATE (tree->name[i], char *, tree->Nband[i]);
+      for (j = 0; j < tree->Nband[i]; j++) {
+	ALLOCATE (tree->name[i][j], char, BOUNDARY_TREE_NAME_LENGTH);
+      }
+    }
+  }
+
+  /*** cell information table ***/
+  { 
+    // load data for this header 
+    if (!gfits_load_header (f, &theader)) goto escape;
+
+    // read the fits table bytes
+    if (!gfits_fread_ftable_data (f, &ftable, FALSE)) goto escape;
+ 
+    // need to create and assign to flat-field correction
+    GET_COLUMN_NEW(R,     "RA",   	 double);
+    GET_COLUMN_NEW(D,     "DEC",  	 double);
+    GET_COLUMN_NEW(zone,  "ZONE",        int);
+    GET_COLUMN_NEW(band,  "BAND",        int);
+    GET_COLUMN_NEW(index, "INDEX",       int);
+    GET_COLUMN_NEW(name,  "NAME",        char); // XXX how is this done?
+    gfits_free_header (&theader);
+    gfits_free_table  (&ftable);
+    fprintf (stderr, "loaded data for %lld cells\n", (long long) Nrow);
+
+    // assign the storage arrays
+    for (i = 0; i < Nrow; i++) {
+      nz = zone[i];
+      nb = band[i];
+      tree->ra[nz][nb] = R[i];
+      tree->dec[nz][nb] = D[i];
+      tree->cell[nz][nb] = i; // XXX ?
+      memcpy(tree->name[nz][nb], &name[i*BOUNDARY_TREE_NAME_LENGTH], BOUNDARY_TREE_NAME_LENGTH);
+    }
+
+    free (R     );
+    free (D     );
+    free (zone  );
+    free (band  );
+    free (index );
+    free (name  );
+  }
+
+  gfits_free_header (&header);
+  gfits_free_matrix (&matrix);
+  fclose (f);
+
+  return tree;
+
+escape:
+  gfits_free_header (&header);
+  gfits_free_matrix (&matrix);
+  gfits_free_header (&theader);
+  gfits_free_table  (&ftable);
+  if (tree) free (tree);
+
+  fclose (f);
+  return NULL;
+}
+
+// we are passed a BoundaryTree structure, write it to a FITS table (3 ext)
+int BoundaryTreeSave(char *filename, BoundaryTree *tree) {
+
+  int i, nz, nb;
+  Header header;
+  Header theader;
+  Matrix matrix;
+  FTable ftable;
+
+  gfits_init_header (&header);
+  header.extend = TRUE;
+  gfits_create_header (&header);
+  gfits_create_matrix (&header, &matrix);
+
+  FILE *f = fopen (filename, "w");
+  if (!f) {
+    fprintf (stderr, "ERROR: cannot open boundary tree file for output %s\n", filename);
+    return FALSE;
+  }
+
+  // we need some information in the header to define the layout
+  gfits_modify (&header, "DEC_ORI", "%lf", 1, tree->DEC_origin);
+  gfits_modify (&header, "DEC_OFF", "%lf", 1, tree->DEC_offset);
+
+  gfits_fwrite_header  (f, &header);
+  gfits_fwrite_matrix  (f, &matrix);
+  gfits_free_header (&header);
+  gfits_free_matrix (&matrix);
+
+  /*** zone information table ***/
+  {
+    gfits_create_table_header (&theader, "BINTABLE", "ZONE_DATA");
+
+    gfits_define_bintable_column (&theader, "J", "ZONE",      "zone sequence number", "none", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "J", "NBAND",     "number of cells in each zone", "none", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "D", "RA_ORIGIN", "origin of ra cell sequence", "degree", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "D", "RA_OFFSET", "offset per cell of ra cell sequence", "degree/cell", 1.0, 0.0);
+
+    // generate the output array that carries the data
+    gfits_create_table (&theader, &ftable);
+
+    // create intermediate storage arrays
+    int *zone = NULL; ALLOCATE (zone,  int, tree->Nzone);
+
+    // assign the storage arrays
+    for (i = 0; i < tree->Nzone; i++) {
+      zone[i] = i;
+    }
+
+    // add the columns to the output array
+    gfits_set_bintable_column (&theader, &ftable, "ZONE",   	zone,            tree->Nzone);
+    gfits_set_bintable_column (&theader, &ftable, "NBAND",   	tree->Nband,     tree->Nzone);
+    gfits_set_bintable_column (&theader, &ftable, "RA_ORIGIN", 	tree->RA_origin, tree->Nzone);
+    gfits_set_bintable_column (&theader, &ftable, "RA_OFFSET", 	tree->RA_offset, tree->Nzone);
+    free (zone);
+
+    gfits_fwrite_Theader (f, &theader);
+    gfits_fwrite_table (f, &ftable);
+    gfits_free_header (&theader);
+    gfits_free_table (&ftable);
+  }
+
+  /*** cell information table ***/
+  {
+    gfits_create_table_header (&theader, "BINTABLE", "CELL_DATA");
+
+    char fmt[16];
+    snprintf (fmt, 16, "%dA", BOUNDARY_TREE_NAME_LENGTH);
+    gfits_define_bintable_column (&theader, "D", "RA",   "ra (J2000) of cell center", "degree", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "D", "DEC",  "dec (J2000) of cell center", "degree", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "J", "ZONE", "zone sequence number", "none", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "J", "BAND", "band sequence number", "none", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, "J", "INDEX","cell index", "none", 1.0, 0.0);
+    gfits_define_bintable_column (&theader, fmt, "NAME", "cell name", "none", 1.0, 0.0);
+
+    // generate the output array that carries the data
+    gfits_create_table (&theader, &ftable);
+
+    int Ncell = 0;
+    for (i = 0; i < tree->Nzone; i++) {
+      Ncell += tree->Nband[i];
+    }
+
+    // create intermediate storage arrays
+    // NOTE: we have to unroll the 2D arrays in tree into 1D arrays
+    double *R             ; ALLOCATE (R,     double, Ncell);
+    double *D             ; ALLOCATE (D,     double, Ncell);
+    int    *zone          ; ALLOCATE (zone,  int,    Ncell);
+    int    *band          ; ALLOCATE (band,  int,    Ncell);
+    int    *index         ; ALLOCATE (index, int,    Ncell);
+    char   *name          ; ALLOCATE (name,  char,   Ncell*BOUNDARY_TREE_NAME_LENGTH);
+
+    // NOTE: a table column of characters must be fixed width, and is passed as a
+    // contiguous array of Nchar * Nrow values
+
+    // assign the storage arrays
+    i = 0;
+    for (nz = 0; nz < tree->Nzone; nz++) {
+      for (nb = 0; nb < tree->Nband[nz]; nb++) {
+	R[i]     = tree->ra[nz][nb];
+	D[i]     = tree->dec[nz][nb];
+	zone[i]  = nz;
+	band[i]  = nb;
+	index[i] = i; // or tree->cells[nz][nb] ?
+	memcpy(&name[i*BOUNDARY_TREE_NAME_LENGTH], tree->name[nz][nb], BOUNDARY_TREE_NAME_LENGTH);
+	i++; 
+      }
+    }
+
+    // add the columns to the output array
+    gfits_set_bintable_column (&theader, &ftable, "RA",    R,     Ncell);
+    gfits_set_bintable_column (&theader, &ftable, "DEC",   D,     Ncell);
+    gfits_set_bintable_column (&theader, &ftable, "ZONE",  zone,  Ncell);
+    gfits_set_bintable_column (&theader, &ftable, "BAND",  band,  Ncell);
+    gfits_set_bintable_column (&theader, &ftable, "INDEX", index, Ncell);
+    gfits_set_bintable_column (&theader, &ftable, "NAME",  name,  Ncell);
+
+    free (R     );
+    free (D     );
+    free (zone  );
+    free (band  );
+    free (index );
+    free (name  );
+
+    gfits_fwrite_Theader (f, &theader);
+    gfits_fwrite_table  (f, &ftable);
+    gfits_free_header (&theader);
+    gfits_free_table (&ftable);
+  }
+  return TRUE;
+}
+
+// the boundary tree...
+// given an (ra,dec) pair, find the containing projection cell.
+
+int BoundaryTreeCellCoords (BoundaryTree *tree, int *zone, int *band, double ra, double dec) {
+
+  // first, find the containing zone
+
+  // if we know dDEC, we can get the bin instantly:
+  *zone = (dec - tree->DEC_origin) / tree->DEC_offset;
+  
+  if (*zone < 0) return FALSE;
+  if (*zone >= tree->Nzone) return FALSE;
+
+  // now select the RA bin for that zone
+  *band = (ra - tree->RA_origin[*zone]) / tree->RA_offset[*zone];
+  
+  if (*band < 0) return FALSE;
+  if (*band >= tree->Nband[*zone]) *band = 0;
+
+  return TRUE;
+}
+
Index: trunk/Ohana/src/libdvo/src/LoadPhotcodesFITS.c
===================================================================
--- trunk/Ohana/src/libdvo/src/LoadPhotcodesFITS.c	(revision 34088)
+++ trunk/Ohana/src/libdvo/src/LoadPhotcodesFITS.c	(revision 34260)
@@ -63,4 +63,5 @@
   CONVERT_FORMAT("DVO_PHOTCODE_PS1_V2",    PS1_V2);
   CONVERT_FORMAT("DVO_PHOTCODE_PS1_V3",    PS1_V3);
+  CONVERT_FORMAT("DVO_PHOTCODE_PS1_V4",    PS1_V4);
 
   table = GetPhotcodeTable ();
Index: trunk/Ohana/src/libdvo/src/SavePhotcodesFITS.c
===================================================================
--- trunk/Ohana/src/libdvo/src/SavePhotcodesFITS.c	(revision 34088)
+++ trunk/Ohana/src/libdvo/src/SavePhotcodesFITS.c	(revision 34260)
@@ -4,4 +4,5 @@
 /* locking is used to avoid collisions with programs trying to update the photcodes values */
 /* XXX better distinction between NOT FOUND and FAILURE */
+
 int SavePhotcodesFITS (char *filename) {
 
@@ -29,9 +30,9 @@
   // for the moment, we simply support the latest photcode format for output
   // XXX update this as needed as new formats are defined
-  PhotCode_PS1_V3 *photcode_output = PhotCode_Internal_To_PS1_V3 (table[0].code, table[0].Ncode);
+  PhotCode_PS1_V4 *photcode_output = PhotCode_Internal_To_PS1_V4 (table[0].code, table[0].Ncode);
 
   /* convert FITS format data to internal format (byteswaps & EXTNAME) */
   if (!gfits_db_create (&db)) return (FALSE);
-  if (!gfits_table_set_PhotCode_PS1_V3 (&db.ftable, photcode_output, table[0].Ncode)) return (FALSE);
+  if (!gfits_table_set_PhotCode_PS1_V4 (&db.ftable, photcode_output, table[0].Ncode)) return (FALSE);
   if (!gfits_db_save (&db)) return (FALSE);
   if (!gfits_db_close (&db)) return (FALSE);
Index: trunk/Ohana/src/libdvo/src/dbExtractAverages.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dbExtractAverages.c	(revision 34088)
+++ trunk/Ohana/src/libdvo/src/dbExtractAverages.c	(revision 34260)
@@ -233,4 +233,8 @@
 	  break;
 
+	case MAG_KRON:
+	  value.Flt = PhotKronAve (field->photcode, average, secfilt);
+	  break;
+
 	case MAG_20:
 	  value.Flt = PhotM20 (field->photcode, average, secfilt);
@@ -241,4 +245,20 @@
 	case MAG_UC_DIST:
 	  value.Flt = PhotUCdist (field->photcode, average, secfilt);
+	  break;
+	case MAG_STACK_ID:
+	  value.Int = PhotStackID (field->photcode, average, secfilt);
+	  break;
+
+	case MAG_FLUX_PSF:
+	  value.Flt = PhotAveFluxPSF (field->photcode, average, secfilt);
+	  break;
+	case MAG_FLUX_PSF_ERR:
+	  value.Flt = PhotAvedFluxPSF (field->photcode, average, secfilt);
+	  break;
+	case MAG_FLUX_KRON:
+	  value.Flt = PhotAveFluxKron (field->photcode, average, secfilt);
+	  break;
+	case MAG_FLUX_KRON_ERR:
+	  value.Flt = PhotAvedFluxKron (field->photcode, average, secfilt);
 	  break;
       }
Index: trunk/Ohana/src/libdvo/src/dbExtractMeasures.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dbExtractMeasures.c	(revision 34088)
+++ trunk/Ohana/src/libdvo/src/dbExtractMeasures.c	(revision 34260)
@@ -117,5 +117,17 @@
 	  break;
 	case MAG_APER:
-	  value.Flt = PhotAper  (measure); 
+	  value.Flt = PhotAper (measure); 
+	  break;
+	case MAG_APER_INST:
+	  value.Flt = PhotAperInst (measure); 
+	  break;
+	case MAG_KRON:
+	  value.Flt = PhotKron (measure); 
+	  break;
+	case MAG_KRON_INST:
+	  value.Flt = PhotKronInst (measure); 
+	  break;
+	case MAG_KRON_ERR:
+	  value.Flt = measure[0].dMkron; 
 	  break;
 	case MAG_ERR:
@@ -152,4 +164,16 @@
 	  if (Nsec == -1) break;
 	  value.Int = secfilt[Nsec].Nused;
+	  break;
+	case MAG_FLUX_PSF:
+	  value.Flt = PhotAveFluxPSF (field->photcode, average, secfilt);
+	  break;
+	case MAG_FLUX_PSF_ERR:
+	  value.Flt = PhotAvedFluxPSF (field->photcode, average, secfilt);
+	  break;
+	case MAG_FLUX_KRON:
+	  value.Flt = PhotAveFluxKron (field->photcode, average, secfilt);
+	  break;
+	case MAG_FLUX_KRON_ERR:
+	  value.Flt = PhotAvedFluxKron (field->photcode, average, secfilt);
 	  break;
       }
@@ -498,5 +522,33 @@
       break;
 
-      // add the star/galaxy sep -- 
+    case MEAS_CENTER_OFFSET: /* OK */
+      { 
+	Image *image;
+	image = MatchImageDVO (measure[0].t, measure[0].photcode, measure[0].imageID);
+	if (image == NULL) break;
+	
+	// we have measure[0].Xccd,Yccd and image[0].NX,NY.  Find the distance to the center
+
+	// XXX we may hypotetically have images with -NX to +NX here (eg, projection center), but 
+	// we do not get a detection from that type of image
+	float Xcenter = 0.5*image[0].NX;
+	float Ycenter = 0.5*image[0].NY;
+	float distance = hypot (measure[0].Xccd - Xcenter, measure[0].Yccd - Ycenter);
+	value.Flt = distance;
+      }
+      break;
+
+    case MEAS_FLUX_PSF: /* OK */
+      value.Flt = measure[0].FluxPSF;
+      break;
+    case MEAS_FLUX_PSF_ERR: /* OK */
+      value.Flt = measure[0].dFluxPSF;
+      break;
+    case MEAS_FLUX_KRON: /* OK */
+      value.Flt = measure[0].FluxKron;
+      break;
+    case MEAS_FLUX_KRON_ERR: /* OK */
+      value.Flt = measure[0].dFluxKron;
+      break;
   }
   return (value);
Index: trunk/Ohana/src/libdvo/src/dbFields.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dbFields.c	(revision 34088)
+++ trunk/Ohana/src/libdvo/src/dbFields.c	(revision 34260)
@@ -30,24 +30,35 @@
 int GetMagMode (char *string) {
 
-  if (!strcasecmp (string, "inst"))      return (MAG_INST);
-  if (!strcasecmp (string, "cat"))       return (MAG_CAT);
-  if (!strcasecmp (string, "sys"))       return (MAG_SYS);
-  if (!strcasecmp (string, "rel"))       return (MAG_REL);
-  if (!strcasecmp (string, "cal"))       return (MAG_CAL);
-  if (!strcasecmp (string, "ave"))       return (MAG_AVE);
-  if (!strcasecmp (string, "ref"))       return (MAG_REF);
-  if (!strcasecmp (string, "ap"))        return (MAG_APER);
-  if (!strcasecmp (string, "aper"))      return (MAG_APER);
-  if (!strcasecmp (string, "err"))       return (MAG_ERR);
-  if (!strcasecmp (string, "aveerr"))    return (MAG_AVE_ERR);
-  if (!strcasecmp (string, "photflags")) return (MAG_PHOT_FLAGS);
-  if (!strcasecmp (string, "flags"))     return (MAG_PHOT_FLAGS);
-  if (!strcasecmp (string, "chisq"))     return (MAG_CHISQ);
-  if (!strcasecmp (string, "ncode"))     return (MAG_NCODE);
-  if (!strcasecmp (string, "nphot"))     return (MAG_NPHOT);
-  if (!strcasecmp (string, "stdev"))     return (MAG_STDEV);
-  if (!strcasecmp (string, "20"))        return (MAG_20);
-  if (!strcasecmp (string, "80"))        return (MAG_80);
-  if (!strcasecmp (string, "ucdist"))    return (MAG_UC_DIST);
+  if (!strcasecmp (string, "inst"))        return (MAG_INST);
+  if (!strcasecmp (string, "cat"))         return (MAG_CAT);
+  if (!strcasecmp (string, "sys"))         return (MAG_SYS);
+  if (!strcasecmp (string, "rel"))         return (MAG_REL);
+  if (!strcasecmp (string, "cal"))         return (MAG_CAL);
+  if (!strcasecmp (string, "ave"))         return (MAG_AVE);
+  if (!strcasecmp (string, "ref"))         return (MAG_REF);
+  if (!strcasecmp (string, "ap"))          return (MAG_APER);
+  if (!strcasecmp (string, "aper"))        return (MAG_APER);
+  if (!strcasecmp (string, "aperinst"))    return (MAG_APER_INST);
+  if (!strcasecmp (string, "aper_inst"))   return (MAG_APER_INST);
+  if (!strcasecmp (string, "kron"))        return (MAG_KRON);
+  if (!strcasecmp (string, "kroninst"))    return (MAG_KRON_INST);
+  if (!strcasecmp (string, "kron_inst"))   return (MAG_KRON_INST);
+  if (!strcasecmp (string, "kronerr"))     return (MAG_KRON_ERR);
+  if (!strcasecmp (string, "err"))         return (MAG_ERR);
+  if (!strcasecmp (string, "aveerr"))      return (MAG_AVE_ERR);
+  if (!strcasecmp (string, "photflags"))   return (MAG_PHOT_FLAGS);
+  if (!strcasecmp (string, "flags"))       return (MAG_PHOT_FLAGS);
+  if (!strcasecmp (string, "chisq"))       return (MAG_CHISQ);
+  if (!strcasecmp (string, "ncode"))       return (MAG_NCODE);
+  if (!strcasecmp (string, "nphot"))       return (MAG_NPHOT);
+  if (!strcasecmp (string, "stdev"))       return (MAG_STDEV);
+  if (!strcasecmp (string, "20"))          return (MAG_20);
+  if (!strcasecmp (string, "80"))          return (MAG_80);
+  if (!strcasecmp (string, "ucdist"))      return (MAG_UC_DIST);
+  if (!strcasecmp (string, "stackID"))     return (MAG_STACK_ID);
+  if (!strcasecmp (string, "fluxpsf"))     return (MAG_FLUX_PSF);
+  if (!strcasecmp (string, "fluxpsferr"))  return (MAG_FLUX_PSF_ERR);
+  if (!strcasecmp (string, "fluxkron"))    return (MAG_FLUX_KRON);
+  if (!strcasecmp (string, "fluxkronerr")) return (MAG_FLUX_KRON_ERR);
   return (MAG_NONE);
 }
@@ -229,4 +240,11 @@
   if (!strcasecmp (fieldName, "MCAL_OFFSET"))    ESCAPE (MEAS_MCAL_OFFSET,    MAG_NONE, OPIHI_FLT);
   if (!strcasecmp (fieldName, "FLAT"))    	 ESCAPE (MEAS_FLAT,           MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "CENTER_OFFSET"))  ESCAPE (MEAS_CENTER_OFFSET,  MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "FLUX"))       	 ESCAPE (MEAS_FLUX_PSF,       MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "FLUX_ERR"))       ESCAPE (MEAS_FLUX_PSF_ERR,   MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "FLUX_PSF"))       ESCAPE (MEAS_FLUX_PSF,       MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "FLUX_PSF_ERR"))   ESCAPE (MEAS_FLUX_PSF_ERR,   MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "FLUX_KRON"))      ESCAPE (MEAS_FLUX_KRON,      MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "FLUX_KRON_ERR"))  ESCAPE (MEAS_FLUX_KRON_ERR,  MAG_NONE, OPIHI_FLT);
 
   // for words that don't parse, try a photcode
@@ -242,4 +260,5 @@
   field->magMode = mode;
   switch (mode) {
+    case MAG_STACK_ID:
     case MAG_NCODE:
     case MAG_NPHOT:
@@ -336,4 +355,5 @@
   field->magMode = mode;
   switch (mode) {
+    case MAG_STACK_ID:
     case MAG_NCODE:
     case MAG_NPHOT:
Index: trunk/Ohana/src/libdvo/src/dvo_catalog.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dvo_catalog.c	(revision 34088)
+++ trunk/Ohana/src/libdvo/src/dvo_catalog.c	(revision 34260)
@@ -55,4 +55,5 @@
   if (!strcasecmp (catformat, "PS1_V2"))          return (DVO_FORMAT_PS1_V2);
   if (!strcasecmp (catformat, "PS1_V3"))          return (DVO_FORMAT_PS1_V3);
+  if (!strcasecmp (catformat, "PS1_V4"))          return (DVO_FORMAT_PS1_V4);
   if (!strcasecmp (catformat, "PS1_REF"))         return (DVO_FORMAT_PS1_REF);
   return (DVO_FORMAT_UNDEF);
@@ -66,4 +67,136 @@
   if (!strcasecmp (catmode, "SPLIT")) return (DVO_MODE_SPLIT);
   return (DVO_MODE_UNDEF);
+}
+
+// init all data, or just catalog data
+void dvo_average_init (Average *average) {
+  average->R         	   = 0;
+  average->D         	   = 0;
+  average->dR        	   = 0;
+  average->dD        	   = 0;
+
+  average->uR        	   = 0;
+  average->uD        	   = 0;
+  average->duR       	   = 0;
+  average->duD       	   = 0;
+  average->P         	   = 0;
+  average->dP        	   = 0;
+
+  average->ChiSqAve  	   = 0.0;
+  average->ChiSqPM   	   = 0.0;
+  average->ChiSqPar  	   = 0.0;
+  average->Tmean   	   = 0;
+  average->Trange   	   = 0;
+
+  average->Xp        	   = 0;
+  average->Npos    	   = 0;
+
+  average->Nmeasure        = 0;
+  average->Nmissing        = 0;
+  average->Nextend         = 0;
+  average->measureOffset   = -1;
+  average->missingOffset   = -1;
+  average->extendOffset    = -1;
+
+  average->flags           = 0;
+  average->photFlagsUpper  = 0;
+  average->photFlagsLower  = 0;
+
+  average->objID     	   = 0;
+  average->catID     	   = 0;
+  average->extID     	   = 0;
+}
+
+// init all data, or just catalog data
+void dvo_secfilt_init (SecFilt *secfilt) {
+  secfilt->M           = NAN;
+  secfilt->Map         = NAN;
+  secfilt->Mkron       = NAN;
+  secfilt->dMkron      = NAN;
+  secfilt->dM          = NAN;
+  secfilt->Xm          = NAN_S_SHORT;
+
+  secfilt->FluxPSF     = NAN;
+  secfilt->dFluxPSF    = NAN;
+  secfilt->FluxKron    = NAN;
+  secfilt->dFluxKron   = NAN;
+
+  secfilt->flags       = 0;
+  secfilt->Ncode       = 0;
+  secfilt->Nused       = 0;
+
+  secfilt->M_20        = NAN_S_SHORT;
+  secfilt->M_80        = NAN_S_SHORT;
+
+  secfilt->ubercalDist = 1000;
+  secfilt->Mstdev      = NAN_S_SHORT;
+  secfilt->stackID     = 0;
+
+  secfilt->dummy       = 0;
+}
+
+// init all data, or just catalog data
+void dvo_measure_init (Measure *measure) {
+ measure->M         = NAN;
+ measure->dR        = NAN;
+ measure->dD        = NAN;
+ measure->M         = NAN;
+ measure->Mcal      = NAN;
+ measure->Map       = NAN;
+ measure->Mkron     = NAN;
+ measure->dMkron    = NAN;
+ measure->dM        = NAN;
+ measure->dMcal     = NAN;
+ measure->dt        = NAN;
+
+ measure->FluxPSF   = NAN;
+ measure->dFluxPSF  = NAN;
+ measure->FluxKron  = NAN;
+ measure->dFluxKron = NAN;
+
+ measure->airmass   = NAN;
+ measure->az        = NAN;
+
+ measure->Xccd      = NAN;
+ measure->Yccd      = NAN;
+
+ measure->Sky       = NAN;
+ measure->dSky      = NAN;
+
+ measure->t         = 0;
+ measure->t_msec    = 0;
+ measure->averef    = 0;
+
+ measure->detID     = 0;
+ measure->imageID   = 0;
+ measure->objID     = 0;
+ measure->catID     = 0;
+ measure->extID     = 0;
+
+ measure->psfQual   = NAN;
+ measure->psfChisq  = NAN;
+ measure->psfNdof   = 0;
+ measure->psfNpix   = 0;
+ measure->crNsigma  = NAN;
+ measure->extNsigma = NAN;
+
+ measure->FWx       = 0;
+ measure->FWy       = 0;
+ measure->theta     = 0;
+
+ measure->Mxx       = 0;
+ measure->Mxy       = 0;
+ measure->Myy       = 0;
+
+ measure->dXccd     = 0;
+ measure->dYccd     = 0;
+ measure->dRsys     = 0;
+
+ measure->posangle  = 0;
+ measure->pltscale  = NAN;
+
+ measure->photcode  = 0;
+ measure->dbFlags   = 0;
+ measure->photFlags = 0;
 }
 
@@ -600,2 +733,3 @@
 }
 
+
Index: trunk/Ohana/src/libdvo/src/dvo_catalog_raw.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dvo_catalog_raw.c	(revision 34088)
+++ trunk/Ohana/src/libdvo/src/dvo_catalog_raw.c	(revision 34260)
@@ -89,4 +89,5 @@
       FORMAT_CASE (PS1_V2,    PS1_V2);
       FORMAT_CASE (PS1_V3,    PS1_V3);
+      FORMAT_CASE (PS1_V4,    PS1_V4);
       FORMAT_CASE (PS1_REF,   PS1_REF);
 
@@ -282,4 +283,5 @@
   if (catalog[0].catformat == DVO_FORMAT_PS1_V2)          gfits_modify (&catalog[0].header, "FORMAT", "%s", 1, "PS1_V2");
   if (catalog[0].catformat == DVO_FORMAT_PS1_V3)          gfits_modify (&catalog[0].header, "FORMAT", "%s", 1, "PS1_V3");
+  if (catalog[0].catformat == DVO_FORMAT_PS1_V4)          gfits_modify (&catalog[0].header, "FORMAT", "%s", 1, "PS1_V4");
   if (catalog[0].catformat == DVO_FORMAT_PS1_REF)         gfits_modify (&catalog[0].header, "FORMAT", "%s", 1, "PS1_REF");
 
@@ -384,4 +386,5 @@
       FORMAT_CASE (PS1_V2,    PS1_V2);
       FORMAT_CASE (PS1_V3,    PS1_V3);
+      FORMAT_CASE (PS1_V4,    PS1_V4);
       FORMAT_CASE (PS1_REF,   PS1_REF);
 
@@ -434,4 +437,5 @@
       FORMAT_CASE (PS1_V2,    PS1_V2);
       FORMAT_CASE (PS1_V3,    PS1_V3);
+      FORMAT_CASE (PS1_V4,    PS1_V4);
       FORMAT_CASE (PS1_REF,   PS1_REF);
 
@@ -488,4 +492,5 @@
       FORMAT_CASE (PS1_V2,    PS1_V2);
       FORMAT_CASE (PS1_V3,    PS1_V3);
+      FORMAT_CASE (PS1_V4,    PS1_V4);
       FORMAT_CASE (PS1_REF,   PS1_REF);
 
@@ -538,4 +543,5 @@
       FORMAT_CASE (PS1_V2,    PS1_V2);
       FORMAT_CASE (PS1_V3,    PS1_V3);
+      FORMAT_CASE (PS1_V4,    PS1_V4);
       FORMAT_CASE (PS1_REF,   PS1_REF);
 
@@ -592,4 +598,5 @@
       FORMAT_CASE (PS1_V2,    PS1_V2);
       FORMAT_CASE (PS1_V3,    PS1_V3);
+      FORMAT_CASE (PS1_V4,    PS1_V4);
       FORMAT_CASE (PS1_REF,   PS1_REF);
 
@@ -642,4 +649,5 @@
       FORMAT_CASE (PS1_V2,    PS1_V2);
       FORMAT_CASE (PS1_V3,    PS1_V3);
+      FORMAT_CASE (PS1_V4,    PS1_V4);
       FORMAT_CASE (PS1_REF,   PS1_REF);
 
Index: trunk/Ohana/src/libdvo/src/dvo_convert.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dvo_convert.c	(revision 34088)
+++ trunk/Ohana/src/libdvo/src/dvo_convert.c	(revision 34260)
@@ -40,4 +40,5 @@
   CONVERT_FORMAT ("DVO_AVERAGE_PS1_V2",          PS1_V2);
   CONVERT_FORMAT ("DVO_AVERAGE_PS1_V3",          PS1_V3);
+  CONVERT_FORMAT ("DVO_AVERAGE_PS1_V4",          PS1_V4);
   CONVERT_FORMAT ("DVO_AVERAGE_PS1_REF",         PS1_REF);
 # undef CONVERT_FORMAT
@@ -96,4 +97,5 @@
   CONVERT_FORMAT ("DVO_AVERAGE_PS1_V2",          PS1_V2,          PS1_V2);
   CONVERT_FORMAT ("DVO_AVERAGE_PS1_V3",          PS1_V3,          PS1_V3);
+  CONVERT_FORMAT ("DVO_AVERAGE_PS1_V4",          PS1_V4,          PS1_V4);
   CONVERT_FORMAT ("DVO_AVERAGE_PS1_REF",         PS1_REF,         PS1_REF);
 # undef CONVERT_FORMAT
@@ -130,4 +132,5 @@
       FORMAT_CASE (PS1_V2,          PS1_V2);
       FORMAT_CASE (PS1_V3,          PS1_V3);
+      FORMAT_CASE (PS1_V4,          PS1_V4);
       FORMAT_CASE (PS1_REF,         PS1_REF);
 # undef FORMAT_CASE
@@ -185,4 +188,5 @@
   CONVERT_FORMAT ("DVO_MEASURE_PS1_V2",          PS1_V2,          PS1_V2);
   CONVERT_FORMAT ("DVO_MEASURE_PS1_V3",          PS1_V3,          PS1_V3);
+  CONVERT_FORMAT ("DVO_MEASURE_PS1_V4",          PS1_V4,          PS1_V4);
   CONVERT_FORMAT ("DVO_MEASURE_PS1_REF",         PS1_REF,         PS1_REF);
 # undef CONVERT_FORMAT
@@ -219,4 +223,5 @@
       FORMAT_CASE (PS1_V2,          PS1_V2);
       FORMAT_CASE (PS1_V3,          PS1_V3);
+      FORMAT_CASE (PS1_V4,          PS1_V4);
       FORMAT_CASE (PS1_REF,         PS1_REF);
 # undef FORMAT_CASE
@@ -274,4 +279,5 @@
   CONVERT_FORMAT ("DVO_SECFILT_PS1_V2",          PS1_V2,          PS1_V2);
   CONVERT_FORMAT ("DVO_SECFILT_PS1_V3",          PS1_V3,          PS1_V3);
+  CONVERT_FORMAT ("DVO_SECFILT_PS1_V4",          PS1_V4,          PS1_V4);
   CONVERT_FORMAT ("DVO_SECFILT_PS1_REF",         PS1_REF,         PS1_REF);
 # undef CONVERT_FORMAT
@@ -308,4 +314,5 @@
       FORMAT_CASE (PS1_V2,          PS1_V2);
       FORMAT_CASE (PS1_V3,          PS1_V3);
+      FORMAT_CASE (PS1_V4,          PS1_V4);
       FORMAT_CASE (PS1_REF,         PS1_REF);
 # undef FORMAT_CASE
@@ -387,4 +394,5 @@
   CONVERT_FORMAT ("DVO_IMAGE_PS1_V2",          PS1_V2,          PS1_V2);
   CONVERT_FORMAT ("DVO_IMAGE_PS1_V3",          PS1_V3,          PS1_V3);
+  CONVERT_FORMAT ("DVO_IMAGE_PS1_V4",          PS1_V4,          PS1_V4);
   CONVERT_FORMAT ("DVO_IMAGE_PS1_REF",         PS1_REF,         PS1_REF);
 
@@ -425,4 +433,5 @@
       FORMAT_CASE (PS1_V2,          PS1_V2);
       FORMAT_CASE (PS1_V3,          PS1_V3);
+      FORMAT_CASE (PS1_V4,          PS1_V4);
       FORMAT_CASE (PS1_REF,         PS1_REF);
 
@@ -479,4 +488,5 @@
       FORMAT_CASE (PS1_V2,          PS1_V2);
       FORMAT_CASE (PS1_V3,          PS1_V3);
+      FORMAT_CASE (PS1_V4,          PS1_V4);
       FORMAT_CASE (PS1_REF,         PS1_REF);
 
Index: trunk/Ohana/src/libdvo/src/dvo_convert_PS1_DEV_1.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dvo_convert_PS1_DEV_1.c	(revision 34088)
+++ trunk/Ohana/src/libdvo/src/dvo_convert_PS1_DEV_1.c	(revision 34260)
@@ -57,4 +57,12 @@
     out[i].psfNdof    = 0;
     out[i].psfNpix    = 0;
+
+    // added for PS1_V4
+    out[i].Mkron      = NAN;
+    out[i].dMkron     = NAN;
+    out[i].FluxPSF    = NAN;
+    out[i].dFluxPSF   = NAN;
+    out[i].FluxKron   = NAN;
+    out[i].dFluxKron  = NAN;
   }
   return (out);
@@ -215,4 +223,13 @@
     out[i].Mstdev      = 0;
     out[i].ubercalDist = 0;
+
+    // added for PS1_V4
+    out[i].Mkron       = NAN;
+    out[i].dMkron      = NAN;
+    out[i].FluxPSF     = NAN;
+    out[i].dFluxPSF    = NAN;
+    out[i].FluxKron    = NAN;
+    out[i].dFluxKron   = NAN;
+    out[i].stackID     = 0;
  }
   return (out);
Index: trunk/Ohana/src/libdvo/src/dvo_convert_PS1_DEV_2.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dvo_convert_PS1_DEV_2.c	(revision 34088)
+++ trunk/Ohana/src/libdvo/src/dvo_convert_PS1_DEV_2.c	(revision 34260)
@@ -54,4 +54,12 @@
     out[i].psfNdof    = 0;
     out[i].psfNpix    = 0;
+
+    // added for PS1_V4
+    out[i].Mkron      = NAN;
+    out[i].dMkron     = NAN;
+    out[i].FluxPSF    = NAN;
+    out[i].dFluxPSF   = NAN;
+    out[i].FluxKron   = NAN;
+    out[i].dFluxKron  = NAN;
   }
   return (out);
@@ -209,4 +217,13 @@
     out[i].Mstdev      = 0;
     out[i].ubercalDist = 0;
+
+    // added for PS1_V4
+    out[i].Mkron       = NAN;
+    out[i].dMkron      = NAN;
+    out[i].FluxPSF     = NAN;
+    out[i].dFluxPSF    = NAN;
+    out[i].FluxKron    = NAN;
+    out[i].dFluxKron   = NAN;
+    out[i].stackID     = 0;
  }
   return (out);
Index: trunk/Ohana/src/libdvo/src/dvo_convert_PS1_REF.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dvo_convert_PS1_REF.c	(revision 34088)
+++ trunk/Ohana/src/libdvo/src/dvo_convert_PS1_REF.c	(revision 34260)
@@ -52,4 +52,12 @@
     out[i].dbFlags    = 0;
     out[i].photFlags  = 0;
+
+    // added for PS1_V4
+    out[i].Mkron      = NAN;
+    out[i].dMkron     = NAN;
+    out[i].FluxPSF    = NAN;
+    out[i].dFluxPSF   = NAN;
+    out[i].FluxKron   = NAN;
+    out[i].dFluxKron  = NAN;
   }
   return (out);
@@ -169,4 +177,13 @@
     out[i].Mstdev      = 0;
     out[i].ubercalDist = 0;
+
+    // added for PS1_V4
+    out[i].Mkron       = NAN;
+    out[i].dMkron      = NAN;
+    out[i].FluxPSF     = NAN;
+    out[i].dFluxPSF    = NAN;
+    out[i].FluxKron    = NAN;
+    out[i].dFluxKron   = NAN;
+    out[i].stackID     = 0;
  }
   return (out);
Index: trunk/Ohana/src/libdvo/src/dvo_convert_PS1_V1.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dvo_convert_PS1_V1.c	(revision 34088)
+++ trunk/Ohana/src/libdvo/src/dvo_convert_PS1_V1.c	(revision 34260)
@@ -52,4 +52,12 @@
     out[i].dbFlags    = in[i].dbFlags;
     out[i].photFlags  = in[i].photFlags;
+
+    // added for PS1_V4
+    out[i].Mkron      = NAN;
+    out[i].dMkron     = NAN;
+    out[i].FluxPSF    = NAN;
+    out[i].dFluxPSF   = NAN;
+    out[i].FluxKron   = NAN;
+    out[i].dFluxKron  = NAN;
   }
   return (out);
@@ -213,4 +221,13 @@
     out[i].Mstdev      = 0;
     out[i].ubercalDist = 0;
+
+    // added for PS1_V4
+    out[i].Mkron       = NAN;
+    out[i].dMkron      = NAN;
+    out[i].FluxPSF     = NAN;
+    out[i].dFluxPSF    = NAN;
+    out[i].FluxKron    = NAN;
+    out[i].dFluxKron   = NAN;
+    out[i].stackID     = 0;
  }
   return (out);
Index: trunk/Ohana/src/libdvo/src/dvo_convert_PS1_V2.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dvo_convert_PS1_V2.c	(revision 34088)
+++ trunk/Ohana/src/libdvo/src/dvo_convert_PS1_V2.c	(revision 34260)
@@ -53,4 +53,12 @@
     out[i].dbFlags    = in[i].dbFlags;
     out[i].photFlags  = in[i].photFlags;
+
+    // added for PS1_V4
+    out[i].Mkron      = NAN;
+    out[i].dMkron     = NAN;
+    out[i].FluxPSF    = NAN;
+    out[i].dFluxPSF   = NAN;
+    out[i].FluxKron   = NAN;
+    out[i].dFluxKron  = NAN;
   }
   return (out);
@@ -216,4 +224,13 @@
     out[i].Mstdev      = 0;
     out[i].ubercalDist = 0;
+
+    // added for PS1_V4
+    out[i].Mkron       = NAN;
+    out[i].dMkron      = NAN;
+    out[i].FluxPSF     = NAN;
+    out[i].dFluxPSF    = NAN;
+    out[i].FluxKron    = NAN;
+    out[i].dFluxKron   = NAN;
+    out[i].stackID     = 0;
  }
   return (out);
Index: trunk/Ohana/src/libdvo/src/dvo_convert_PS1_V3.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dvo_convert_PS1_V3.c	(revision 34088)
+++ trunk/Ohana/src/libdvo/src/dvo_convert_PS1_V3.c	(revision 34260)
@@ -53,4 +53,12 @@
     out[i].dbFlags    = in[i].dbFlags;
     out[i].photFlags  = in[i].photFlags;
+
+    // added for PS1_V4
+    out[i].Mkron      = NAN;
+    out[i].dMkron     = NAN;
+    out[i].FluxPSF    = NAN;
+    out[i].dFluxPSF   = NAN;
+    out[i].FluxKron   = NAN;
+    out[i].dFluxKron  = NAN;
   }
   return (out);
@@ -214,4 +222,13 @@
     out[i].Mstdev      = in[i].Mstdev;      
     out[i].ubercalDist = in[i].ubercalDist;      
+
+    // added for PS1_V4
+    out[i].Mkron       = NAN;
+    out[i].dMkron      = NAN;
+    out[i].FluxPSF     = NAN;
+    out[i].dFluxPSF    = NAN;
+    out[i].FluxKron    = NAN;
+    out[i].dFluxKron   = NAN;
+    out[i].stackID     = 0;
  }
   return (out);
Index: trunk/Ohana/src/libdvo/src/dvo_convert_PS1_V4.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dvo_convert_PS1_V4.c	(revision 34260)
+++ trunk/Ohana/src/libdvo/src/dvo_convert_PS1_V4.c	(revision 34260)
@@ -0,0 +1,463 @@
+# include <dvo.h>
+
+/* convert PS1_V4 formats to internal formats */
+
+Measure *Measure_PS1_V4_ToInternal (Measure_PS1_V4 *in, off_t Nvalues) {
+
+  off_t i;
+  Measure *out;
+
+  ALLOCATE_ZERO (out, Measure, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    out[i].dR         = in[i].dR;
+    out[i].dD         = in[i].dD;
+    out[i].M          = in[i].M;
+    out[i].Mcal       = in[i].Mcal;
+    out[i].Map        = in[i].Map;
+    out[i].Mkron      = in[i].Mkron;
+    out[i].dMkron     = in[i].dMkron;
+    out[i].dM         = in[i].dM;
+    out[i].dMcal      = in[i].dMcal;
+    out[i].dt         = in[i].dt;
+    out[i].FluxPSF    = in[i].FluxPSF;
+    out[i].dFluxPSF   = in[i].dFluxPSF;
+    out[i].FluxKron   = in[i].FluxKron;
+    out[i].dFluxKron  = in[i].dFluxKron;
+    out[i].airmass    = in[i].airmass;
+    out[i].az         = in[i].az;
+    out[i].Xccd       = in[i].Xccd;
+    out[i].Yccd       = in[i].Yccd;
+    out[i].Sky        = in[i].Sky;
+    out[i].dSky       = in[i].dSky;
+    out[i].t          = in[i].t;
+    out[i].t_msec     = in[i].t_msec;
+    out[i].averef     = in[i].averef;
+    out[i].detID      = in[i].detID;
+    out[i].imageID    = in[i].imageID;
+    out[i].objID      = in[i].objID;
+    out[i].catID      = in[i].catID;
+    out[i].extID      = in[i].extID;
+    out[i].psfQual    = in[i].psfQual;
+    out[i].psfChisq   = in[i].psfChisq;
+    out[i].psfNdof    = in[i].psfNdof;
+    out[i].psfNpix    = in[i].psfNpix;
+    out[i].crNsigma   = in[i].crNsigma;
+    out[i].extNsigma  = in[i].extNsigma;
+    out[i].FWx 	      = in[i].FWx;
+    out[i].FWy 	      = in[i].FWy;
+    out[i].theta      = in[i].theta;
+    out[i].Mxx 	      = in[i].Mxx;
+    out[i].Mxy 	      = in[i].Mxy;
+    out[i].Myy 	      = in[i].Myy;
+    out[i].dXccd      = in[i].dXccd;
+    out[i].dYccd      = in[i].dYccd;
+    out[i].dRsys      = in[i].dRsys;
+    out[i].posangle   = in[i].posangle;
+    out[i].pltscale   = in[i].pltscale;
+    out[i].photcode   = in[i].photcode;
+    out[i].dbFlags    = in[i].dbFlags;
+    out[i].photFlags  = in[i].photFlags;
+  }
+  return (out);
+}
+
+Measure_PS1_V4 *MeasureInternalTo_PS1_V4 (Measure *in, off_t Nvalues) {
+
+  off_t i;
+  Measure_PS1_V4 *out;
+
+  ALLOCATE_ZERO (out, Measure_PS1_V4, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    out[i].dR         = in[i].dR;
+    out[i].dD         = in[i].dD;
+    out[i].M          = in[i].M;
+    out[i].Mcal       = in[i].Mcal;
+    out[i].Map        = in[i].Map;
+    out[i].Mkron      = in[i].Mkron;
+    out[i].dMkron     = in[i].dMkron;
+    out[i].dM         = in[i].dM;
+    out[i].dMcal      = in[i].dMcal;
+    out[i].dt         = in[i].dt;
+    out[i].FluxPSF    = in[i].FluxPSF;
+    out[i].dFluxPSF   = in[i].dFluxPSF;
+    out[i].FluxKron   = in[i].FluxKron;
+    out[i].dFluxKron  = in[i].dFluxKron;
+    out[i].airmass    = in[i].airmass;
+    out[i].az         = in[i].az;
+    out[i].Xccd       = in[i].Xccd;
+    out[i].Yccd       = in[i].Yccd;
+    out[i].Sky        = in[i].Sky;
+    out[i].dSky       = in[i].dSky;
+    out[i].t          = in[i].t;
+    out[i].t_msec     = in[i].t_msec;
+    out[i].averef     = in[i].averef;
+    out[i].detID      = in[i].detID;
+    out[i].imageID    = in[i].imageID;
+    out[i].objID      = in[i].objID;
+    out[i].catID      = in[i].catID;
+    out[i].extID      = in[i].extID;
+    out[i].psfQual    = in[i].psfQual;
+    out[i].psfChisq   = in[i].psfChisq;
+    out[i].psfNdof    = in[i].psfNdof;
+    out[i].psfNpix    = in[i].psfNpix;
+    out[i].crNsigma   = in[i].crNsigma;
+    out[i].extNsigma  = in[i].extNsigma;
+    out[i].FWx 	      = in[i].FWx;
+    out[i].FWy 	      = in[i].FWy;
+    out[i].theta      = in[i].theta;
+    out[i].Mxx 	      = in[i].Mxx;
+    out[i].Mxy 	      = in[i].Mxy;
+    out[i].Myy 	      = in[i].Myy;
+    out[i].dXccd      = in[i].dXccd;
+    out[i].dYccd      = in[i].dYccd;
+    out[i].dRsys      = in[i].dRsys;
+    out[i].posangle   = in[i].posangle;
+    out[i].pltscale   = in[i].pltscale;
+    out[i].photcode   = in[i].photcode;
+    out[i].dbFlags    = in[i].dbFlags;
+    out[i].photFlags  = in[i].photFlags;
+  }
+  return (out);
+}
+
+// 'primary' is needed to conform with the API for Loneos and Elixir, but is not used
+Average *Average_PS1_V4_ToInternal (Average_PS1_V4 *in, off_t Nvalues, SecFilt **primary) {
+
+  off_t i;
+  Average *out;
+
+  ALLOCATE_ZERO (out, Average, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    out[i].R        	 = in[i].R;      
+    out[i].D        	 = in[i].D;      
+    out[i].dR       	 = in[i].dR;
+    out[i].dD       	 = in[i].dD;
+    out[i].uR       	 = in[i].uR;
+    out[i].uD       	 = in[i].uD;
+    out[i].duR      	 = in[i].duR;
+    out[i].duD      	 = in[i].duD;
+    out[i].P        	 = in[i].P;
+    out[i].dP       	 = in[i].dP;
+    out[i].Xp       	 = in[i].Xp;     
+    out[i].ChiSqAve    	 = in[i].ChiSqAve;     
+    out[i].ChiSqPM    	 = in[i].ChiSqPM;     
+    out[i].ChiSqPar    	 = in[i].ChiSqPar;     
+    out[i].Tmean    	 = in[i].Tmean;     
+    out[i].Trange   	 = in[i].Trange;     
+    out[i].Npos       	 = in[i].Npos;     
+    out[i].Nmeasure      = in[i].Nmeasure;     
+    out[i].Nmissing      = in[i].Nmissing;     
+    out[i].Nextend       = in[i].Nextend;     
+    out[i].measureOffset = in[i].measureOffset; 
+    out[i].missingOffset = in[i].missingOffset;
+    out[i].extendOffset  = in[i].extendOffset;
+    out[i].flags     	 = in[i].flags;   
+    out[i].photFlagsUpper = in[i].photFlagsUpper;   
+    out[i].photFlagsLower = in[i].photFlagsLower;   
+    out[i].objID 	 = in[i].objID;
+    out[i].catID 	 = in[i].catID;
+    out[i].extID 	 = in[i].extID;
+  }
+  return (out);
+}
+
+// 'primary' is needed to conform with the API for Loneos and Elixir, but is not used
+Average_PS1_V4 *AverageInternalTo_PS1_V4 (Average *in, off_t Nvalues, SecFilt *primary) {
+
+  off_t i;
+  Average_PS1_V4 *out;
+
+  ALLOCATE_ZERO (out, Average_PS1_V4, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    out[i].R        	 = in[i].R;      
+    out[i].D        	 = in[i].D;      
+    out[i].dR       	 = in[i].dR;
+    out[i].dD       	 = in[i].dD;
+    out[i].uR       	 = in[i].uR;
+    out[i].uD       	 = in[i].uD;
+    out[i].duR      	 = in[i].duR;
+    out[i].duD      	 = in[i].duD;
+    out[i].P        	 = in[i].P;
+    out[i].dP       	 = in[i].dP;
+    out[i].Xp       	 = in[i].Xp;     
+    out[i].ChiSqAve    	 = in[i].ChiSqAve;     
+    out[i].ChiSqPM     	 = in[i].ChiSqPM;     
+    out[i].ChiSqPar   	 = in[i].ChiSqPar;     
+    out[i].Tmean    	 = in[i].Tmean;     
+    out[i].Trange   	 = in[i].Trange;     
+    out[i].Npos       	 = in[i].Npos;     
+    out[i].Nmeasure      = in[i].Nmeasure;     
+    out[i].Nmissing      = in[i].Nmissing;     
+    out[i].Nextend       = in[i].Nextend;     
+    out[i].measureOffset = in[i].measureOffset; 
+    out[i].missingOffset = in[i].missingOffset;
+    out[i].extendOffset  = in[i].extendOffset;
+    out[i].flags     	 = in[i].flags;   
+    out[i].photFlagsUpper = in[i].photFlagsUpper;   
+    out[i].photFlagsLower = in[i].photFlagsLower;   
+    out[i].objID 	 = in[i].objID;
+    out[i].catID 	 = in[i].catID;
+    out[i].extID 	 = in[i].extID;
+  }
+  return (out);
+}
+
+SecFilt *SecFilt_PS1_V4_ToInternal (SecFilt_PS1_V4 *in, off_t Nvalues) {
+
+  off_t i;
+  SecFilt *out;
+
+  ALLOCATE_ZERO (out, SecFilt, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    out[i].M           = in[i].M;      
+    out[i].Map         = in[i].Map;      
+    out[i].Mkron       = in[i].Mkron;      
+    out[i].dMkron      = in[i].dMkron;      
+    out[i].dM          = in[i].dM;      
+    out[i].Xm          = in[i].Xm;     
+    out[i].FluxPSF     = in[i].FluxPSF;
+    out[i].dFluxPSF    = in[i].dFluxPSF;
+    out[i].FluxKron    = in[i].FluxKron;
+    out[i].dFluxKron   = in[i].dFluxKron;
+    out[i].flags       = in[i].flags;     
+    out[i].Ncode       = in[i].Ncode;
+    out[i].Nused       = in[i].Nused;
+    out[i].M_20        = in[i].M_20;      
+    out[i].M_80        = in[i].M_80;      
+    out[i].Mstdev      = in[i].Mstdev;      
+    out[i].ubercalDist = in[i].ubercalDist;      
+    out[i].stackID     = in[i].stackID;      
+ }
+  return (out);
+}
+
+SecFilt_PS1_V4 *SecFiltInternalTo_PS1_V4 (SecFilt *in, off_t Nvalues) {
+
+  off_t i;
+  SecFilt_PS1_V4 *out;
+
+  ALLOCATE_ZERO (out, SecFilt_PS1_V4, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    out[i].M           = in[i].M;      
+    out[i].Map         = in[i].Map;      
+    out[i].Mkron       = in[i].Mkron;      
+    out[i].dMkron      = in[i].dMkron;      
+    out[i].dM          = in[i].dM;      
+    out[i].Xm          = in[i].Xm;     
+    out[i].FluxPSF     = in[i].FluxPSF;
+    out[i].dFluxPSF    = in[i].dFluxPSF;
+    out[i].FluxKron    = in[i].FluxKron;
+    out[i].dFluxKron   = in[i].dFluxKron;
+    out[i].flags       = in[i].flags;     
+    out[i].Ncode       = in[i].Ncode;
+    out[i].Nused       = in[i].Nused;
+    out[i].M_20        = in[i].M_20;      
+    out[i].M_80        = in[i].M_80;      
+    out[i].Mstdev      = in[i].Mstdev;      
+    out[i].ubercalDist = in[i].ubercalDist;      
+    out[i].stackID     = in[i].stackID;      
+  }
+  return (out);
+}
+
+Image *Image_PS1_V4_ToInternal (Image_PS1_V4 *in, off_t Nvalues) {
+
+  off_t i;
+  Image *out;
+
+  ALLOCATE_ZERO (out, Image, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
+
+    strncpy (out[i].name, in[i].name, 120); // out[121], in[121]
+    out[i].name[120] = 0; // force termination
+
+    out[i].tzero    	    = in[i].tzero;
+    out[i].nstar    	    = in[i].nstar;
+    out[i].secz	    	    = in[i].secz;
+    out[i].NX	    	    = in[i].NX;
+    out[i].NY	    	    = in[i].NY;
+    out[i].apmifit  	    = in[i].apmifit;
+    out[i].dapmifit 	    = in[i].dapmifit;
+    out[i].Mcal	    	    = in[i].Mcal;
+    out[i].dMcal    	    = in[i].dMcal;
+    out[i].Xm	    	    = in[i].Xm;
+    out[i].photcode   	    = in[i].photcode;
+    out[i].exptime  	    = in[i].exptime;
+    out[i].sidtime  	    = in[i].sidtime;
+    out[i].latitude  	    = in[i].latitude;
+
+    out[i].RAo  	    = in[i].RAo;
+    out[i].DECo  	    = in[i].DECo;
+    out[i].Radius  	    = in[i].Radius;
+
+    out[i].detection_limit  = in[i].detection_limit;
+    out[i].saturation_limit = in[i].saturation_limit;
+    out[i].cerror	    = in[i].cerror;
+    out[i].fwhm_x	    = in[i].fwhm_x;
+    out[i].fwhm_y	    = in[i].fwhm_y;
+    out[i].trate	    = in[i].trate;
+    out[i].ccdnum	    = in[i].ccdnum;
+    out[i].flags	    = in[i].flags;
+    out[i].imageID	    = in[i].imageID;
+    out[i].parentID	    = in[i].parentID;
+    out[i].externID	    = in[i].externID;
+    out[i].sourceID	    = in[i].sourceID;
+
+    // as of 2011.02.03, the old Mx,My,..., Mxxxx,Myyyy have been deprecated and replaced
+    // with the following.  (no real databases used those values -- see
+    // libdvo/doc/dvo-images.txt)
+    out[i].nLinkAstrom	    = in[i].nLinkAstrom;
+    out[i].nLinkPhotom	    = in[i].nLinkPhotom;
+    out[i].ubercalDist	    = in[i].ubercalDist;
+    out[i].dXpixSys	    = in[i].dXpixSys;
+    out[i].dYpixSys	    = in[i].dYpixSys;
+    out[i].dMagSys	    = in[i].dMagSys;
+    out[i].nFitAstrom       = in[i].nFitAstrom;
+    out[i].nFitPhotom       = in[i].nFitPhotom;
+    out[i].photom_map_id    = in[i].photom_map_id;
+    out[i].astrom_map_id    = in[i].astrom_map_id;
+  }
+  return (out);
+}
+
+Image_PS1_V4 *ImageInternalTo_PS1_V4 (Image *in, off_t Nvalues) {
+
+  off_t i;
+  Image_PS1_V4 *out;
+
+  ALLOCATE_ZERO (out, Image_PS1_V4, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
+
+    strncpy (out[i].name, in[i].name, 120); // out[121], in[121]
+    out[i].name[120] = 0; // force termination
+
+    out[i].tzero    	    = in[i].tzero;
+    out[i].nstar    	    = in[i].nstar;
+    out[i].secz	    	    = in[i].secz;
+    out[i].NX	    	    = in[i].NX;
+    out[i].NY	    	    = in[i].NY;
+    out[i].apmifit  	    = in[i].apmifit;
+    out[i].dapmifit 	    = in[i].dapmifit;
+    out[i].Mcal	    	    = in[i].Mcal;
+    out[i].dMcal    	    = in[i].dMcal;
+    out[i].Xm	    	    = in[i].Xm;
+    out[i].photcode   	    = in[i].photcode;
+    out[i].exptime  	    = in[i].exptime;
+    out[i].sidtime  	    = in[i].sidtime;
+    out[i].latitude  	    = in[i].latitude;
+
+    out[i].RAo  	    = in[i].RAo;
+    out[i].DECo  	    = in[i].DECo;
+    out[i].Radius  	    = in[i].Radius;
+
+    out[i].detection_limit  = in[i].detection_limit;
+    out[i].saturation_limit = in[i].saturation_limit;
+    out[i].cerror	    = in[i].cerror;
+    out[i].fwhm_x	    = in[i].fwhm_x;
+    out[i].fwhm_y	    = in[i].fwhm_y;
+    out[i].trate	    = in[i].trate;
+    out[i].ccdnum	    = in[i].ccdnum;
+    out[i].flags	    = in[i].flags;
+    out[i].imageID	    = in[i].imageID;
+    out[i].parentID	    = in[i].parentID;
+    out[i].externID	    = in[i].externID;
+    out[i].sourceID	    = in[i].sourceID;
+
+    // as of 2011.02.03, the old Mx,My,..., Mxxxx,Myyyy have been deprecated and replaced
+    // with the following.  (no real databases used those values -- see
+    // libdvo/doc/dvo-images.txt)
+    out[i].nLinkAstrom	    = in[i].nLinkAstrom;
+    out[i].nLinkPhotom	    = in[i].nLinkPhotom;
+    out[i].ubercalDist	    = in[i].ubercalDist;
+    out[i].dXpixSys	    = in[i].dXpixSys;
+    out[i].dYpixSys	    = in[i].dYpixSys;
+    out[i].dMagSys	    = in[i].dMagSys;
+    out[i].nFitAstrom       = in[i].nFitAstrom;
+    out[i].nFitPhotom       = in[i].nFitPhotom;
+    out[i].photom_map_id    = in[i].photom_map_id;
+    out[i].astrom_map_id    = in[i].astrom_map_id;
+  }
+  return (out);
+}
+
+PhotCode *PhotCode_PS1_V4_To_Internal (PhotCode_PS1_V4 *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_V4 *PhotCode_Internal_To_PS1_V4 (PhotCode *in, off_t Nvalues) {
+
+  off_t i;
+  PhotCode_PS1_V4 *out;
+
+  ALLOCATE_ZERO (out, PhotCode_PS1_V4, 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: trunk/Ohana/src/libdvo/src/dvo_convert_elixir.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dvo_convert_elixir.c	(revision 34088)
+++ trunk/Ohana/src/libdvo/src/dvo_convert_elixir.c	(revision 34260)
@@ -64,4 +64,12 @@
     out[i].psfNdof    = 0;
     out[i].psfNpix    = 0;
+
+    // added for PS1_V4
+    out[i].Mkron      = NAN;
+    out[i].dMkron     = NAN;
+    out[i].FluxPSF    = NAN;
+    out[i].dFluxPSF   = NAN;
+    out[i].FluxKron   = NAN;
+    out[i].dFluxKron  = NAN;
   }
   return (out);
@@ -224,4 +232,13 @@
     out[i].Mstdev      = 0;
     out[i].ubercalDist = 0;
+
+    // added for PS1_V4
+    out[i].Mkron       = NAN;
+    out[i].dMkron      = NAN;
+    out[i].FluxPSF    = NAN;
+    out[i].dFluxPSF   = NAN;
+    out[i].FluxKron   = NAN;
+    out[i].dFluxKron  = NAN;
+    out[i].stackID     = 0;
   }
   return (out);
Index: trunk/Ohana/src/libdvo/src/dvo_convert_loneos.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dvo_convert_loneos.c	(revision 34088)
+++ trunk/Ohana/src/libdvo/src/dvo_convert_loneos.c	(revision 34260)
@@ -66,4 +66,12 @@
     out[i].psfNdof    = 0;
     out[i].psfNpix    = 0;
+
+    // added for PS1_V4
+    out[i].Mkron      = NAN;
+    out[i].dMkron     = NAN;
+    out[i].FluxPSF    = NAN;
+    out[i].dFluxPSF   = NAN;
+    out[i].FluxKron   = NAN;
+    out[i].dFluxKron  = NAN;
   }
   return (out);
@@ -217,4 +225,13 @@
     out[i].Mstdev      = 0;
     out[i].ubercalDist = 0;
+
+    // added for PS1_V4
+    out[i].Mkron       = NAN;
+    out[i].dMkron      = NAN;
+    out[i].FluxPSF    = NAN;
+    out[i].dFluxPSF   = NAN;
+    out[i].FluxKron   = NAN;
+    out[i].dFluxKron  = NAN;
+    out[i].stackID     = 0;
   }
   return (out);
Index: trunk/Ohana/src/libdvo/src/dvo_convert_panstarrs_DEV_0.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dvo_convert_panstarrs_DEV_0.c	(revision 34088)
+++ trunk/Ohana/src/libdvo/src/dvo_convert_panstarrs_DEV_0.c	(revision 34260)
@@ -61,4 +61,12 @@
     out[i].psfNdof    = 0;
     out[i].psfNpix    = 0;
+
+    // added for PS1_V4
+    out[i].Mkron      = NAN;
+    out[i].dMkron     = NAN;
+    out[i].FluxPSF     = NAN;
+    out[i].dFluxPSF    = NAN;
+    out[i].FluxKron    = NAN;
+    out[i].dFluxKron   = NAN;
   }
   return (out);
@@ -224,4 +232,13 @@
     out[i].Mstdev      = 0;
     out[i].ubercalDist = 0;
+
+    // added for PS1_V4
+    out[i].Mkron       = NAN;
+    out[i].dMkron      = NAN;
+    out[i].FluxPSF     = NAN;
+    out[i].dFluxPSF    = NAN;
+    out[i].FluxKron    = NAN;
+    out[i].dFluxKron   = NAN;
+    out[i].stackID     = 0;
  }
   return (out);
Index: trunk/Ohana/src/libdvo/src/dvo_convert_panstarrs_DEV_1.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dvo_convert_panstarrs_DEV_1.c	(revision 34088)
+++ trunk/Ohana/src/libdvo/src/dvo_convert_panstarrs_DEV_1.c	(revision 34260)
@@ -61,4 +61,12 @@
     out[i].psfNdof    = 0;
     out[i].psfNpix    = 0;
+
+    // added for PS1_V4
+    out[i].Mkron      = NAN;
+    out[i].dMkron     = NAN;
+    out[i].FluxPSF     = NAN;
+    out[i].dFluxPSF    = NAN;
+    out[i].FluxKron    = NAN;
+    out[i].dFluxKron   = NAN;
   }
   return (out);
@@ -224,4 +232,13 @@
     out[i].Mstdev      = 0;
     out[i].ubercalDist = 0;
+
+    // added for PS1_V4
+    out[i].Mkron       = NAN;
+    out[i].dMkron      = NAN;
+    out[i].FluxPSF     = NAN;
+    out[i].dFluxPSF    = NAN;
+    out[i].FluxKron    = NAN;
+    out[i].dFluxKron   = NAN;
+    out[i].stackID     = 0;
  }
   return (out);
Index: trunk/Ohana/src/libdvo/src/dvo_image.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dvo_image.c	(revision 34088)
+++ trunk/Ohana/src/libdvo/src/dvo_image.c	(revision 34260)
@@ -212,4 +212,5 @@
   if (db[0].format == DVO_FORMAT_PS1_V2)          gfits_modify (&db[0].header, "FORMAT", "%s", 1, "PS1_V2");
   if (db[0].format == DVO_FORMAT_PS1_V3)          gfits_modify (&db[0].header, "FORMAT", "%s", 1, "PS1_V3");
+  if (db[0].format == DVO_FORMAT_PS1_V4)          gfits_modify (&db[0].header, "FORMAT", "%s", 1, "PS1_V4");
   if (db[0].format == DVO_FORMAT_PS1_REF)         gfits_modify (&db[0].header, "FORMAT", "%s", 1, "PS1_REF");
   
Index: trunk/Ohana/src/libdvo/src/dvo_image_raw.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dvo_image_raw.c	(revision 34088)
+++ trunk/Ohana/src/libdvo/src/dvo_image_raw.c	(revision 34260)
@@ -58,4 +58,5 @@
   if (db[0].format == DVO_FORMAT_PS1_V2)          ImageSize = sizeof(Image_PS1_V2);
   if (db[0].format == DVO_FORMAT_PS1_V3)          ImageSize = sizeof(Image_PS1_V3);
+  if (db[0].format == DVO_FORMAT_PS1_V4)          ImageSize = sizeof(Image_PS1_V4);
   if (db[0].format == DVO_FORMAT_PS1_REF)         ImageSize = sizeof(Image_PS1_REF);
 
@@ -87,4 +88,5 @@
   if (db[0].format == DVO_FORMAT_PS1_V2)          gfits_table_mkheader_Image_PS1_V2 (&db[0].theader);
   if (db[0].format == DVO_FORMAT_PS1_V3)          gfits_table_mkheader_Image_PS1_V3 (&db[0].theader);
+  if (db[0].format == DVO_FORMAT_PS1_V4)          gfits_table_mkheader_Image_PS1_V4 (&db[0].theader);
   if (db[0].format == DVO_FORMAT_PS1_REF)         gfits_table_mkheader_Image_PS1_REF (&db[0].theader);
     
Index: trunk/Ohana/src/libdvo/src/dvo_photcode_ops.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dvo_photcode_ops.c	(revision 34088)
+++ trunk/Ohana/src/libdvo/src/dvo_photcode_ops.c	(revision 34260)
@@ -278,4 +278,57 @@
 }
 
+float PhotAperInst (Measure *measure) {
+
+  int Np;
+  float Minst;
+
+  Np = photcodes[0].hashcode[measure[0].photcode];
+  if (Np == -1) return (NAN);
+
+  if (photcodes[0].code[Np].type == PHOT_REF) {
+    Minst = measure[0].Map;
+    return (Minst);
+  }
+  Minst = measure[0].Map - measure[0].dt - ZERO_POINT;
+  
+  return (Minst);
+}
+
+float PhotKron (Measure *measure) {
+
+  int Np;
+  float Mcat;
+  PhotCode *code;
+
+  Np = photcodes[0].hashcode[measure[0].photcode];
+  if (Np == -1) return (NAN);
+
+  if (photcodes[0].code[Np].type == PHOT_REF) {
+    Mcat = measure[0].Mkron;
+    return (Mcat);
+  }
+  code = &photcodes[0].code[Np];
+  Mcat = measure[0].Mkron - ZERO_POINT + code[0].K*(measure[0].airmass - 1.000) + SCALE*code[0].C;
+  
+  return (Mcat);
+}
+
+float PhotKronInst (Measure *measure) {
+
+  int Np;
+  float Minst;
+
+  Np = photcodes[0].hashcode[measure[0].photcode];
+  if (Np == -1) return (NAN);
+
+  if (photcodes[0].code[Np].type == PHOT_REF) {
+    Minst = measure[0].Mkron;
+    return (Minst);
+  }
+  Minst = measure[0].Mkron - measure[0].dt - ZERO_POINT;
+  
+  return (Minst);
+}
+
 float PhotSys (Measure *measure, Average *average, SecFilt *secfilt) {
 
@@ -307,4 +360,23 @@
   Msys = Mcat + Mcol;
   return (Msys);
+}
+
+float PhotZeroPoint (Measure *measure, Average *average, SecFilt *secfilt) {
+
+  int Np;
+  float ZP;
+  PhotCode *code;
+
+  Np = photcodes[0].hashcode[measure[0].photcode];
+  if (Np == -1) return (NAN);
+
+  if (photcodes[0].code[Np].type == PHOT_REF) {
+    ZP = 0.0;
+    return (ZP);
+  }
+  code = &photcodes[0].code[Np];
+  ZP = code[0].K*(measure[0].airmass - 1.000) + SCALE*code[0].C;
+
+  return (ZP);
 }
 
@@ -488,4 +560,64 @@
 }
 
+float PhotKronAve (PhotCode *code, Average *average, SecFilt *secfilt) {
+
+  int Ns;
+  float Mkron;
+
+  if (code == NULL) return NAN;
+
+  Ns = photcodes[0].hashNsec[code[0].code];
+  Mkron = (Ns == -1) ? NAN : secfilt[Ns].Mkron;
+  return (Mkron);
+}
+
+float PhotAveFluxPSF (PhotCode *code, Average *average, SecFilt *secfilt) {
+
+  int Ns;
+  float Fpsf;
+
+  if (code == NULL) return NAN;
+
+  Ns = photcodes[0].hashNsec[code[0].code];
+  Fpsf = (Ns == -1) ? NAN : secfilt[Ns].FluxPSF;
+  return (Fpsf);
+}
+
+float PhotAvedFluxPSF (PhotCode *code, Average *average, SecFilt *secfilt) {
+
+  int Ns;
+  float dFpsf;
+
+  if (code == NULL) return NAN;
+
+  Ns = photcodes[0].hashNsec[code[0].code];
+  dFpsf = (Ns == -1) ? NAN : secfilt[Ns].dFluxPSF;
+  return (dFpsf);
+}
+
+float PhotAveFluxKron (PhotCode *code, Average *average, SecFilt *secfilt) {
+
+  int Ns;
+  float Fkron;
+
+  if (code == NULL) return NAN;
+
+  Ns = photcodes[0].hashNsec[code[0].code];
+  Fkron = (Ns == -1) ? NAN : secfilt[Ns].FluxKron;
+  return (Fkron);
+}
+
+float PhotAvedFluxKron (PhotCode *code, Average *average, SecFilt *secfilt) {
+
+  int Ns;
+  float dFkron;
+
+  if (code == NULL) return NAN;
+
+  Ns = photcodes[0].hashNsec[code[0].code];
+  dFkron = (Ns == -1) ? NAN : secfilt[Ns].dFluxKron;
+  return (dFkron);
+}
+
 float PhotM20 (PhotCode *code, Average *average, SecFilt *secfilt) {
 
@@ -522,4 +654,16 @@
   Muc  = (Ns == -1) ? NAN : secfilt[Ns].ubercalDist;
   return (Muc);
+}
+
+unsigned int PhotStackID (PhotCode *code, Average *average, SecFilt *secfilt) {
+
+  int Ns;
+  unsigned int ID;
+
+  if (code == NULL) return 0;
+
+  Ns = photcodes[0].hashNsec[code[0].code];
+  ID = (Ns == -1) ? 0 : secfilt[Ns].stackID;
+  return (ID);
 }
 
