Index: trunk/Ohana/src/libdvo/Makefile
===================================================================
--- trunk/Ohana/src/libdvo/Makefile	(revision 35263)
+++ trunk/Ohana/src/libdvo/Makefile	(revision 35416)
@@ -36,5 +36,6 @@
 $(DESTINC)/ps1_v3_defs.h \
 $(DESTINC)/ps1_v4_defs.h \
-$(DESTINC)/ps1_ref_defs.h
+$(DESTINC)/ps1_ref_defs.h \
+$(DESTINC)/cmf-ps1-dv3.h
 
 INCS = $(DEFS) $(DESTINC)/dvo.h $(DESTINC)/autocode.h $(DESTINC)/dvo_util.h $(DESTINC)/dvodb.h $(DESTINC)/libdvo_astro.h $(DESTINC)/convert.h $(DESTINC)/get_graphdata.h
@@ -84,4 +85,5 @@
 $(SRC)/cmf-ps1-v1-alt.$(ARCH).o \
 $(SRC)/cmf-ps1-sv1-alt.$(ARCH).o \
+$(SRC)/cmf-ps1-dv3.$(ARCH).o \
 $(SRC)/dvo_util.$(ARCH).o \
 $(SRC)/dbBooleanCond.$(ARCH).o		\
Index: trunk/Ohana/src/libdvo/include/cmf-ps1-dv3.h
===================================================================
--- trunk/Ohana/src/libdvo/include/cmf-ps1-dv3.h	(revision 35416)
+++ trunk/Ohana/src/libdvo/include/cmf-ps1-dv3.h	(revision 35416)
@@ -0,0 +1,61 @@
+
+/** STRUCT DEFINITION **/
+typedef struct {
+  unsigned int     detID;                // detection ID                     
+  float            X;                    // x coord (pixels)
+  float            Y;                    // y coord (pixels)
+  float            dX;                   // x coord error (pixels)
+  float            dY;                   // y coord error (pixels)
+  float            posangle;             // Posangle at source (degrees)
+  float            pltscale;             // Plate Scale at source (arcsec/pixel)
+  float            M;                    // inst mags (mags)
+  float            dM;                   // inst mag error (mags)
+  float            Flux;                 // psf flux (counts)
+  float            dFlux;                // psf flux error (counts      )
+  float            Map;                  // standard aperture mag (mags)
+  float            MapRaw;               // raw aperture mag (mags)
+  float            apRadius;             // radius used for fit (pixels)
+  float            apFlux;               // ap flux
+  float            apFluxErr;            // ap flux err
+  float            Mpeak;                // peak flux as a mag (mags)
+  float            Mcalib;               // calibrated psf mag (mags)
+  float            dMcal;                // zero point scatter (mags)
+  double           RA;                   // PSF RA coord (degrees)
+  double           DEC;                  // PSF DEC coord (degrees)
+  float            sky;                  // sky flux (cnts/sec)
+  float            dSky;                 // sky flux error (cnts/sec)
+  float            psfChisq;             // psf fit chisq
+  float            crNsigma;             // Nsigma deviations from PSF to CF
+  float            extNsigma;            // Nsigma deviations from PSF to EXT
+  float            fx;                   // psf fit major axis (pixels)
+  float            fy;                   // psf fit minor axis (pixels)
+  float            df;                   // ellipse angle (degrees)
+  float            psfQF;                // quality factor
+  float            psfQFperf;            // quality factor perfect
+  int              psfNdof;              // psf degrees of freedom
+  int              psfNpix;              // psf number of pixels
+  float            Mxx;                  // second moment X (pixels^2)
+  float            Mxy;                  // second moment Y (pixels^2)
+  float            Myy;                  // second moment XY (pixels^2)
+  float            Mr1;                  // first radial moment (pixels)
+  float            Mrh;                  // half radial moment (pixels^1/2)
+  float            kronFlux;             // kron flux (counts)
+  float            kronFluxErr;          // kron flux error (counts)
+  float            kronInner;            // kron flux 1<R<2.5 (counts)
+  float            kronOuter;            // kron flux 2.5<R<4 (counts)
+  int              D_Npos;               // diff param
+  float            D_Fratio;             // diff param
+  float            D_Nratio_bad;         // diff param
+  float            D_Nratio_mask;        // diff param
+  float            D_Nratio_all;         // diff param
+  float            D_Rp;                 // diff param
+  float            D_SNp;                // diff param
+  float            D_Rm;                 // diff param
+  float            D_SNm;                // diff param
+  int              flags;                // analysis flags
+  int              flags2;               // analysis flags (2)
+  short            nFrames;              // images overlapping peak
+  short            padding;              // padding for 8byte records
+} CMF_PS1_DV3;
+
+CMF_PS1_DV3 *gfits_table_get_CMF_PS1_DV3 (FTable *table, off_t *Ndata, char *swapped);
Index: trunk/Ohana/src/libdvo/include/dvo.h
===================================================================
--- trunk/Ohana/src/libdvo/include/dvo.h	(revision 35263)
+++ trunk/Ohana/src/libdvo/include/dvo.h	(revision 35416)
@@ -129,5 +129,5 @@
   ID_MEAS_BLEND_MEAS_X   = 0x00001000,  // detection is within radius of multiple objects across catalogs		     
   ID_MEAS_ARTIFACT       = 0x00002000,  // detection is thought to be non-astronomical				     
