Index: /branches/eam_branches/ipp-20130307/Ohana/src/libdvo/include/dvodb.h
===================================================================
--- /branches/eam_branches/ipp-20130307/Ohana/src/libdvo/include/dvodb.h	(revision 35341)
+++ /branches/eam_branches/ipp-20130307/Ohana/src/libdvo/include/dvodb.h	(revision 35342)
@@ -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: /branches/eam_branches/ipp-20130307/Ohana/src/libdvo/src/ImageMetadata.c
===================================================================
--- /branches/eam_branches/ipp-20130307/Ohana/src/libdvo/src/ImageMetadata.c	(revision 35341)
+++ /branches/eam_branches/ipp-20130307/Ohana/src/libdvo/src/ImageMetadata.c	(revision 35342)
@@ -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: /branches/eam_branches/ipp-20130307/Ohana/src/libdvo/src/ImageMetadataSelection.c
===================================================================
--- /branches/eam_branches/ipp-20130307/Ohana/src/libdvo/src/ImageMetadataSelection.c	(revision 35341)
+++ /branches/eam_branches/ipp-20130307/Ohana/src/libdvo/src/ImageMetadataSelection.c	(revision 35342)
@@ -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: /branches/eam_branches/ipp-20130307/Ohana/src/libdvo/src/ImageSelection.c
===================================================================
--- /branches/eam_branches/ipp-20130307/Ohana/src/libdvo/src/ImageSelection.c	(revision 35341)
+++ /branches/eam_branches/ipp-20130307/Ohana/src/libdvo/src/ImageSelection.c	(revision 35342)
@@ -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: /branches/eam_branches/ipp-20130307/Ohana/src/libdvo/src/dbExtractMeasures.c
===================================================================
--- /branches/eam_branches/ipp-20130307/Ohana/src/libdvo/src/dbExtractMeasures.c	(revision 35341)
+++ /branches/eam_branches/ipp-20130307/Ohana/src/libdvo/src/dbExtractMeasures.c	(revision 35342)
@@ -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,7 @@
   int Nsec;
   dbValue value;
-  double ra, dec, x, y, dT;
-
-  Coords *mosaic;
+  double dT;
+
+  Coords *mosaic, *fieldc;
   PhotCode *equiv;
 
@@ -465,27 +478,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;
-      if (REMOTE_CLIENT) {
-	mosaic = MatchMosaicMetadata (measure[0].imageID);
-      } else {
-	mosaic = MatchMosaic (measure[0].t, measure[0].photcode);
-      }
-      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;
-      if (REMOTE_CLIENT) {
-	mosaic = MatchMosaicMetadata (measure[0].imageID);
-      } else {
-	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: /branches/eam_branches/ipp-20130307/Ohana/src/libdvo/src/dbFields.c
===================================================================
--- /branches/eam_branches/ipp-20130307/Ohana/src/libdvo/src/dbFields.c	(revision 35341)
+++ /branches/eam_branches/ipp-20130307/Ohana/src/libdvo/src/dbFields.c	(revision 35342)
@@ -220,4 +220,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);
Index: /branches/eam_branches/ipp-20130307/Ohana/src/opihi/dvo/dvo_host_utils.c
===================================================================
--- /branches/eam_branches/ipp-20130307/Ohana/src/opihi/dvo/dvo_host_utils.c	(revision 35341)
+++ /branches/eam_branches/ipp-20130307/Ohana/src/opihi/dvo/dvo_host_utils.c	(revision 35342)
@@ -199,4 +199,5 @@
 
     if (table->hosts[i].status) continue; 
+    if (!table->hosts[i].pid) continue;
 
     if (ReadVectors) {
Index: /branches/eam_branches/ipp-20130307/Ohana/src/opihi/dvo/mextract.c
===================================================================
--- /branches/eam_branches/ipp-20130307/Ohana/src/opihi/dvo/mextract.c	(revision 35341)
+++ /branches/eam_branches/ipp-20130307/Ohana/src/opihi/dvo/mextract.c	(revision 35342)
@@ -16,5 +16,5 @@
     if (field->ID == MEAS_CENTER_OFFSET)  return TRUE; // 0.5*NX, 0.5*NY
     if (field->ID == MEAS_EXPNAME_AS_INT) return TRUE; // expname (or as int)
-    if (field->ID == MEAS_AIRMASS)        return TRUE; // airmass
+    if (field->ID == MEAS_MEAN_AIRMASS)   return TRUE; // airmass
     return FALSE;
 }
Index: /branches/eam_branches/ipp-20130307/Ohana/src/opihi/dvo/photometry.c
===================================================================
--- /branches/eam_branches/ipp-20130307/Ohana/src/opihi/dvo/photometry.c	(revision 35341)
+++ /branches/eam_branches/ipp-20130307/Ohana/src/opihi/dvo/photometry.c	(revision 35342)
@@ -1127,5 +1127,5 @@
   double value;
   Image *image;
-  Coords *mosaic;
+  // Coords *mosaic;
 
   value = 0;
@@ -1193,8 +1193,9 @@
 # endif
       break;
+# if 0
     case MEAS_XMOSAIC: /* 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);
+      mosaic = MatchMosaic (measure[0].t, measure[0].photcode); // XXX not used anymore
       if (mosaic == NULL) break;
       RD_to_XY (&x, &y, ra, dec, mosaic);
@@ -1204,9 +1205,10 @@
       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);
+      mosaic = MatchMosaic (measure[0].t, measure[0].photcode); // XXX not used anymore
       if (mosaic == NULL) break;
       RD_to_XY (&x, &y, ra, dec, mosaic);
       value = y;
       break;
+# endif
   }
   return (value);
