Index: /branches/eam_branch_20081124/Ohana/src/opihi/dvo/dbExtractImages.c
===================================================================
--- /branches/eam_branch_20081124/Ohana/src/opihi/dvo/dbExtractImages.c	(revision 20861)
+++ /branches/eam_branch_20081124/Ohana/src/opihi/dvo/dbExtractImages.c	(revision 20861)
@@ -0,0 +1,209 @@
+# include "dvoshell.h"
+
+static CoordTransform *celestial_to_galactic = NULL;
+static CoordTransform *celestial_to_ecliptic = NULL;
+
+static int haveGalactic = FALSE;
+static double GLON = 0.0;
+static double GLAT = 0.0;
+
+static int haveEcliptic = FALSE;
+static double ELON = 0.0;
+static double ELAT = 0.0;
+
+// define a locally-static transform
+int dbExtractImagesInitTransform (CoordTransformSystem target) {
+
+  // galactic transform is kept forever
+  if (target == COORD_GALACTIC) {
+    if (celestial_to_galactic != NULL) return (TRUE);
+    celestial_to_galactic = InitTransform (COORD_CELESTIAL, target);
+    return (TRUE);
+  }
+
+  // ecliptic transform must be updated (is weakly time-dependent)
+  if (target == COORD_ECLIPTIC) {
+    if (celestial_to_ecliptic != NULL) {
+      free (celestial_to_ecliptic);
+    }
+    celestial_to_ecliptic = InitTransform (COORD_CELESTIAL, target);
+    return (TRUE);
+  }
+  return (FALSE);
+}
+
+int dbExtractImagesInit () {
+  haveGalactic = FALSE;
+  haveEcliptic = FALSE;
+  return (TRUE);
+}
+
+/* return image.field based on the selection */
+dbValue dbExtractImages (Image *image, dbField *field) {
+
+  int i, Nsec;
+  dbValue value;
+
+  value.Flt = NAN;
+  value.Int =   0;
+
+  /* assign vector values */
+  switch (field->ID) {
+    case IMAGE_RA:
+      XXX : need a better implementation of this...
+	if (!FindMosaicForImage (image, Nimage, j)) continue;
+      x = 0.5*image[0].NX;
+      y = 0.5*image[0].NY;
+      XY_to_RD (&ra, &dec, x, y, &image[0].coords);
+      value.Flt = ra;
+      break;
+    case IMAGE_DEC:
+      if (!FindMosaicForImage (image, Nimage, j)) continue;
+      x = 0.5*image[0].NX;
+      y = 0.5*image[0].NY;
+      XY_to_RD (&ra, &dec, x, y, &image[0].coords);
+      value.Flt = dec;
+      break;
+    case IMAGE_GLON:
+      if (!haveGalactic) {
+	ApplyTransform (&GLON, &GLAT, RAo, DECo, celestial_to_galactic);
+	haveGalactic = TRUE;
+      }
+      value.Flt = GLON;
+      break;
+    case IMAGE_GLAT:
+      if (!haveGalactic) {
+	ApplyTransform (&GLON, &GLAT, RAo, DECo, celestial_to_galactic);
+	haveGalactic = TRUE;
+      }
+      value.Flt = GLAT;
+      break;
+    case IMAGE_ELON:
+      if (!haveEcliptic) {
+	ApplyTransform (&ELON, &ELAT, RAo, DECo, celestial_to_ecliptic);
+	haveEcliptic = TRUE;
+      }
+      value.Flt = ELON;
+      break;
+    case IMAGE_ELAT:
+      if (!haveEcliptic) {
+	ApplyTransform (&ELON, &ELAT, RAo, DECo, celestial_to_ecliptic);
+	haveEcliptic = TRUE;
+      }
+      value.Flt = ELAT;
+      break;
+    case IMAGE_Xm:
+      value.Flt = pow(10.0, 0.01*image[0].Xm);
+      break;
+    case IMAGE_AIRMASS:
+      value.Flt = image[0].secz;
+      break;
+    case IMAGE_MCAL:
+      value.Flt = image[0].Mcal;
+      break;
+    case IMAGE_dMCAL:
+      value.Flt = image[0].dMcal;
+      break;
+    case IMAGE_PHOTCODE:
+      value.Flt = image[0].photcode;
+      break;
+    case IMAGE_TIME:
+      t = image[0].tzero + 0.5*image[0].NY * image[0].trate / 10000;
+      value.Flt = TimeValue (t, TimeReference, TimeFormat);
+      break;
+    case IMAGE_FWHM:
+      value.Flt = image[0].fwhm_x / 25.0;
+      break;
+    case IMAGE_EXPTIME:
+      value.Flt = image[0].exptime;
+      break;
+    case IMAGE_NSTAR:
+      value.Flt = image[0].nstar;
+      break;
+    case IMAGE_NCAL:
+      value.Flt = image[0].Mxxxx;
+      break;
+    case IMAGE_SKY:
+      value.Flt = image[0].Myyyy + 0x8000;
+      break;
+    case IMAGE_FLAG:
+      value.Flt = image[0].code;
+      break;
+    case IMAGE_NX_PIX:
+      value.Flt = image[0].NX;
+      break;
+    case IMAGE_NY_PIX:
+      value.Flt = image[0].NY;
+      break;
+    case IMAGE_IMAGE_ID:
+      value.Flt = image[0].imageID;
+      break;
+    case IMAGE_THETA: {
+      double theta1, theta2, s1, s2;
+      s1 = SIGN(image[0].coords.pc1_1);
+      s2 = SIGN(image[0].coords.pc2_2);
+      theta1 = DEG_RAD*atan2 (+s1*image[0].coords.pc1_2, s1*image[0].coords.pc1_1);
+      theta2 = DEG_RAD*atan2 (-s2*image[0].coords.pc2_1, s2*image[0].coords.pc2_2);
+      value.Flt = 0.5*(theta1+theta2);
+      break; }
+    case IMAGE_SKEW: {
+      double theta1, theta2, s1, s2;
+      s1 = SIGN(image[0].coords.pc1_1);
+      s2 = SIGN(image[0].coords.pc2_2);
+      theta1 = DEG_RAD*atan2 (+s1*image[0].coords.pc1_2, s1*image[0].coords.pc1_1);
+      theta2 = DEG_RAD*atan2 (-s2*image[0].coords.pc2_1, s2*image[0].coords.pc2_2);
+      value.Flt = (theta1-theta2);
+      break; }
+    case IMAGE_SCALE: {
+      double scale1, scale2;
+      scale1 = fabs(image[0].coords.cdelt1);
+      scale2 = fabs(image[0].coords.cdelt2);
+      value.Flt = 0.5*(scale1+scale2);
+      break; }
+    case IMAGE_DSCALE: {
+      double scale1, scale2;
+      scale1 = fabs(image[0].coords.cdelt1);
+      scale2 = fabs(image[0].coords.cdelt2);
+      value.Flt = (scale1-scale2);
+      break; }
+
+      // reference pixel extractions
+    case IMAGE_X_LL_CHIP:
+    case IMAGE_Y_LL_CHIP:
+    case IMAGE_Y_LR_CHIP:
+    case IMAGE_X_UL_CHIP:
+      value.Flt = 0.0;
+      break;
+    case IMAGE_X_LR_CHIP:
+    case IMAGE_X_UR_CHIP:
+      value.Flt = image[0].NX;
+      break;
+    case IMAGE_Y_UL_CHIP:
+    case IMAGE_Y_UR_CHIP:
+      value.Flt = image[0].NX;
+      break;
+
+    case IMAGE_X_LL_FP:
+    case IMAGE_Y_LL_FP:
+      XY_to_LM (&x, &y, 0.0, 0.0, &image[0].coords);
+      value.Flt = (mode == X_LL_FP) ? x : y;
+      break;
+    case IMAGE_X_LR_FP:
+    case IMAGE_Y_LR_FP:
+      XY_to_LM (&x, &y, image[0].NX, 0.0, &image[0].coords);
+      value.Flt = (mode == X_LR_FP) ? x : y;
+      break;
+    case IMAGE_X_UL_FP:
+    case IMAGE_Y_UL_FP:
+      XY_to_LM (&x, &y, 0.0, image[0].NY, &image[0].coords);
+      value.Flt = (mode == X_UL_FP) ? x : y;
+      break;
+    case IMAGE_X_UR_FP:
+    case IMAGE_Y_UR_FP:
+      XY_to_LM (&x, &y, image[0].NX, image[0].NY, &image[0].coords);
+      value.Flt = (mode == X_UR_FP) ? x : y;
+      break;
+  }
+  return (value);
+}  
+
Index: /branches/eam_branch_20081124/Ohana/src/opihi/dvo/dbFields.c
===================================================================
--- /branches/eam_branch_20081124/Ohana/src/opihi/dvo/dbFields.c	(revision 20860)
+++ /branches/eam_branch_20081124/Ohana/src/opihi/dvo/dbFields.c	(revision 20861)
@@ -270,2 +270,75 @@
   return (TRUE);
 }