-  ID_MEAS_UNDEF_5        = 0x00004000,  // unused 
+  ID_MEAS_SYNTH_MAG      = 0x00004000,  // magnitude is synthetic
   ID_MEAS_PHOTOM_UBERCAL = 0x00008000,  // externally-supplied zero point from ubercal analysis
   ID_MEAS_STACK_PRIMARY  = 0x00010000,  // this stack measurement is in the primary skycell
@@ -288,4 +288,7 @@
 CMF_PS1_SV1 *gfits_table_get_CMF_PS1_SV1_Alt (FTable *ftable, off_t *Ndata, char *swapped);
 
+// another special case : does not match byte-boundaries
+# include "cmf-ps1-dv3.h"
+
 typedef struct {
   int Ncode;					  // number of photcodes
@@ -717,6 +720,8 @@
 
 void dvo_average_init (Average *average);
+void dvo_averageT_init (AverageTiny *average);
 void dvo_secfilt_init (SecFilt *secfilt);
 void dvo_measure_init (Measure *measure);
+void dvo_measureT_init (MeasureTiny *measure);
 
 # endif // DVO_H
Index: trunk/Ohana/src/libdvo/include/dvodb.h
===================================================================
--- trunk/Ohana/src/libdvo/include/dvodb.h	(revision 35263)
+++ trunk/Ohana/src/libdvo/include/dvodb.h	(revision 35416)
@@ -125,4 +125,6 @@
       MEAS_YFIX, 
       MEAS_POS_SYS_ERR, 
+      MEAS_XFIELD, 
+      MEAS_YFIELD, 
       MEAS_XMOSAIC, 
       MEAS_YMOSAIC, 
@@ -301,4 +303,5 @@
   double crval1;
   double crval2;
+  float theta;
   unsigned int imageID;
   unsigned int externID;
@@ -382,4 +385,5 @@
 ImageMetadata *MatchImageMetadataDVO (unsigned int imageID);
 Coords *MatchMosaicMetadata (unsigned int imageID);
+Coords *MatchFieldMetadata (unsigned int imageID);
 off_t match_image_by_ID (ImageMetadata *image, off_t Nimage, unsigned int ID);
 void sort_image_metadata (ImageMetadata *image, off_t Nimage);
Index: trunk/Ohana/src/libdvo/src/ImageMetadata.c
===================================================================
--- trunk/Ohana/src/libdvo/src/ImageMetadata.c	(revision 35263)
+++ trunk/Ohana/src/libdvo/src/ImageMetadata.c	(revision 35416)
@@ -63,4 +63,5 @@
   GET_COLUMN (crval1,   "CRVAL1",         double);
   GET_COLUMN (crval2,   "CRVAL2",         double);
+  GET_COLUMN (theta,    "THETA",          float);
   GET_COLUMN (Mcal,     "MCAL",           float);
   GET_COLUMN (secz,     "SECZ",           float);
@@ -75,4 +76,5 @@
     image[i].crval1   = crval1[i]  ;
     image[i].crval2   = crval2[i]  ;
+    image[i].theta    = theta[i]  ;
     image[i].Mcal     = Mcal[i]    ;
     image[i].secz     = secz[i]    ;
@@ -87,4 +89,5 @@
   free (crval1);
   free (crval2);
+  free (theta);
   free (Mcal);
   free (secz);
@@ -112,4 +115,6 @@
   FTable ftable;
 
+  BuildChipMatch (image, Nimage);
+
   gfits_init_header (&header);
   header.extend = TRUE;
@@ -124,4 +129,5 @@
   gfits_define_bintable_column (&theader, "D", "CRVAL1", "ra at center", "degrees", 1.0, 0.0);
   gfits_define_bintable_column (&theader, "D", "CRVAL2", "dec at center", "degrees", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E", "THETA", "camera rot angle", "degrees", 1.0, 0.0);
   gfits_define_bintable_column (&theader, "E", "MCAL", "zero point offset", "magnitudes", 1.0, 0.0);
   gfits_define_bintable_column (&theader, "E", "SECZ", "airmass", "none", 1.0, 0.0);
@@ -134,5 +140,5 @@
   unsigned int *imageID, *externID, *expname;
   double *crval1, *crval2;
-  float *Mcal, *Xcenter, *Ycenter, *secz;
+  float *Mcal, *Xcenter, *Ycenter, *secz, *theta;
 
   // create intermediate storage arrays
@@ -142,4 +148,5 @@
   ALLOCATE (crval1,   double,  	      Nimage);
   ALLOCATE (crval2,   double, 	      Nimage);
+  ALLOCATE (theta,    float, 	      Nimage);
   ALLOCATE (Mcal,     float, 	      Nimage);
   ALLOCATE (secz,     float, 	      Nimage);
@@ -149,8 +156,14 @@
   // assign the storage arrays
   for (i = 0; i < Nimage; i++) {
+    int Nmosaic = FindMosaicForImage (image, Nimage, i);
+    if (!Nmosaic) continue;
+    Nmosaic --;
     imageID[i]  = image[i].imageID;
     externID[i] = image[i].externID;
-    crval1[i]   = image[i].coords.crval1;
-    crval2[i]   = image[i].coords.crval2;
+    crval1[i]   = image[Nmosaic].coords.crval1;
+    crval2[i]   = image[Nmosaic].coords.crval2;
+
+    theta[i]    = DEG_RAD*atan2(image[Nmosaic].coords.pc1_2, image[Nmosaic].coords.pc1_1);
+
     Mcal[i]     = image[i].Mcal;
     secz[i]     = image[i].secz;
@@ -172,4 +185,5 @@
   gfits_set_bintable_column (&theader, &ftable, "CRVAL1",         crval1,  Nimage);
   gfits_set_bintable_column (&theader, &ftable, "CRVAL2",         crval2,  Nimage);
+  gfits_set_bintable_column (&theader, &ftable, "THETA",          theta,   Nimage);
   gfits_set_bintable_column (&theader, &ftable, "MCAL",           Mcal,    Nimage);
   gfits_set_bintable_column (&theader, &ftable, "SECZ",           secz,    Nimage);
@@ -182,4 +196,5 @@
   free (crval1);
   free (crval2);
+  free (theta);
   free (Mcal);
   free (secz);
Index: trunk/Ohana/src/libdvo/src/ImageMetadataSelection.c
===================================================================
--- trunk/Ohana/src/libdvo/src/ImageMetadataSelection.c	(revision 35263)
+++ trunk/Ohana/src/libdvo/src/ImageMetadataSelection.c	(revision 35416)
@@ -5,4 +5,5 @@
 static off_t Nimage = 0;
 static Coords mosaic;
+static Coords field;
 
 /* load images based on parameters and region, etc */
@@ -11,4 +12,12 @@
   image = NULL;
   
+  /* field defines a frame with 0,0 at the field center, and 1 arcsec / pixel */
+  field.crpix1 = field.crpix2 = 0.0;
+  field.cdelt1 = field.cdelt2 = 1.0 / 3600;
+  field.pc1_1  = field.pc2_2  = 1.0;
+  field.pc1_2  = field.pc2_1  = 0.0;
+  field.Npolyterms = 0;
+  strcpy (field.ctype, "RA---SIN");
+
   /* mosaic defines a frame with 0,0 at the mosaic center, and 1 arcsec / pixel */
   mosaic.crpix1 = mosaic.crpix2 = 0.0;
@@ -42,4 +51,20 @@
 }
 
+Coords *MatchFieldMetadata (unsigned int imageID) { 
+
+  int m;
+
+  m = match_image_by_ID (image, Nimage, imageID);
+  if (m == -1) return (NULL);
+
+  // if WRP, return the image, otherwise return NULL
+  // if (strcmp(&image[m].coords.ctype[4], "-WRP")) return NULL;
+  // return (&image[m].coords);
+
+  field.crval1 = image[m].crval1;
+  field.crval2 = image[m].crval2;
+  return (&field);
+}
+
 Coords *MatchMosaicMetadata (unsigned int imageID) { 
 
@@ -48,6 +73,17 @@
   m = match_image_by_ID (image, Nimage, imageID);
   if (m == -1) return (NULL);
+
+  // if WRP, return the image, otherwise return NULL
+  // if (strcmp(&image[m].coords.ctype[4], "-WRP")) return NULL;
+  // return (&image[m].coords);
+
   mosaic.crval1 = image[m].crval1;
   mosaic.crval2 = image[m].crval2;
+
+  mosaic.pc1_1 =  cos(RAD_DEG*image[m].theta);
+  mosaic.pc1_2 =  sin(RAD_DEG*image[m].theta);
+  mosaic.pc2_2 =  cos(RAD_DEG*image[m].theta);
+  mosaic.pc2_1 = -sin(RAD_DEG*image[m].theta);
+
   return (&mosaic);
 }
Index: trunk/Ohana/src/libdvo/src/ImageSelection.c
===================================================================
--- trunk/Ohana/src/libdvo/src/ImageSelection.c	(revision 35263)
+++ trunk/Ohana/src/libdvo/src/ImageSelection.c	(revision 35416)
@@ -93,8 +93,13 @@
   int m;
 
+  // mosaic.crval1 = 0;
+  // mosaic.crval2 = 0;
   m = match_image_subset (image, subset, Nsubset, time, source);
   if (m == -1) return (NULL);
-  mosaic.crval1 = image[m].coords.crval1;
-  mosaic.crval2 = image[m].coords.crval2;
-  return (&mosaic);
+  // mosaic = image[m].coords.crval1;
+  // mosaic = image[m].coords.crval2;
+
+  // if WRP, return the image, otherwise return NULL
+  if (strcmp(&image[m].coords.ctype[4], "-WRP")) return NULL;
+  return (&image[m].coords);
 }
Index: trunk/Ohana/src/libdvo/src/cmf-ps1-dv3.c
===================================================================
--- trunk/Ohana/src/libdvo/src/cmf-ps1-dv3.c	(revision 35416)
+++ trunk/Ohana/src/libdvo/src/cmf-ps1-dv3.c	(revision 35416)
@@ -0,0 +1,181 @@
+# include "dvo.h"
+
+/*** note : this file is derived from the autocode version, but is modified because
+     the forma does not match with structure byte boundaries ***/
+
+/* if we are not correctly including the ohana headers, this will fail */
+# ifndef BYTE_SWAP
+# ifndef NOT_BYTE_SWAP
+# error "neither BYTE_SWAP not NOT_BYTE_SWAP is set"
+# endif
+# endif
+
+# define FT_SIZE 224
+CMF_PS1_DV3 *gfits_table_get_CMF_PS1_DV3 (FTable *ftable, off_t *Ndata, char *swapped) {
+
+  off_t i, nitems;
+  unsigned char *byte, *inbyte, *otbyte, tmp;
+  CMF_PS1_DV3 *output;
+
+  /* provide initial values to avoid compiler warnings for non-BYTE_SWAP arch */
+  i = tmp = 0;
+  byte = NULL;
+
+  // this function is a special case : it must have Nx = FT_SIZE
+  if (ftable[0].header[0].Naxis[0] != FT_SIZE) { 
+    fprintf (stderr, "ERROR: wrong format for CMF_PS1_DV3: "OFF_T_FMT" vs %d\n",  ftable[0].header[0].Naxis[0], FT_SIZE);
+    return (NULL);
+  }
+
+  *Ndata = ftable[0].header[0].Naxis[1];
+  nitems = ftable[0].header[0].Naxis[1];
+
+  if ((swapped == NULL) || (*swapped == FALSE)) {
+
+    // the byte table below is generated by libautocode/def/cmf-ps1-dv3.d.
+    // the table dv3.d matches the input FITS table layout.  
+    // the byte order in that file follows the list below.
+# ifdef BYTE_SWAP
+      // we need to do the byte swap before applying the table scaling:
+      byte = (unsigned char *) ftable[0].buffer;
+      for (i = 0; i < nitems; i++, byte += FT_SIZE) {
+        /** BYTE SWAP **/
+        SWAP_WORD (0); // IPP_IDET
+        SWAP_WORD (4); // X_PSF
+        SWAP_WORD (8); // Y_PSF
+        SWAP_WORD (12); // X_PSF_SIG
+        SWAP_WORD (16); // Y_PSF_SIG
+        SWAP_WORD (20); // POSANGLE
+        SWAP_WORD (24); // PLTSCALE
+        SWAP_WORD (28); // PSF_INST_MAG
+        SWAP_WORD (32); // PSF_INST_MAG_SIG
+        SWAP_WORD (36); // PSF_INST_FLUX
+        SWAP_WORD (40); // PSF_INST_FLUX_SIG
+        SWAP_WORD (44); // AP_MAG
+        SWAP_WORD (48); // AP_MAG_RAW
+        SWAP_WORD (52); // AP_MAG_RADIUS
+        SWAP_WORD (56); // AP_FLUX
+        SWAP_WORD (60); // AP_FLUX_SIG
+        SWAP_WORD (64); // PEAK_FLUX_AS_MAG
+        SWAP_WORD (68); // CAL_PSF_MAG
+        SWAP_WORD (72); // CAL_PSF_MAG_SIG
+        SWAP_DBLE (76); // RA_PSF
+        SWAP_DBLE (84); // DEC_PSF
+        SWAP_WORD (92); // SKY
+        SWAP_WORD (96); // SKY_SIGMA
+        SWAP_WORD (100); // PSF_CHISQ
+        SWAP_WORD (104); // CR_NSIGMA
+        SWAP_WORD (108); // EXT_NSIGMA
+        SWAP_WORD (112); // PSF_MAJOR
+        SWAP_WORD (116); // PSF_MINOR
+        SWAP_WORD (120); // PSF_THETA
+        SWAP_WORD (124); // PSF_QF
+        SWAP_WORD (128); // PSF_QF_PERFECT
+        SWAP_WORD (132); // PSF_NDOF
+        SWAP_WORD (136); // PSF_NPIX
+        SWAP_WORD (140); // MOMENTS_XX
+        SWAP_WORD (144); // MOMENTS_XY
+        SWAP_WORD (148); // MOMENTS_YY
+        SWAP_WORD (152); // MOMENTS_R1
+        SWAP_WORD (156); // MOMENTS_RH
+        SWAP_WORD (160); // KRON_FLUX
+        SWAP_WORD (164); // KRON_FLUX_ERR
+        SWAP_WORD (168); // KRON_FLUX_INNER
+        SWAP_WORD (172); // KRON_FLUX_OUTER
+        SWAP_WORD (176); // DIFF_NPOS
+        SWAP_WORD (180); // DIFF_FRATIO
+        SWAP_WORD (184); // DIFF_NRATIO_BAD
+        SWAP_WORD (188); // DIFF_NRATIO_MASK
+        SWAP_WORD (192); // DIFF_NRATIO_ALL
+        SWAP_WORD (196); // DIFF_R_P
+        SWAP_WORD (200); // DIFF_SN_P
+        SWAP_WORD (204); // DIFF_R_M
+        SWAP_WORD (208); // DIFF_SN_M
+        SWAP_WORD (212); // FLAGS
+        SWAP_WORD (216); // FLAGS2
+        SWAP_BYTE (220); // N_FRAMES
+        SWAP_BYTE (222); // PADDING
+      }
+# endif  
+
+      gfits_table_scale_data (ftable);
+      if (swapped != NULL) *swapped = TRUE;
+  }
+
+  byte = (unsigned char *) ftable[0].buffer;
+
+  // allocate a new output data buffer
+  ALLOCATE (output, CMF_PS1_DV3, nitems);
+  inbyte = (unsigned char *) byte;
+  otbyte = (unsigned char *) output;
+
+  // the data in the input table does not line up with the output structure: copy carefully.
+  int ST_SIZE = sizeof(CMF_PS1_DV3);
+  for (i = 0; i < nitems; i++, inbyte += FT_SIZE, otbyte += ST_SIZE) {
+    memcpy (&otbyte[  0], &inbyte[  0],  76); // IPP_IDET to CAL_PSF_MAG_SIG
+    memcpy (&otbyte[ 80], &inbyte[ 76], 148); // RA_PSF to PADDING
+  }
+
+  free (ftable[0].buffer);
+  ftable[0].buffer = (char *) output;
+
+  return (output);
+} 
+
+// data organization (input vs output)
+//              FITS                       struct
+// WORD  0      IPP_IDET              0    IPP_IDET                   
+// WORD  4      X_PSF                 4    X_PSF                           
+// WORD  8      Y_PSF                 8    Y_PSF                           
+// WORD  12     X_PSF_SIG             12   X_PSF_SIG               
+// WORD  16     Y_PSF_SIG             16   Y_PSF_SIG               
+// WORD  20     POSANGLE              20   POSANGLE                
+// WORD  24     PLTSCALE              24   PLTSCALE                
+// WORD  28     PSF_INST_MAG          28   PSF_INST_MAG            
+// WORD  32     PSF_INST_MAG_SIG      32   PSF_INST_MAG_SIG        
+// WORD  36     PSF_INST_FLUX         36   PSF_INST_FLUX                   
+// WORD  40     PSF_INST_FLUX_SIG     40   PSF_INST_FLUX_SIG       
+// WORD  44     AP_MAG                44   AP_MAG                          
+// WORD  48     AP_MAG_RAW            48   AP_MAG_RAW              
+// WORD  52     AP_MAG_RADIUS         52   AP_MAG_RADIUS                   
+// WORD  56     AP_FLUX               56   AP_FLUX                         
+// WORD  60     AP_FLUX_SIG           60   AP_FLUX_SIG             
+// WORD  64     PEAK_FLUX_AS_MAG      64   PEAK_FLUX_AS_MAG        
+// WORD  68     CAL_PSF_MAG           68   CAL_PSF_MAG             
+// WORD  72     CAL_PSF_MAG_SIG       72   CAL_PSF_MAG_SIG                 
+// DBLE  76     RA_PSF                80   RA_PSF                          
+// DBLE  84     DEC_PSF               88   DEC_PSF                         
+// WORD  92     SKY                   96   SKY                     
+// WORD  96     SKY_SIGMA             100  SKY_SIGMA               
+// WORD  100    PSF_CHISQ             104  PSF_CHISQ               
+// WORD  104    CR_NSIGMA             108  CR_NSIGMA               
+// WORD  108    EXT_NSIGMA            112  EXT_NSIGMA              
+// WORD  112    PSF_MAJOR             116  PSF_MAJOR               
+// WORD  116    PSF_MINOR             120  PSF_MINOR               
+// WORD  120    PSF_THETA             124  PSF_THETA               
+// WORD  124    PSF_QF                128  PSF_QF                          
+// WORD  128    PSF_QF_PERFECT        132  PSF_QF_PERFECT                  
+// WORD  132    PSF_NDOF              136  PSF_NDOF                
+// WORD  136    PSF_NPIX              140  PSF_NPIX                
+// WORD  140    MOMENTS_XX            144  MOMENTS_XX              
+// WORD  144    MOMENTS_XY            148  MOMENTS_XY              
+// WORD  148    MOMENTS_YY            152  MOMENTS_YY              
+// WORD  152    MOMENTS_R1            156  MOMENTS_R1              
+// WORD  156    MOMENTS_RH            160  MOMENTS_RH              
+// WORD  160    KRON_FLUX             164  KRON_FLUX               
+// WORD  164    KRON_FLUX_ERR         168  KRON_FLUX_ERR                   
+// WORD  168    KRON_FLUX_INNER       172  KRON_FLUX_INNER                 
+// WORD  172    KRON_FLUX_OUTER       176  KRON_FLUX_OUTER                 
+// WORD  176    DIFF_NPOS             180  DIFF_NPOS               
+// WORD  180    DIFF_FRATIO           184  DIFF_FRATIO             
+// WORD  184    DIFF_NRATIO_BAD       188  DIFF_NRATIO_BAD                 
+// WORD  188    DIFF_NRATIO_MASK      192  DIFF_NRATIO_MASK        
+// WORD  192    DIFF_NRATIO_ALL       196  DIFF_NRATIO_ALL                 
+// WORD  196    DIFF_R_P              200  DIFF_R_P                
+// WORD  200    DIFF_SN_P             204  DIFF_SN_P               
+// WORD  204    DIFF_R_M              208  DIFF_R_M                
+// WORD  208    DIFF_SN_M             212  DIFF_SN_M               
+// WORD  212    FLAGS                 216  FLAGS                           
+// WORD  216    FLAGS2                220  FLAGS2                          
+// BYTE  220    N_FRAMES              224  N_FRAMES                
+// BYTE  222    PADDING               226  PADDING                         
Index: trunk/Ohana/src/libdvo/src/dbExtractAverages.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dbExtractAverages.c	(revision 35263)
+++ trunk/Ohana/src/libdvo/src/dbExtractAverages.c	(revision 35416)
@@ -141,4 +141,8 @@
       value.Flt = average[0].ChiSqPar;
       break;
+
+    // XXX case AVE_PM_GROUPS:
+    // XXX   value.Int = GetProperMotionGroups (average, measure);
+    // XXX   break;
 
     case AVE_TMEAN:
@@ -278,2 +282,11 @@
 }  
 
