Index: trunk/Ohana/src/opihi/dvo/mextract.c
===================================================================
--- trunk/Ohana/src/opihi/dvo/mextract.c	(revision 34749)
+++ trunk/Ohana/src/opihi/dvo/mextract.c	(revision 35263)
@@ -1,3 +1,22 @@
 # include "dvoshell.h"
+
+int field_needs_images (dbField *field) {
+  // the image subset table requires imageID for all fields
+
+    if (!MEASURE_HAS_XCCD) {
+      // I'm keeping this code because it gives a way of handling dvo dbs that don't have
+      // measure.xccd if we need it
+      if (field->ID == MEAS_XCCD) return TRUE; // full astrometry per chip (120 bytes!)
+      if (field->ID == MEAS_YCCD) return TRUE; // full astrometry per chip (120 bytes!)
+    }
+    if (field->ID == MEAS_XMOSAIC) 	  return TRUE; // crval1,2 only
+    if (field->ID == MEAS_YMOSAIC) 	  return TRUE; // crval1,2 only
+    if (field->ID == MEAS_EXTERN_ID)      return TRUE; // externID
+    if (field->ID == MEAS_FLAT)           return TRUE; // Mcal
+    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
+    return FALSE;
+}
 
 int mextract (int argc, char **argv) {
@@ -5,5 +24,5 @@
   off_t i, j, k, m; // used for counter averages and measures
   int n, N, Npts, NPTS, last, next, state, Nfields, Nreturn, Ncstack, Nstack;
-  int Nsecfilt, VERBOSE, loadImages, mosaicMode;
+  int Nsecfilt, VERBOSE, loadImages;
   char **cstack, name[1024];
   dbValue *values;
@@ -33,4 +52,11 @@
     remove_argument (N, &argc, argv);
     VERBOSE = TRUE;
+  }
+
+  char *imageMetadataFile = FALSE;
+  if ((N = get_argument (argc, argv, "-image-metadata"))) {
+    remove_argument (N, &argc, argv);
+    imageMetadataFile = strcreate (argv[N]);
+    remove_argument (N, &argc, argv);
   }
 
@@ -66,5 +92,6 @@
 
   // init locally static variables (time refs)
-  dbExtractMeasuresInit();
+  // HOST_ID tells library if operation is on remote client or not
+  dbExtractMeasuresInit(HOST_ID);
 
   // command-line is of the form: mextract field,field, field [where (field op value)...]
@@ -106,7 +133,43 @@
   if ((skylist = SelectRegions (selection)) == NULL) goto escape;
 
+  // load image data if needed (for fields listed below)
+  loadImages = FALSE;
+  for (i = 0; !loadImages && (i < Nfields); i++) {
+    loadImages = field_needs_images (&fields[i]);
+  }
+    
   // this does all the work of re-packaging the command, calling it on the remote machines, then loading in the results
   if (PARALLEL && !HOST_ID) {
-    int status = HostTableParallelOps (argc, argv, RESULT_FILE, TRUE, 0, VERBOSE);
+
+    // Image Metadata for remote queries:
+    // 1) figure out if we need any image metadata
+    // 2) load the images and generate a subset table with just the fields of interest
+    // 3) add the input subset filename to the dvo_client command
+
+    // allocate the temp array and copy all but (RA) (DEC)
+    int targc = 0;
+    char **targv = NULL;
+    ALLOCATE (targv, char *, argc);
+    for (i = 0; i < argc; i++) {
+      targv[targc] = strcreate (argv[i]);
+      targc ++;
+    }
+
+    if (loadImages) {
+      Image *image;
+      off_t Nimage;
+      if ((image = LoadImagesDVO (&Nimage)) == NULL) goto escape;
+
+      char *filename = abspath("image.metadata.fits", DVO_MAX_PATH);
+      ImageMetadataSave (filename, image, Nimage);
+
+      REALLOCATE (targv, char *, targc + 2);
+      targv[targc+0] = strcreate ("-image-metadata");
+      targv[targc+1] = strcreate (filename);
+      targc += 2;
+    }
+
+    // call the remote client
+    int status = HostTableParallelOps (targc, targv, RESULT_FILE, TRUE, 0, VERBOSE);
 
     dbFreeFields (fields, Nfields);
@@ -116,24 +179,20 @@
     dvo_catalog_free (&catalog);
 
+    // free up targv
+    for (i = 0; i < targc; i++) {
+      free (targv[i]);
+    }
+    free (targv);
+
     return status;
   }
 
-  // load image data if needed (for fields listed below)
-  loadImages = FALSE;
-  mosaicMode = FALSE;
-  for (i = 0; !loadImages && (i < Nfields); i++) {
-    if (!MEASURE_HAS_XCCD) {
-      // I'm keeping this code because it gives a way of handling dvo dbs that don't have
-      // measure.xccd if we need it
-      if (fields[i].ID == MEAS_XCCD) loadImages = TRUE;
-      if (fields[i].ID == MEAS_YCCD) loadImages = TRUE;
-    }
-    if (fields[i].ID == MEAS_XMOSAIC) 	    loadImages = mosaicMode = TRUE;
-    if (fields[i].ID == MEAS_YMOSAIC) 	    loadImages = mosaicMode = TRUE;
-    if (fields[i].ID == MEAS_EXTERN_ID)     loadImages = mosaicMode = TRUE;
-    if (fields[i].ID == MEAS_FLAT)          loadImages = mosaicMode = TRUE;
-    if (fields[i].ID == MEAS_CENTER_OFFSET) loadImages = mosaicMode = TRUE;
-  }
-  if (loadImages && !SetImageSelection (mosaicMode, selection)) goto escape;
+  if (loadImages) {
+    if (HOST_ID) {
+      if (!SetImageMetadataSelection (imageMetadataFile)) goto escape;
+    } else {
+      if (!SetImageSelection (TRUE, selection)) goto escape;
+    }
+  }
 
   /* create storage vector */
@@ -251,4 +310,5 @@
   free (stack);
   FreeImageSelection ();
+  FreeImageMetadataSelection ();
   SkyListFree (skylist);
   FreeSkyRegionSelection (selection);
@@ -264,4 +324,5 @@
   free (stack);
   FreeImageSelection ();
+  FreeImageMetadataSelection ();
   SkyListFree (skylist);
   FreeSkyRegionSelection (selection);