+
+int ParseImageField (dbField *field, char *fieldName) {
+
+  int mode;
+  PhotCode *code;
+
+  field->table = DVO_TABLE_IMAGE;
+  field->name  = strcreate (fieldName);
+
+  // if either GLON or GLAT is requested, we set up a static tranformation 
+  // at prepare to calculate the values only once for each row
+  if (!strcasecmp (fieldName, "GLON"))  { 
+    dbExtractImagesInitTransform (COORD_GALACTIC);
+    ESCAPE (IMAGE_GLON, MAG_NONE, OPIHI_FLT);
+  }
+  if (!strcasecmp (fieldName, "GLAT"))  {
+    dbExtractImagesInitTransform (COORD_GALACTIC);
+    ESCAPE (IMAGE_GLAT, MAG_NONE, OPIHI_FLT);
+  }
+
+  // if either ELON or ELAT is requested, we set up a static tranformation 
+  // at prepare to calculate the values only once for each row
+  if (!strcasecmp (fieldName, "ELON"))  { 
+    dbExtractImagesInitTransform (COORD_ECLIPTIC);
+    ESCAPE (IMAGE_ELON, MAG_NONE, OPIHI_FLT);
+  }
+  if (!strcasecmp (fieldName, "ELAT"))  {
+    dbExtractImagesInitTransform (COORD_ECLIPTIC);
+    ESCAPE (IMAGE_ELAT, MAG_NONE, OPIHI_FLT);
+  }
+
+  if (!strcasecmp (fieldName, "RA"       )) ESCAPE (IMAGE_RA,        MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "DEC"      )) ESCAPE (IMAGE_DEC,       MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "Xm"       )) ESCAPE (IMAGE_XM,        MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "airmass"  )) ESCAPE (IMAGE_AIRMASS,   MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "Mcal"     )) ESCAPE (IMAGE_MCAL,      MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "dMcal"    )) ESCAPE (IMAGE_dMCAL,     MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "photcode" )) ESCAPE (IMAGE_PHOTCODE,  MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "time"     )) ESCAPE (IMAGE_TIME,      MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "FWHM"     )) ESCAPE (IMAGE_FWHM,      MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "exptime"  )) ESCAPE (IMAGE_EXPTIME,   MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "nstar"    )) ESCAPE (IMAGE_NSTAR,     MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "ncal"     )) ESCAPE (IMAGE_NCAL,      MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "sky"      )) ESCAPE (IMAGE_SKY,       MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "flag"     )) ESCAPE (IMAGE_FLAG,      MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "NX"       )) ESCAPE (IMAGE_NX_PIX,    MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "NY"       )) ESCAPE (IMAGE_NY_PIX,    MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "theta"    )) ESCAPE (IMAGE_THETA,     MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "skew"     )) ESCAPE (IMAGE_SKEW,      MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "scale"    )) ESCAPE (IMAGE_SCALE,     MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "dscale"   )) ESCAPE (IMAGE_DSCALE,    MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "imageID"  )) ESCAPE (IMAGE_IMAGE_ID,  MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "X_LL_CHIP")) ESCAPE (IMAGE_X_LL_CHIP, MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "X_LR_CHIP")) ESCAPE (IMAGE_X_LR_CHIP, MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "X_UL_CHIP")) ESCAPE (IMAGE_X_UL_CHIP, MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "X_UR_CHIP")) ESCAPE (IMAGE_X_UR_CHIP, MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "Y_LL_CHIP")) ESCAPE (IMAGE_Y_LL_CHIP, MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "Y_LR_CHIP")) ESCAPE (IMAGE_Y_LR_CHIP, MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "Y_UL_CHIP")) ESCAPE (IMAGE_Y_UL_CHIP, MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "Y_UR_CHIP")) ESCAPE (IMAGE_Y_UR_CHIP, MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "X_LL_FP"  )) ESCAPE (IMAGE_X_LL_FP,   MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "X_LR_FP"  )) ESCAPE (IMAGE_X_LR_FP,   MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "X_UL_FP"  )) ESCAPE (IMAGE_X_UL_FP,   MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "X_UR_FP"  )) ESCAPE (IMAGE_X_UR_FP,   MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "Y_LL_FP"  )) ESCAPE (IMAGE_Y_LL_FP,   MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "Y_LR_FP"  )) ESCAPE (IMAGE_Y_LR_FP,   MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "Y_UL_FP"  )) ESCAPE (IMAGE_Y_UL_FP,   MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "Y_UR_FP"  )) ESCAPE (IMAGE_Y_UR_FP,   MAG_NONE, OPIHI_FLT);
+
+  // for words that don't parse, try a photcode
+  gprint (GP_ERR, "unknown image field %s\n", fieldName);
+  return (FALSE);
+}
Index: /branches/eam_branch_20081124/Ohana/src/opihi/dvo/imextract.c
===================================================================
--- /branches/eam_branch_20081124/Ohana/src/opihi/dvo/imextract.c	(revision 20860)
+++ /branches/eam_branch_20081124/Ohana/src/opihi/dvo/imextract.c	(revision 20861)
@@ -1,45 +1,3 @@
 # include "dvoshell.h"