+// XXX int GetProperMotionGroups (Average *average, Measure *measure) {
+// XXX   // need the times, excluding ignored detections
+// XXX   // sort the images
+// XXX   for (i = 0; i < Ntimes - 1; i++)  {
+// XXX     if (time[i+1] - time[i] < TRANGE) Ngroup ++;
+// XXX   }
+// XXX   return Ngroup;
+// XXX }
+// XXX 
Index: trunk/Ohana/src/libdvo/src/dbExtractMeasures.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dbExtractMeasures.c	(revision 35263)
+++ trunk/Ohana/src/libdvo/src/dbExtractMeasures.c	(revision 35416)
@@ -16,4 +16,8 @@
 static int REMOTE_CLIENT = FALSE;
 
+// the following values are calculated together in a single function, eg.,
+// ApplyTransform() returning Glon & Glat.  for a single measurement, we want to do this
+// calculation once and save both values in case both are requested (usually both are if
+// either is)
 static int haveGalacticAve = FALSE;
 static double GLON_AVE = 0.0;
@@ -31,4 +35,12 @@
 static double ELON_MEAS = 0.0;
 static double ELAT_MEAS = 0.0;
+
+static int haveMosaicMeas = FALSE;
+static double XMOS_MEAS = 0.0;
+static double YMOS_MEAS = 0.0;
+
+static int haveFieldMeas = FALSE;
+static double XFIELD_MEAS = 0.0;
+static double YFIELD_MEAS = 0.0;
 
 int dbExtractMeasuresInit (int isRemoteClient) {
@@ -66,4 +78,5 @@
 
 int dbExtractMeasuresInitMeas () {
+  haveMosaicMeas   = FALSE;
   haveGalacticMeas = FALSE;
   haveEclipticMeas = FALSE;
@@ -76,7 +89,8 @@
   int Nsec;
   dbValue value;
-  double ra, dec, x, y, dT;
-
-  Coords *mosaic;
+  double dT;
+
+  Coords *mosaic, *fieldc;
+
   PhotCode *equiv;
 
@@ -85,13 +99,58 @@
 
   switch (field->ID) {
-    case MEAS_MAG: /* magnitudes are already determined above */
-      equiv = GetPhotcodeEquivbyCode (measure[0].photcode);
-
-      // we return the magnitude for this measure if:
-      if (field->photcode->type == PHOT_MAG) goto valid_photcode;
+    case MEAS_MAG: { /* magnitudes are already determined above */
+      PhotCode *myEquiv = GetPhotcodeEquivbyCode (measure[0].photcode);
+
+      // if we request mag:ave, use equiv for photcode
+      if  (field->photcode->type == PHOT_MAG) {
+	equiv = myEquiv;
+	goto valid_photcode;
+      }
+
+      // if we ask for 2MASS_K, etc (REF values), return NAN unless measure->code matches
       if ((field->photcode->type == PHOT_REF) && (measure[0].photcode == field->photcode->code)) goto valid_photcode;
+
+      // if we ask for GPC1.g.XY03:rel, etc (DEP values), return NAN unless measure->code matches
       if ((field->photcode->type == PHOT_DEP) && (measure[0].photcode == field->photcode->code)) goto valid_photcode;
 
-      if ((equiv != NULL) && (field->photcode->type == PHOT_SEC) && (equiv[0].code == field->photcode->code)) goto valid_photcode;
+      // if we ask for g:ave, or other SEC-level values, return the corresponding field 
+      if (field->photcode->type == PHOT_SEC) {
+	switch (field->magMode) {
+	  // measure-like : return non-NAN if measure.equiv.photcode matches field.photcode
+	  case MAG_INST:
+	  case MAG_CAT:
+	  case MAG_SYS:
+	  case MAG_REL:
+	  case MAG_CAL:
+	  case MAG_APER:
+	  case MAG_APER_INST:
+	  case MAG_KRON:
+	  case MAG_KRON_INST:
+	  case MAG_KRON_ERR:
+	  case MAG_ERR:
+	  case MAG_PHOT_FLAGS:
+	    equiv = myEquiv;
+	    if (equiv && (equiv->code == field->photcode->code)) goto valid_photcode;
+	    break;
+
+	    // mean-like : return value for the given photcode
+	  case MAG_AVE:
+	  case MAG_REF:
+	  case MAG_CHISQ:
+	  case MAG_AVE_ERR:
+	  case MAG_NCODE:
+	  case MAG_NPHOT:
+	  case MAG_FLUX_PSF:
+	  case MAG_FLUX_PSF_ERR:
+	  case MAG_FLUX_KRON:
+	  case MAG_FLUX_KRON_ERR:
+	    equiv = field->photcode;
+	    goto valid_photcode;
+	    break;
+	  default:
+	    fprintf (stderr, "error");
+	    return value;
+	}
+      }
       break;
 
@@ -182,4 +241,5 @@
       }
       break;
+    }
     case MEAS_RA: /* OK */
       value.Flt = average[0].R - measure[0].dR / 3600.0;
@@ -465,19 +525,69 @@
       value.Flt = FromShortPixels(measure[0].dRsys);
       break;
-    case MEAS_XMOSAIC: /* OK */
-      ra  = average[0].R - measure[0].dR / 3600.0;
-      dec = average[0].D - measure[0].dD / 3600.0;
-      mosaic = MatchMosaicMetadata (measure[0].imageID);
-      if (mosaic == NULL) break;
-      RD_to_XY (&x, &y, ra, dec, mosaic);
-      value.Flt = x;
+
+    case MEAS_XFIELD: /* offset relative to exposure center in ra,dec space */
+      if (!haveFieldMeas) {
+	if (REMOTE_CLIENT) {
+	  fieldc = MatchFieldMetadata (measure[0].imageID);
+	} else {
+	  fprintf (stderr, "non-parallel Xmos broken\n");
+	  abort();
+	  // fieldc = MatchField (measure[0].t, measure[0].photcode);
+	}
+	if (fieldc == NULL) break;
+	double Rm = average[0].R - measure[0].dR / 3600.0;
+	double Dm = average[0].D - measure[0].dD / 3600.0;
+	RD_to_XY (&XFIELD_MEAS, &YFIELD_MEAS, Rm, Dm, fieldc);
+      }
+      value.Flt = XFIELD_MEAS;
+      break;
+    case MEAS_YFIELD: /* OK */
+      if (!haveFieldMeas) {
+	if (REMOTE_CLIENT) {
+	  fieldc = MatchFieldMetadata (measure[0].imageID);
+	} else {
+	  fprintf (stderr, "non-parallel Xmos broken\n");
+	  abort();
+	  // fieldc = MatchField (measure[0].t, measure[0].photcode);
+	}
+	if (fieldc == NULL) break;
+	double Rm = average[0].R - measure[0].dR / 3600.0;
+	double Dm = average[0].D - measure[0].dD / 3600.0;
+	RD_to_XY (&XFIELD_MEAS, &YFIELD_MEAS, Rm, Dm, fieldc);
+      }
+      value.Flt = YFIELD_MEAS;
+      break;
+
+    case MEAS_XMOSAIC: /* offset relative to exposure center in camera coords */
+      if (!haveMosaicMeas) {
+	if (REMOTE_CLIENT) {
+	  mosaic = MatchMosaicMetadata (measure[0].imageID);
+	} else {
+	  fprintf (stderr, "non-parallel Xmos broken\n");
+	  abort();
+	  mosaic = MatchMosaic (measure[0].t, measure[0].photcode);
+	}
+	if (mosaic == NULL) break;
+	double Rm = average[0].R - measure[0].dR / 3600.0;
+	double Dm = average[0].D - measure[0].dD / 3600.0;
+	RD_to_XY (&XMOS_MEAS, &YMOS_MEAS, Rm, Dm, mosaic);
+      }
+      value.Flt = XMOS_MEAS;
       break;
     case MEAS_YMOSAIC: /* OK */
-      ra  = average[0].R - measure[0].dR / 3600.0;
-      dec = average[0].D - measure[0].dD / 3600.0;
-      mosaic = MatchMosaic (measure[0].t, measure[0].photcode);
-      if (mosaic == NULL) break;
-      RD_to_XY (&x, &y, ra, dec, mosaic);
-      value.Flt = y;
+      if (!haveMosaicMeas) {
+	if (REMOTE_CLIENT) {
+	  mosaic = MatchMosaicMetadata (measure[0].imageID);
+	} else {
+	  fprintf (stderr, "non-parallel Xmos broken\n");
+	  abort();
+	  mosaic = MatchMosaic (measure[0].t, measure[0].photcode);
+	}
+	if (mosaic == NULL) break;
+	double Rm = average[0].R - measure[0].dR / 3600.0;
+	double Dm = average[0].D - measure[0].dD / 3600.0;
+	RD_to_XY (&XMOS_MEAS, &YMOS_MEAS, Rm, Dm, mosaic);
+      }
+      value.Flt = YMOS_MEAS;
       break;
 
Index: trunk/Ohana/src/libdvo/src/dbFields.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dbFields.c	(revision 35263)
+++ trunk/Ohana/src/libdvo/src/dbFields.c	(revision 35416)
@@ -87,4 +87,9 @@
     strcpy (code[0].name, "MAG");
     code[0].type = PHOT_MAG;
+    // the field call 'mag' is only valid for mextract
+    // it should default to REL, but other types should default to AVE
+    if (useDefault) {
+      *mode = MAG_REL;
+    }
     free (tmpstring);
     return (code);
@@ -220,4 +225,6 @@
   if (!strcasecmp (fieldName, "YFIX"))       	 ESCAPE (MEAS_YFIX,           MAG_NONE, OPIHI_FLT);
   if (!strcasecmp (fieldName, "POS_SYS_ERR"))    ESCAPE (MEAS_POS_SYS_ERR,    MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "XFIELD"))    	 ESCAPE (MEAS_XFIELD,         MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "YFIELD"))    	 ESCAPE (MEAS_YFIELD,         MAG_NONE, OPIHI_FLT);
   if (!strcasecmp (fieldName, "XMOSAIC"))    	 ESCAPE (MEAS_XMOSAIC,        MAG_NONE, OPIHI_FLT);
   if (!strcasecmp (fieldName, "YMOSAIC"))    	 ESCAPE (MEAS_YMOSAIC,        MAG_NONE, OPIHI_FLT);