-
-// need to upgrade this to support multiple fields and WHERE clauses
-
-enum {ZERO, 
-      RA, 
-      DEC, 
-      Xm, 
-      AIRMASS, 
-      MCAL, 
-      dMCAL, 
-      PHOTCODE, 
-      TIME, 
-      FWHM, 
-      EXPTIME, 
-      NSTAR, 
-      NCAL, 
-      SKY, 
-      FLAG, 
-      NX_PIX, 
-      NY_PIX, 
-      THETA, 
-      SKEW, 
-      SCALE, 
-      DSCALE, 
-      IMAGE_ID,
-      X_LL_CHIP,
-      X_LR_CHIP,
-      X_UL_CHIP,
-      X_UR_CHIP,
-      Y_LL_CHIP,
-      Y_LR_CHIP,
-      Y_UL_CHIP,
-      Y_UR_CHIP,
-      X_LL_FP,
-      X_LR_FP,
-      X_UL_FP,
-      X_UR_FP,
-      Y_LL_FP,
-      Y_LR_FP,
-      Y_UL_FP,
-      Y_UR_FP,
-};
 
 int imextract (int argc, char **argv) {
@@ -55,5 +13,14 @@
   Vector *vec;
 
-  if (!InitPhotcodes ()) return (FALSE);
+  if ((N = get_argument (argc, argv, "-h"))) goto help;
+  if ((N = get_argument (argc, argv, "--help"))) goto help;
+
+  VERBOSE = FALSE;
+  if ((N = get_argument (argc, argv, "-v"))) {
+    remove_argument (N, &argc, argv);
+    VERBOSE = TRUE;
+  }
+
+  if (!InitPhotcodes ()) goto escape;
 
   // parse skyregion options
@@ -63,100 +30,50 @@
   }
 