@@ -254,5 +261,5 @@
 
   // check for code:mode in photcode name 
-  code = ParsePhotcodeField (fieldName, &mode, MAG_REL);
+  code = ParsePhotcodeField (fieldName, &mode, MAG_AVE);
   if (code == NULL) {
     gprint (GP_ERR, "unknown field '%s' for measurement table in DVO database\n", fieldName);
Index: trunk/Ohana/src/libdvo/src/dvo_catalog.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dvo_catalog.c	(revision 35263)
+++ trunk/Ohana/src/libdvo/src/dvo_catalog.c	(revision 35416)
@@ -112,4 +112,14 @@
 
 // init all data, or just catalog data
+void dvo_averageT_init (AverageTiny *average) {
+  average->R         	   = 0;
+  average->D         	   = 0;
+  average->flags           = 0;
+  average->Nmeasure        = 0;
+  average->measureOffset   = -1;
+  average->catID     	   = 0;
+}
+
+// init all data, or just catalog data
 void dvo_secfilt_init (SecFilt *secfilt) {
   secfilt->M           = NAN;
@@ -142,5 +152,4 @@
  measure->dR        = NAN;
  measure->dD        = NAN;
- measure->M         = NAN;
  measure->Mcal      = NAN;
  measure->Map       = NAN;
@@ -203,4 +212,34 @@
  measure->dbFlags   = 0;
  measure->photFlags = 0;
+}
+
+void dvo_measureT_init (MeasureTiny *measure) {
+ measure->dR        = NAN;
+ measure->dD        = NAN;
+ measure->M         = NAN;
+ measure->Mcal      = NAN;
+ measure->dM        = NAN;
+
+ measure->airmass   = NAN;
+ measure->Xccd      = NAN;
+ measure->Yccd      = NAN;
+ measure->Xfix      = NAN;
+ measure->Yfix      = NAN;
+
+ measure->t         = 0;
+ measure->dt        = NAN;
+ measure->averef    = 0;
+
+ measure->imageID   = 0;
+
+ measure->dbFlags   = 0;
+ measure->photFlags = 0;
+ measure->photcode  = 0;
+
+ measure->catID     = 0;
+
+ measure->dXccd     = 0;
+ measure->dYccd     = 0;
+ measure->dRsys     = 0;
 }
 