-  /* check for time-based selection */
-  TimeSelect = FALSE;
-  if ((N = get_argument (argc, argv, "-time"))) {
-    remove_argument (N, &argc, argv);
-    if (!ohana_str_to_time (argv[N], &tzero)) { 
-      gprint (GP_ERR, "syntax error\n");
-      return (FALSE);
+  // command-line is of the form: avextract field,field, field [where (field op value)...]
+
+  // parse the fields to be extracted and returned
+  fields = dbCmdlineFields (argc, argv, DVO_TABLE_IMAGE, &last, &Nfields);
+  if (fields == NULL) return (FALSE);
+
+  // examine line for 'where' or 'match to'.  'match to' is forbidden
+  state = dbCmdlineConditions (argc, argv, last, &next);
+  if (state == DVO_DB_CMDLINE_ERROR) goto escape;
+  if (state == DVO_DB_CMDLINE_IS_MATCH) goto escape; // not allowed for mextract
+
+  // parse the remainder of the line as a boolean math expression
+  cstack = isolate_elements (argc-next, &argv[next], &Ncstack);
+  
+  // construct the db Boolean math stack (frees cstack)
+  stack = dbRPN (Ncstack, cstack, &Nstack);
+
+  // add the skyregion limits to the where statement (or create)
+  dbAstroRegionLimits (&stack, &Nstack, selection, DVO_TABLE_IMAGE);
+
+  // parse stack elements into fields and scalars as needed
+  Nreturn = Nfields; 
+  if (!dbCheckStack (stack, Nstack, DVO_TABLE_IMAGE, &fields, &Nfields)) goto escape;
+
+  /* create output storage vectors */
+  ALLOCATE (values, dbValue, Nfields);
+  ALLOCATE (vec, Vector *, Nreturn);
+  for (i = 0; i < Nreturn; i++) {
+    if (ISNUM(fields[i].name[0])) {
+      sprintf (name, "v_%s", fields[i].name);
+    } else {
+      sprintf (name, "%s", fields[i].name);
     }
-    remove_argument (N, &argc, argv);
-    if (!ohana_str_to_dtime (argv[N], &trange)) { 
-      gprint (GP_ERR, "syntax error\n");
-      return (FALSE);
-    }
-    remove_argument (N, &argc, argv);
-    TimeSelect = TRUE;
+    if ((vec[i] = SelectVector (name, ANYVECTOR, TRUE)) == NULL) goto escape;
   }
 
-  /* check for region-based selection */
-  FlagValue = 0;
-  FlagSelect = FALSE;
-  if ((N = get_argument (argc, argv, "-flag"))) {
-    remove_argument (N, &argc, argv);
-    FlagValue = atoi (argv[N]);
-    remove_argument (N, &argc, argv);
-    FlagSelect = TRUE;
-  }
+  Npts = 0;
+  NPTS = 1;
 
-  /* check for photcode-based selection */
-  code = NULL;
-  PhotcodeSelect = FALSE;
-  if ((N = get_argument (argc, argv, "-photcode"))) {
-    PhotcodeSelect = TRUE;
-    remove_argument (N, &argc, argv);
-    if ((code = GetPhotcodebyName (argv[N])) == NULL) {
-      gprint (GP_ERR, "ERROR: photcode %s not found in photcode table\n", argv[N]);
-      return (FALSE);
-    }
-    if ((code[0].type != PHOT_SEC) && (code[0].type != PHOT_DEP)) {
-      gprint (GP_ERR, "photcode must be primary, secondary, or dependent code\n");
-      return (FALSE);
-    }
-    remove_argument (N, &argc, argv);
-  }
-
-  if (argc != 2) {
-    gprint (GP_ERR, "USAGE: imextract (value) [-region] [-time start range] [-photcode photcode]\n");
-    return (FALSE);
-  }
-  
-  /* identify selection */
-  mode = ZERO;
-  if (!strcasecmp (argv[1], "ra"       )) mode = RA;
-  if (!strcasecmp (argv[1], "dec"      )) mode = DEC;
-  if (!strcasecmp (argv[1], "Xm"       )) mode = Xm;
-  if (!strcasecmp (argv[1], "airmass"  )) mode = AIRMASS;
-  if (!strcasecmp (argv[1], "Mcal"     )) mode = MCAL;
-  if (!strcasecmp (argv[1], "dMcal"    )) mode = dMCAL;
-  if (!strcasecmp (argv[1], "photcode" )) mode = PHOTCODE;
-  if (!strcasecmp (argv[1], "time"     )) mode = TIME;
-  if (!strcasecmp (argv[1], "FWHM"     )) mode = FWHM;
-  if (!strcasecmp (argv[1], "exptime"  )) mode = EXPTIME;
-  if (!strcasecmp (argv[1], "nstar"    )) mode = NSTAR;
-  if (!strcasecmp (argv[1], "ncal"     )) mode = NCAL;
-  if (!strcasecmp (argv[1], "sky"      )) mode = SKY;
-  if (!strcasecmp (argv[1], "flag"     )) mode = FLAG;
-  if (!strcasecmp (argv[1], "NX"       )) mode = NX_PIX;
-  if (!strcasecmp (argv[1], "NY"       )) mode = NY_PIX;
-  if (!strcasecmp (argv[1], "theta"    )) mode = THETA;
-  if (!strcasecmp (argv[1], "skew"     )) mode = SKEW;
-  if (!strcasecmp (argv[1], "scale"    )) mode = SCALE;
-  if (!strcasecmp (argv[1], "dscale"   )) mode = DSCALE;
-  if (!strcasecmp (argv[1], "imageID"  )) mode = IMAGE_ID;
-  if (!strcasecmp (argv[1], "X_LL_CHIP")) mode = X_LL_CHIP;
-  if (!strcasecmp (argv[1], "X_LR_CHIP")) mode = X_LR_CHIP;
-  if (!strcasecmp (argv[1], "X_UL_CHIP")) mode = X_UL_CHIP;
-  if (!strcasecmp (argv[1], "X_UR_CHIP")) mode = X_UR_CHIP;
-  if (!strcasecmp (argv[1], "Y_LL_CHIP")) mode = Y_LL_CHIP;
-  if (!strcasecmp (argv[1], "Y_LR_CHIP")) mode = Y_LR_CHIP;
-  if (!strcasecmp (argv[1], "Y_UL_CHIP")) mode = Y_UL_CHIP;
-  if (!strcasecmp (argv[1], "Y_UR_CHIP")) mode = Y_UR_CHIP;
-  if (!strcasecmp (argv[1], "X_LL_FP"  )) mode = X_LL_FP;
-  if (!strcasecmp (argv[1], "X_LR_FP"  )) mode = X_LR_FP;
-  if (!strcasecmp (argv[1], "X_UL_FP"  )) mode = X_UL_FP;
-  if (!strcasecmp (argv[1], "X_UR_FP"  )) mode = X_UR_FP;
-  if (!strcasecmp (argv[1], "Y_LL_FP"  )) mode = Y_LL_FP;
-  if (!strcasecmp (argv[1], "Y_LR_FP"  )) mode = Y_LR_FP;
-  if (!strcasecmp (argv[1], "Y_UL_FP"  )) mode = Y_UL_FP;
-  if (!strcasecmp (argv[1], "Y_UR_FP"  )) mode = Y_UR_FP;
-  if (mode == ZERO) {
-    gprint (GP_ERR, "value may be one of the following:\n");
-    gprint (GP_ERR, " ra dec airmass Mcal dMcal Xm photcode time fwhm exptime nstar ncal sky flag\n");
-    return (FALSE);
-  }
-  if ((vec = SelectVector (argv[1], ANYVECTOR, TRUE)) == NULL) return (FALSE);
+  // grab data from all selected sky regions
+  Signal = signal (SIGINT, handle_interrupt);
+  interrupt = FALSE;
 
   if ((image = LoadImages (&Nimage)) == NULL) return (FALSE);
+
+  // XXX do I need to use this, or the region portion
   image_subset (image, Nimage, &subset, &Nsubset, selection, tzero, trange, TimeSelect);
   if ((mode == RA) || (mode == DEC)) BuildChipMatch (image, Nimage);
@@ -167,148 +84,33 @@
   ResetVector (vec, OPIHI_FLT, Nimage);
   
-  N = 0;
-  /* assign vector values */
-  for (i = 0; i < Nsubset; i++) {
-    j = subset[i];
-    if (PhotcodeSelect) {
-      if (code[0].type == PHOT_DEP) {
-	if (code[0].code != image[j].photcode) continue;
+  for (j = 0; (j < Nimage) && !interrupt; j++) {
+
+    dbExtractImagesInit (); // reset counters for saved fields 
+    for (n = 0; n < Nfields; n++) {
+      values[n] = dbExtractImages (&image[j], &fields[n]);
+    }
+    // test the conditional statement
+    if (!dbBooleanCond (stack, Nstack, values)) continue;
+    for (n = 0; n < Nreturn; n++) {
+      if (vec[n][0].type == OPIHI_FLT) {
+	vec[n][0].elements.Flt[Npts] = values[n].Flt;
       } else {
-	if (code[0].code != GetPhotcodeEquivCodebyCode (image[j].photcode)) continue;
+	vec[n][0].elements.Int[Npts] = values[n].Int;
       }
     }
-    if (FlagSelect && (FlagValue != image[j].code)) continue;
-    switch (mode) {
-      case RA:
-	if (!FindMosaicForImage (image, Nimage, j)) continue;
-	x = 0.5*image[j].NX;
-	y = 0.5*image[j].NY;
-	XY_to_RD (&ra, &dec, x, y, &image[j].coords);
-	vec[0].elements.Flt[N] = ra;
-	break;
-      case DEC:
-	if (!FindMosaicForImage (image, Nimage, j)) continue;
-	x = 0.5*image[j].NX;
-	y = 0.5*image[j].NY;
-	XY_to_RD (&ra, &dec, x, y, &image[j].coords);
-	vec[0].elements.Flt[N] = dec;
-	break;
-      case Xm:
-	vec[0].elements.Flt[N] = pow(10.0, 0.01*image[j].Xm);
-	break;
-      case AIRMASS:
-	vec[0].elements.Flt[N] = image[j].secz;
-	break;
-      case MCAL:
-	vec[0].elements.Flt[N] = image[j].Mcal;
-	break;
-      case dMCAL:
-	vec[0].elements.Flt[N] = image[j].dMcal;
-	break;
-      case PHOTCODE:
-	vec[0].elements.Flt[N] = image[j].photcode;
-	break;
-      case TIME:
-	t = image[j].tzero + 0.5*image[j].NY * image[j].trate / 10000;
-	vec[0].elements.Flt[N] = TimeValue (t, TimeReference, TimeFormat);
-	break;
-      case FWHM:
-	vec[0].elements.Flt[N] = image[j].fwhm_x / 25.0;
-	break;
-      case EXPTIME:
-	vec[0].elements.Flt[N] = image[j].exptime;
-	break;
-      case NSTAR:
-	vec[0].elements.Flt[N] = image[j].nstar;
-	break;
-      case NCAL:
-	vec[0].elements.Flt[N] = image[j].Mxxxx;
-	break;
-      case SKY:
-	vec[0].elements.Flt[N] = image[j].Myyyy + 0x8000;
-	break;
-      case FLAG:
-	vec[0].elements.Flt[N] = image[j].code;
-	break;
-      case NX_PIX:
-	vec[0].elements.Flt[N] = image[j].NX;
-	break;
-      case NY_PIX:
-	vec[0].elements.Flt[N] = image[j].NY;
-	break;
-      case IMAGE_ID:
-	vec[0].elements.Flt[N] = image[j].imageID;
-	break;
-      case THETA: {
-	double theta1, theta2, s1, s2;
-	s1 = SIGN(image[j].coords.pc1_1);
-	s2 = SIGN(image[j].coords.pc2_2);
-	theta1 = DEG_RAD*atan2 (+s1*image[j].coords.pc1_2, s1*image[j].coords.pc1_1);
-	theta2 = DEG_RAD*atan2 (-s2*image[j].coords.pc2_1, s2*image[j].coords.pc2_2);
-	vec[0].elements.Flt[N] = 0.5*(theta1+theta2);
-	break; }
-      case SKEW: {
-	double theta1, theta2, s1, s2;
-	s1 = SIGN(image[j].coords.pc1_1);
-	s2 = SIGN(image[j].coords.pc2_2);
-	theta1 = DEG_RAD*atan2 (+s1*image[j].coords.pc1_2, s1*image[j].coords.pc1_1);
-	theta2 = DEG_RAD*atan2 (-s2*image[j].coords.pc2_1, s2*image[j].coords.pc2_2);
-	vec[0].elements.Flt[N] = (theta1-theta2);
-	break; }
-      case SCALE: {
-	double scale1, scale2;
-	scale1 = fabs(image[j].coords.cdelt1);
-	scale2 = fabs(image[j].coords.cdelt2);
-	vec[0].elements.Flt[N] = 0.5*(scale1+scale2);
-	break; }
-      case DSCALE: {
-	double scale1, scale2;
-	scale1 = fabs(image[j].coords.cdelt1);
-	scale2 = fabs(image[j].coords.cdelt2);
-	vec[0].elements.Flt[N] = (scale1-scale2);
-	break; }
-
-    // reference pixel extractions
-    case X_LL_CHIP:
-    case Y_LL_CHIP:
-    case Y_LR_CHIP:
-    case X_UL_CHIP:
-      vec[0].elements.Flt[N] = 0.0;
-      break;
-    case X_LR_CHIP:
-    case X_UR_CHIP:
-      vec[0].elements.Flt[N] = image[j].NX;
-      break;
-    case Y_UL_CHIP:
-    case Y_UR_CHIP:
-      vec[0].elements.Flt[N] = image[j].NX;
-      break;
-
-    case X_LL_FP:
-    case Y_LL_FP:
-      XY_to_LM (&x, &y, 0.0, 0.0, &image[j].coords);
-      vec[0].elements.Flt[N] = (mode == X_LL_FP) ? x : y;
-      break;
-    case X_LR_FP:
-    case Y_LR_FP:
-      XY_to_LM (&x, &y, image[j].NX, 0.0, &image[j].coords);
-      vec[0].elements.Flt[N] = (mode == X_LR_FP) ? x : y;
-      break;
-    case X_UL_FP:
-    case Y_UL_FP:
-      XY_to_LM (&x, &y, 0.0, image[j].NY, &image[j].coords);
-      vec[0].elements.Flt[N] = (mode == X_UL_FP) ? x : y;
-      break;
-    case X_UR_FP:
-    case Y_UR_FP:
-      XY_to_LM (&x, &y, image[j].NX, image[j].NY, &image[j].coords);
-      vec[0].elements.Flt[N] = (mode == X_UR_FP) ? x : y;
-      break;
+    Npts++;
+    if (Npts >= NPTS) {
+      NPTS += 2000;
+      for (n = 0; n < Nreturn; n++) {
+	REALLOCATE (vec[n][0].elements.Flt, opihi_flt, NPTS);
+      }
     }
-    N++;
   }
-  
-  vec[0].Nelements = N;
-  REALLOCATE (vec[0].elements.Flt, opihi_flt, N);
+  signal (SIGINT, Signal);
+  interrupt = FALSE;
+  for (n = 0; n < Nreturn; n++) {
+    vec[n][0].Nelements = Npts;
+    REALLOCATE (vec[n][0].elements.Flt, opihi_flt, MAX(1,Npts));
+  }
 
   free (subset);
@@ -316,4 +118,18 @@
   return (TRUE);
   
+ escape:
+  return (FALSE);
+
+ help:
+  gprint (GP_ERR, "USAGE: imextract field[,field,field...] where (expression)\n");
+
+  if ((argc > N + 1) && !strcasecmp (argv[N+1], "fields")) {
+    gprint (GP_ERR, " USAGE: imextract field[,field,field...] where (expression)\n");
+    gprint (GP_ERR, "  RA : right ascension of field center (J2000)\n");
+    gprint (GP_ERR, "  DEC : declination of field center\n");
+    return (FALSE);
+  }
+  gprint (GP_ERR, " avextract --help fields : for a complete listing of allowed fields\n");
+  return (FALSE);
 }
   
Index: /branches/eam_branch_20081124/Ohana/src/opihi/include/dvoshell.h
===================================================================
--- /branches/eam_branch_20081124/Ohana/src/opihi/include/dvoshell.h	(revision 20860)
+++ /branches/eam_branch_20081124/Ohana/src/opihi/include/dvoshell.h	(revision 20861)
@@ -135,4 +135,44 @@
 };
 
+enum {IMAGE_ZERO, 
+      IMAGE_RA, 
+      IMAGE_DEC, 
+      IMAGE_Xm, 
+      IMAGE_AIRMASS, 
+      IMAGE_MCAL, 
+      IMAGE_dMCAL, 
+      IMAGE_PHOTCODE, 
+      IMAGE_TIME, 
+      IMAGE_FWHM, 
+      IMAGE_EXPTIME, 
+      IMAGE_NSTAR, 
+      IMAGE_NCAL, 
+      IMAGE_SKY, 
+      IMAGE_FLAG, 
+      IMAGE_NX_PIX, 
+      IMAGE_NY_PIX, 
+      IMAGE_THETA, 
+      IMAGE_SKEW, 
+      IMAGE_SCALE, 
+      IMAGE_DSCALE, 
+      IMAGE_IMAGE_ID,
+      IMAGE_X_LL_CHIP,
+      IMAGE_X_LR_CHIP,
+      IMAGE_X_UL_CHIP,
+      IMAGE_X_UR_CHIP,
+      IMAGE_Y_LL_CHIP,
+      IMAGE_Y_LR_CHIP,
+      IMAGE_Y_UL_CHIP,
+      IMAGE_Y_UR_CHIP,
+      IMAGE_X_LL_FP,
+      IMAGE_X_LR_FP,
+      IMAGE_X_UL_FP,
+      IMAGE_X_UR_FP,
+      IMAGE_Y_LL_FP,
+      IMAGE_Y_LR_FP,
+      IMAGE_Y_UL_FP,
+      IMAGE_Y_UR_FP,
+};
+
 enum {DVO_TABLE_AVERAGE, DVO_TABLE_MEASURE};
 enum {DVO_DB_CMDLINE_ERROR, DVO_DB_CMDLINE_IS_END, DVO_DB_CMDLINE_IS_WHERE, DVO_DB_CMDLINE_IS_MATCH}; 
