Index: /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/Makefile
===================================================================
--- /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/Makefile	(revision 13453)
+++ /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/Makefile	(revision 13454)
@@ -21,12 +21,22 @@
 $(SRC)/init.$(ARCH).o            	\
 $(SRC)/ImageOps.$(ARCH).o		\
-$(SRC)/ImageSelection.$(ARCH).o	\
+$(SRC)/ImageSelection.$(ARCH).o	        \
 $(SRC)/LoadImages.$(ARCH).o		\
 $(SRC)/cmpReadFile.$(ARCH).o		\
-$(SRC)/compare.$(ARCH).o               \
+$(SRC)/compare.$(ARCH).o                \
 $(SRC)/match_image.$(ARCH).o		\
-$(SRC)/photometry.$(ARCH).o            \
+$(SRC)/photometry.$(ARCH).o             \
 $(SRC)/dvomisc.$(ARCH).o		\
 $(SRC)/region_list.$(ARCH).o		\
+$(SRC)/dvomisc.$(ARCH).o		\
+$(SRC)/dbBooleanCond.$(ARCH).o		\
+$(SRC)/dbCheckStack.$(ARCH).o		\
+$(SRC)/dbCmdlineFields.$(ARCH).o	\
+$(SRC)/dbExtractAverages.$(ARCH).o	\
+$(SRC)/dbExtractMeasures.$(ARCH).o	\
+$(SRC)/dbFields.$(ARCH).o		\
+$(SRC)/dbRPN.$(ARCH).o			\
+$(SRC)/dbStackMath.$(ARCH).o		\
+$(SRC)/dbStackOps.$(ARCH).o		\
 $(SRC)/dvo.$(ARCH).o
 
Index: /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/avextract.c
===================================================================
--- /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/avextract.c	(revision 13453)
+++ /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/avextract.c	(revision 13454)
@@ -3,14 +3,17 @@
 int avextract (int argc, char **argv) {
   
-  int i, j, m, N, NPTS, last, Nfields;
+  int i, j, n, m, Npts, NPTS, last, Nfields, Nreturn, Ncstack, Nstack;
   int Nsecfilt, mode;
   char *RegionName, *RegionList, *p;
+  char **cstack;
+  float *values;
 
   Catalog catalog;
   SkyList *skylist;
   PhotCode *code;
-  Vector *vec;
+  Vector **vec;
 
-  dvoFields *fields;
+  dbField *fields;
+  dbStack *stack;
 
   /* defaults */
@@ -26,4 +29,8 @@
   Nsecfilt = GetPhotcodeNsecfilt ();
 
+  // remove skyregion options
+  // XXX this needs to explicitly handle -qregion and -skyregion
+  if (!SetRegionSelection (&argc, argv, &RegionName, &RegionList)) goto escape;
+
   // command-line is of the form: avextract field,field, field [where (field op value)...]
 
@@ -33,16 +40,12 @@
 
   // parse the remainder of the line as a boolean math expression
-  cstack = isolate_elements (argv-last, &argv[last], &Ncstack);
+  cstack = isolate_elements (argc-last, &argv[last], &Ncstack);
   
   // construct the db Boolean math stack (frees cstack)
-  dbStack = dbRPN (Ncstack, cstack, &NdbStack);
+  stack = dbRPN (Ncstack, cstack, &Nstack);
 
   Nreturn = Nfields; 
-  dbCheckStack (dbStack, NdbStack, DVO_TABLE_AVERAGE, &fields, &Nfields);
+  dbCheckStack (stack, Nstack, DVO_TABLE_AVERAGE, &fields, &Nfields);
   // XXX handle errors
-
-  /* interpret command-line options */
-  // this needs to explicitly handles -qregion and -skyregion
-  if (!SetRegionSelection (&argc, argv, &RegionName, &RegionList)) goto escape;
 
   /* load region corresponding to selection above */
@@ -51,5 +54,5 @@
   /* create output storage vectors */
   ALLOCATE (values, float, Nfields);
-  ALLOCATE (vec, Vector, Nreturn);
+  ALLOCATE (vec, Vector *, Nreturn);
   for (i = 0; i < Nreturn; i++) {
     if ((vec[i] = SelectVector (fields[i].name, ANYVECTOR, TRUE)) == NULL) goto escape;
@@ -78,16 +81,16 @@
       // XXX for measure values, this could be optimized for one loop over measures...
       for (n = 0; n < Nfields; n++) {
-	values[n] = ExtractAveragesNew (&catalog.average[j], &catalog.secfilt[j*Nsecfilt], &catalog.measure[m], fields[n]);
+	values[n] = dbExtractAverages (&catalog.average[j], &catalog.secfilt[j*Nsecfilt], &catalog.measure[m], &fields[n]);
       }
       // test the conditional statement
-      if (!dbBooleanCond (dbStack, NdbStack, values, fields, Nfields)) continue;
+      if (!dbBooleanCond (stack, Nstack, values)) continue;
       for (n = 0; n < Nreturn; n++) {
-	vec[n].elements[N] = values[n];
+	vec[n][0].elements[Npts] = values[n];
       }
-      N++;
-      if (N >= NPTS) {
+      Npts++;
+      if (Npts >= NPTS) {
 	NPTS += 2000;
 	for (n = 0; n < Nreturn; n++) {
-	  REALLOCATE (vec[n].elements, float, NPTS);
+	  REALLOCATE (vec[n][0].elements, float, NPTS);
 	}
       }
@@ -96,7 +99,9 @@
   }
   for (n = 0; n < Nreturn; n++) {
-    vec[n].Nelements = N;
-    REALLOCATE (vec[n].elements, float, MAX(1,N));
+    vec[n][0].Nelements = Npts;
+    REALLOCATE (vec[n][0].elements, float, MAX(1,Npts));
   }
+
+  // XXX free fields and stack 
 
   SkyListFree (skylist, ((RegionName != NULL) || (RegionList != NULL)));
Index: /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/cmpload.c
===================================================================
--- /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/cmpload.c	(revision 13453)
+++ /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/cmpload.c	(revision 13454)
@@ -8,5 +8,5 @@
   int i, Noverlay, NOVERLAY, Nstar, N, Nin, Nextra, Objtype, type;
   int doneread, done, Nskip, Nbytes, nbytes, Ninstar;
-  char *c, *c2, name;
+  char *c, *c2, *name;
   double dtmp;
   FILE *f;
Index: /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/dbBooleanCond.c
===================================================================
--- /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/dbBooleanCond.c	(revision 13453)
+++ /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/dbBooleanCond.c	(revision 13454)
@@ -1,16 +1,19 @@
 # include "dvoshell.h"
 
-int dbBooleanCond (dvoStack dbStack, int NdbStack, float *values, dvoFields *fields, int Nfields) {
+// evaluate the expression in inStack as a boolean; necessary db field values are
+// supplied by fields, in order 0 - Nfields (validate before calling)
+int dbBooleanCond (dbStack *inStack, int NinStack, float *fields) {
   
-  int i, j, Nstack;
-  dvoStack **stack, *output;
+  float value;
+  int i, j, N, Nstack;
+  dbStack **stack, *output;
 
   // 'no stack' means 'no where statement'
-  if (NdbStack == 0) return (TRUE);
+  if (NinStack == 0) return (TRUE);
 
-  Nstack = NdbStack;
-  ALLOCATE (stack, dvoStack *, NdbStack);
-  for (i = 0; i < NdbStack; i++) {
-    stack[i] = &dbStack[i];
+  Nstack = NinStack;
+  ALLOCATE (stack, dbStack *, NinStack);
+  for (i = 0; i < NinStack; i++) {
+    stack[i] = &inStack[i];
   }
 
@@ -18,8 +21,8 @@
 
     /***** binary operators *****/
-    if ((stack[i].type >= 3) && (stack[i].type <= 8)) {
+    if ((stack[i][0].type >= 3) && (stack[i][0].type <= 8)) {
 
       // pre-test that op and entries match
-      output = dbBinary (stack[i-2], stack[i-1], stack[i].name, fields, Nfields); 
+      output = dbBinary (stack[i-2], stack[i-1], stack[i][0].name, fields); 
 
       // free temporary stack items, drop external items
@@ -38,13 +41,13 @@
 
     /***** unary operators **/
-    if (stack[i].type == 9) {
+    if (stack[i][0].type == 9) {
 
       // pre-test that op and entries match
-      output = dbUnary (&stack[i-1], stack[i].name, fields, Nfields); 
+      output = dbUnary (stack[i-1], stack[i][0].name, fields); 
 
       // free temporary stack items, drop external items
-      dbFreeEntry (stack[i-2]);
       dbFreeEntry (stack[i-1]);
 
+      stack[i-1] = output;
       for (j = i + 1; j < Nstack; j++) {
 	stack[j-1] = stack[j];
Index: /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/dbCheckStack.c
===================================================================
--- /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/dbCheckStack.c	(revision 13453)
+++ /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/dbCheckStack.c	(revision 13454)
@@ -1,12 +1,12 @@
-# include "opihi.h"
+# include "dvoshell.h"
 
-int dbCheckStack (dvoStack *stack, int Nstack, int table, dvoField **inFields, int *Nfields) {
+int dbCheckStack (dbStack *stack, int Nstack, int table, dbField **inFields, int *Nfields) {
 
-  int i, Nx, Ny, Nv, size;
+  int i, j, status, NFIELDS;
   char *c;
-  dvoFields *fields;
+  dbField *fields;
 
   NFIELDS = *Nfields + 10;
-  REALLOCATE (*inFields, dvoField, NFIELDS);
+  REALLOCATE (*inFields, dbField, NFIELDS);
   fields = *inFields;
 
@@ -44,5 +44,5 @@
 
       *Nfields ++;
-      CHECK_REALLOCATE (*inFields, dvoField, NFIELDS, *Nfields, 10);
+      CHECK_REALLOCATE (*inFields, dbField, NFIELDS, *Nfields, 10);
       fields = *inFields;
     }
Index: /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/dbCmdlineFields.c
===================================================================
--- /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/dbCmdlineFields.c	(revision 13453)
+++ /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/dbCmdlineFields.c	(revision 13454)
@@ -2,12 +2,15 @@
 
 // identify the fields to be extracted (test for where, check syntax)
-dvoField *dbCmdlineFields (int argc, char **argv, int table, int *last, int *nfields) {
+dbField *dbCmdlineFields (int argc, char **argv, int table, int *last, int *nfields) {
 
-  int i, Nfields, NFIELDS, 
+  int i, j, status, Nfields, NFIELDS;
+  char *p, *q, *field;
+  dbField *fields;
 
   *nfields = 0;
   Nfields = 0;
   NFIELDS = 10;
-  ALLOCATE (fields, dvoField, NFIELDS);
+  ALLOCATE (fields, dbField, NFIELDS);
+  dbInitField (&fields[0]);
 
   // examine each argv[i] entry until we reach a where 
@@ -36,4 +39,7 @@
 	gprint (GP_ERR, "unknown database field %s\n", field);
 	free (field);
+	for (j = 0; j <= Nfields; j++) {
+	  if (fields->name != NULL) free (fields->name);
+	}
 	free (fields);
 	return (NULL);
@@ -42,5 +48,6 @@
 
       Nfields ++;
-      CHECK_REALLOCATE (fields, dvoField, NFIELDS, Nfields, 10);
+      CHECK_REALLOCATE (fields, dbField, NFIELDS, Nfields, 10);
+      dbInitField (&fields[Nfields]);
     }
   }
@@ -53,5 +60,5 @@
       return (NULL);
     }
-    if (i >= argc - 2) {
+    if (i > argc - 2) {
       gprint (GP_ERR, "missing boolean expression\n");
       free (fields);
Index: /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/dbExtractAverages.c
===================================================================
--- /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/dbExtractAverages.c	(revision 13454)
+++ /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/dbExtractAverages.c	(revision 13454)
@@ -0,0 +1,112 @@
+# include "dvoshell.h"
+
+/* return average.field based on the selection */
+double dbExtractAverages (Average *average, SecFilt *secfilt, Measure *measure, dbField *field) {
+
+  int i;
+  double value;
+
+  value = NO_MAG;
+
+  /* assign vector values */
+  switch (field->ID) {
+    case AVE_RA:
+      value = average[0].R;
+      break;
+    case AVE_DEC:
+      value = average[0].D;
+      break;
+    case AVE_RA_ERR:
+      value = average[0].dR;
+      break;
+    case AVE_DEC_ERR:
+      value = average[0].dD;
+      break;
+
+    case AVE_U_RA:
+      value = average[0].uR;
+      break;
+    case AVE_U_DEC:
+      value = average[0].uD;
+      break;
+    case AVE_U_RA_ERR:
+      value = average[0].duR;
+      break;
+    case AVE_U_DEC_ERR:
+      value = average[0].duD;
+      break;
+
+    case AVE_PAR:
+      value = average[0].P;
+      break;
+    case AVE_PAR_ERR:
+      value = average[0].dP;
+      break;
+
+    case AVE_NMEAS:
+      value = average[0].Nm;
+      break;
+    case AVE_NMISS:
+      value = average[0].Nn;
+      break;
+    case AVE_Xp:
+      value = 0.01*average[0].Xp;
+      break;
+    case AVE_FLAG:
+      value = average[0].code;
+      break;
+
+    case AVE_MAG:
+      switch (field->magMode) {
+	case MAG_AVE:
+	  value = PhotAve  (field->photcode, average, secfilt);
+	  break;
+	case MAG_REF:
+	  value = PhotRef  (field->photcode, average, secfilt, measure);
+	  break;
+	case MAG_INST:
+	case MAG_CAT:
+	case MAG_SYS:
+	case MAG_REL:
+	case MAG_CAL:
+	  // XXX need to code this correctly: this returns just the first matching value
+	  value = NO_MAG;
+	  for (i = 0; i < average[0].Nm; i++) {
+	    if (field->photcode->code != measure[i].photcode) continue;
+	    value = measure[i].M;
+	    break;
+	  }
+	  break;
+      }
+      break;
+    case AVE_dMAG:
+      value = PhotdM (field->photcode, average, secfilt);
+      break;
+    case AVE_Xm:
+      value = PhotXm (field->photcode, average, secfilt);
+      break;
+    case AVE_TYPE:
+      break;
+    case AVE_TYPEFRAC:
+      break;
+    case AVE_NCODE:
+      value = 0;
+      for (i = 0; i < average[0].Nm; i++) {
+	if (field->photcode->code != GetPhotcodeEquivCodebyCode (measure[i].photcode)) continue;
+	value ++;
+      }
+      break;
+    case AVE_NPHOT:
+      value = 0;
+      for (i = 0; i < average[0].Nm; i++) {
+	if (field->photcode->code != GetPhotcodeEquivCodebyCode (measure[i].photcode)) continue;
+	if (measure[i].flags & (ID_MEAS_POOR | ID_MEAS_SKIP)) continue;
+	value ++;
+      }
+      break;
+    case AVE_NCRIT:
+      break;
+  }
+  return (value);
+}  
+
Index: /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/dbExtractMeasures.c
===================================================================
--- /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/dbExtractMeasures.c	(revision 13454)
+++ /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/dbExtractMeasures.c	(revision 13454)
@@ -0,0 +1,135 @@
+# include "dvoshell.h"
+
+/* time concepts */
+static time_t TimeReference;
+static int TimeFormat;
+
+void dbExtractMeasuresInit () {
+  GetTimeFormat (&TimeReference, &TimeFormat);
+}
+
+/* return measure.field based on the selection */
+double dbExtractMeasures (Average *average, SecFilt *secfilt, Measure *measure, dbField *field) {
+
+  int i;
+  double value;
+  double ra, dec, x, y;
+
+  Image *image;
+  Coords *mosaic;
+
+  value = NO_MAG;
+
+  switch (field->ID) {
+    // XXX not sure how to apply the photcode here....
+    case MEAS_MAG: /* magnitudes are already determined above */
+      switch (field->magMode) {
+	case MAG_INST:
+	  value = PhotInst (measure);  
+	  break;
+	case MAG_CAT:
+	  value = PhotCat  (measure); 
+	  break;
+	case MAG_SYS:
+	  value = PhotSys  (measure, average, secfilt); 
+	  break;
+	case MAG_REL:
+	  value = PhotRel  (measure, average, secfilt); 
+	  break;
+	case MAG_CAL:
+	  value = PhotCal  (measure, average, secfilt, measure, GetPhotcodeEquivbyCode (measure[0].photcode)); 
+	  break;
+	case MAG_AVE:
+	  value = PhotAve  (GetPhotcodeEquivbyCode (measure[0].photcode), average, secfilt); 
+	  break;
+	case MAG_REF:
+	  value = PhotRef  (GetPhotcodeEquivbyCode (measure[0].photcode), average, secfilt, measure); 
+	  break;
+      }
+      break;
+    case MEAS_RA: /* OK */
+      value = average[0].R - measure[0].dR / 3600.0;
+      break;
+    case MEAS_DEC: /* OK */
+      value = average[0].D - measure[0].dD / 3600.0;
+      break;
+    case MEAS_dMAG: /* OK */
+      value = measure[0].dM;
+      break;
+    case MEAS_AIRMASS: /* OK */
+      value = measure[0].airmass;
+      break;
+    case MEAS_EXPTIME: /* OK */
+      value = pow (10.0, measure[0].dt * 0.4);
+      break;
+    case MEAS_PHOTCODE: /* OK */
+      value = measure[0].photcode;
+      break;
+    case MEAS_TIME: /* OK */
+      value = TimeValue (measure[0].t, TimeReference, TimeFormat);
+      break;
+    case MEAS_dR: /* OK */
+      value = measure[0].dR;
+      break;
+    case MEAS_dD: /* OK */
+      value = measure[0].dD;
+      break;
+    case MEAS_FWHM: /* OK */
+      value = 0.01*measure[0].FWx;
+      break;
+    case MEAS_DOPHOT: /* OK */
+      value = measure[0].dophot;
+      break;
+    case MEAS_FLAGS: /* ? */
+      value = measure[0].flags;
+      break;
+    case MEAS_XCCD: /* OK */
+/* I need to perform this conversion for ELIXIR and LONEOS formats on load */      
+# if 0
+      value = measure[0].Xccd;
+# else
+      ra  = average[0].R - measure[0].dR / 3600.0;
+      dec = average[0].D - measure[0].dD / 3600.0;
+      image = MatchImage (measure[0].t, measure[0].photcode);
+      if (image == NULL) break;
+      RD_to_XY (&x, &y, ra, dec, &image[0].coords);
+      value = x;
+# endif
+      break;
+    case MEAS_YCCD: /* OK */
+/* I need to perform this conversion for ELIXIR and LONEOS formats on load */      
+# if 0
+      value = measure[0].Yccd;
+# else
+      ra  = average[0].R - measure[0].dR / 3600.0;
+      dec = average[0].D - measure[0].dD / 3600.0;
+      image = MatchImage (measure[0].t, measure[0].photcode);
+      if (image == NULL) break;
+      RD_to_XY (&x, &y, ra, dec, &image[0].coords);
+      value = y;
+# endif
+      break;
+    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);
+      if (mosaic == NULL) break;
+      RD_to_XY (&x, &y, ra, dec, mosaic);
+      value = x;
+      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 = y;
+      break;
+  }
+  return (value);
+}
+
+/** the mosaic entries do not use the registered mosaic found 
+    by MatchImage (via FindMosaicForImage).  Rather, they use
+    a coordinate frame saved by SetImageSelection 
+**/
Index: /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/dbFields.c
===================================================================
--- /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/dbFields.c	(revision 13453)
+++ /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/dbFields.c	(revision 13454)
@@ -1,2 +1,12 @@
+# include "dvoshell.h"
+
+dbInitField (dbField *field) {
+  field->name = NULL;
+  field->extract = FALSE;
+  field->table = 0;
+  field->ID = 0;
+  field->magMode = 0;
+  field->photcode = NULL;
+}
 
 int GetMagMode (char *string) {
@@ -14,10 +24,10 @@
 }
 
-PhotCode *ParsePhotcodeField (char *field, int *mode, int default) {
+PhotCode *ParsePhotcodeField (char *field, int *mode, int defMode) {
 
   char *tmpstring, *p;
   PhotCode *code;
 
-  *mode = default;
+  *mode = defMode;
 
   p = strchr (field, ':');
@@ -39,8 +49,9 @@
   field->magMode = (M); \
   field->photcode = NULL; \
-  return (TRUE);
+  return (TRUE); }
 
-int ParseMeasureField (dvoField *field, char *fieldName) {
+int ParseMeasureField (dbField *field, char *fieldName) {
 
+  int mode;
   PhotCode *code;
 
@@ -69,5 +80,5 @@
 
   // check for code:mode in photcode name 
-  code = ParsePhotcodeField (&mode, MAG_REL);
+  code = ParsePhotcodeField (fieldName, &mode, MAG_REL);
   if (code == NULL) return (FALSE);
 
@@ -83,9 +94,11 @@
 }
   
-int ParseAverageField (char *fieldName) {
+int ParseAverageField (dbField *field, char *fieldName) {
 
+  int mode;
   PhotCode *code;
 
   field->table = DVO_TABLE_AVERAGE;
+  field->name  = strcreate (fieldName);
 
   if (!strcasecmp (fieldName, "RA"))    ESCAPE (AVE_RA,        MAG_NONE);
@@ -100,5 +113,5 @@
   if (!strcasecmp (fieldName, "dPAR"))  ESCAPE (AVE_PAR_ERR,   MAG_NONE);
   if (!strcasecmp (fieldName, "MAG"))   ESCAPE (AVE_MAG,       MAG_AVE);
-  if (!strcasecmp (fieldName, "dMAG"))  ESCAPE (AVE_dMAG,      MAG_AVE_ERR);
+  if (!strcasecmp (fieldName, "dMAG"))  ESCAPE (AVE_dMAG,      MAG_ERR);
   if (!strcasecmp (fieldName, "NMEAS")) ESCAPE (AVE_NMEAS,     MAG_NONE);
   if (!strcasecmp (fieldName, "NMISS")) ESCAPE (AVE_NMISS,     MAG_NONE);
@@ -114,12 +127,12 @@
 
   // check for code:mode in photcode name 
-  code = ParsePhotcodeField (&mode, MAG_AVE);
+  code = ParsePhotcodeField (fieldName, &mode, MAG_AVE);
   if (code == NULL) return (FALSE);
 
   // need to distinguish phot, sys errors and scatter
   if (mode == MAG_ERR) {
-    field->ID = MEAS_dMAG;
+    field->ID = AVE_dMAG;
   } else {
-    field->ID = MEAS_MAG;
+    field->ID = AVE_MAG;
   }    
   
Index: /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/dbRPN.c
===================================================================
--- /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/dbRPN.c	(revision 13453)
+++ /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/dbRPN.c	(revision 13454)
@@ -2,14 +2,14 @@
 # define DUMPSTACK 0
 
-dvoStack *dbRPN (int argc, char **argv, int *nstack) {
+dbStack *dbRPN (int argc, char **argv, int *nstack) {
   
   int type, Nx, Ny;
   int i, j, Nstack, Nop_stack, NSTACK;
-  dvoStack *stack, *op_stack;
+  dbStack *stack, *op_stack;
 
   /* max total stack size is argc, though should be less, this is safe */
   NSTACK = argc + 5;
-  ALLOCATE (stack, dvoStack, NSTACK);
-  ALLOCATE (op_stack, dvoStack, NSTACK);
+  ALLOCATE (stack, dbStack, NSTACK);
+  ALLOCATE (op_stack, dbStack, NSTACK);
   for (i = 0; i < NSTACK; i++) {
     dbInitStack (&stack[i]);
@@ -173,5 +173,5 @@
   free (op_stack);
   dbFreeStack (&stack[Nstack], NSTACK - Nstack);
-  REALLOCATE (stack, dvoStack, MAX (Nstack, 1));
+  REALLOCATE (stack, dbStack, MAX (Nstack, 1));
   *nstack = Nstack;
 
Index: /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/dbStackMath.c
===================================================================
--- /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/dbStackMath.c	(revision 13453)
+++ /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/dbStackMath.c	(revision 13454)
@@ -1,7 +1,9 @@
-# include "opihi.h"
+# include "dvoshell.h"
 
-dvoStack *dbBinary (dvoStack *V1, dvoStack *V2, char *op, float *fields, int Nfields) {
+dbStack *dbBinary (dbStack *V1, dbStack *V2, char *op, float *fields) {
 
+  int N;
   float M1, M2;
+  dbStack *OUT;
   
   if (V1->type == 'F') {
@@ -19,5 +21,5 @@
   }
 
-  ALLOCATE (OUT, dvoStack, 1);
+  ALLOCATE (OUT, dbStack, 1);
   OUT->type = 'T';
 
@@ -85,7 +87,9 @@
 }
 
-dvoStack *dbUnary (dvoStack *V1, dvoStack *V2, char *op, float *fields, int Nfields) {
+dbStack *dbUnary (dbStack *V1, char *op, float *fields) {
 
+  int N;
   float M1;
+  dbStack *OUT;
 
   if (V1->type == 'F') {
@@ -96,5 +100,5 @@
   }
   
-  ALLOCATE (OUT, dvoStack, 1);
+  ALLOCATE (OUT, dbStack, 1);
   OUT->type = 'T';
 
@@ -133,4 +137,4 @@
   if (!strcmp (op, "isnan"))  {   OUT->Float = isnan(M1);          } 
 
-  return (TRUE);
+  return (OUT);
 }
Index: /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/dbStackOps.c
===================================================================
--- /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/dbStackOps.c	(revision 13453)
+++ /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/dbStackOps.c	(revision 13454)
@@ -1,5 +1,5 @@
 # include "dvoshell.h"
 
-void dbInitStack (StackVar *stack) {
+void dbInitStack (dbStack *stack) {
   stack[0].type   = 0;
   stack[0].name   = NULL;
@@ -7,5 +7,5 @@
 
 // free data for stack entries (free stack explicitly)
-void dbFreeStack (StackVar *stack, int Nstack) {
+void dbFreeStack (dbStack *stack, int Nstack) {
 
   int i;
@@ -20,5 +20,5 @@
 
 /* delete name and data */
-void dbFreeEntry (dvoStack *stack) {
+void dbFreeEntry (dbStack *stack) {
 
   if (stack->type != 'T') return;
Index: /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/mextract.c
===================================================================
--- /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/mextract.c	(revision 13453)
+++ /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/mextract.c	(revision 13454)
@@ -3,13 +3,18 @@
 int mextract (int argc, char **argv) {
   
-  int i, j, k, m, N, N1, NPTS;
+  int i, j, k, m, n, N, N1, Npts, NPTS, last, Nfields, Nreturn, Ncstack, Nstack;
   int param, mode, Nsecfilt;
   char *RegionName, *RegionList, *p;
   double *M1;
+  char **cstack;
+  float *values;
 
-  PhotCode *code;
   Catalog catalog;
   SkyList *skylist;
-  Vector *vec;
+  PhotCode *code;
+  Vector **vec;
+
+  dbField *fields;
+  dbStack *stack;
 
   /* defaults */
@@ -24,35 +29,47 @@
   if (!InitPhotcodes ()) goto escape;
   Nsecfilt = GetPhotcodeNsecfilt ();
+  
+  // init locally static variables (time refs)
+  dbExtractMeasuresInit();
 
-  /* interpret command-line options */
-  SetSelectionParam (0);
+  // remove skyregion options
+  // XXX this needs to explicitly handle -qregion and -skyregion
   if (!SetRegionSelection (&argc, argv, &RegionName, &RegionList)) goto escape;
-  if (!SetPhotSelections (&argc, argv, 1)) goto usage;
 
-  /* interpret required command-line arguments: mextract (value) */
-  if (argc != 2) goto usage;
-  param = GetMeasureParam (argv[1]);
-  if (param == MEAS_ZERO) {
-    if (!GetPhotcodeInfo (argv[1], &code, &mode)) {
-      GetMeasureParam ("help");
-      goto escape;
-    }
-    param = MEAS_MAG;
-    for (p = argv[1]; *p != 0; p++) { 
-      if (*p == '.') *p = ':';
-    }
-  }
-  if (!TestPhotSelections (&code, &mode, MEAS_ZERO)) goto escape;
+  // 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_MEASURE, &last, &Nfields);
+  if (fields == NULL) return (FALSE);
+
+  // parse the remainder of the line as a boolean math expression
+  cstack = isolate_elements (argc-last, &argv[last], &Ncstack);
+  
+  // construct the db Boolean math stack (frees cstack)
+  stack = dbRPN (Ncstack, cstack, &Nstack);
+
+  Nreturn = Nfields; 
+  dbCheckStack (stack, Nstack, DVO_TABLE_MEASURE, &fields, &Nfields);
+  // XXX handle errors
 
   /* load region corresponding to selection above */
   if ((skylist = SelectRegions (RegionName, RegionList)) == NULL) goto escape;
-  if (!SetImageSelection (param, ((RegionName == NULL) && (RegionList == NULL)))) goto escape;
+
+  // XXX is this still needed?
+  // if (!SetImageSelection (param, ((RegionName == NULL) && (RegionList == NULL)))) goto escape;
 
   /* create storage vector */
-  N = 0;
+  ALLOCATE (values, float, Nfields);
+  ALLOCATE (vec, Vector *, Nreturn);
+  for (i = 0; i < Nreturn; i++) {
+    if ((vec[i] = SelectVector (fields[i].name, ANYVECTOR, TRUE)) == NULL) goto escape;
+  }
+
+  Npts = 0;
   NPTS = 1;
-  if ((vec = SelectVector (argv[1], ANYVECTOR, TRUE)) == NULL) goto escape;
 
+  // XXX need to add interrupt test to this loop
   for (i = 0; i < skylist[0].Nregions; i++) {
+    /* lock, load, unlock catalog */
     catalog.filename = skylist[0].filename[i];
     catalog.catflags = LOAD_AVES | LOAD_MEAS | LOAD_SECF;
@@ -69,18 +86,34 @@
 
     for (j = 0; j < catalog.Naverage; j++) {
-      M1 = NULL;
       m = catalog.average[j].offset;
-      M1 = ExtractMeasures (code, mode, &catalog.average[j], &catalog.secfilt[j*Nsecfilt], &catalog.measure[m], &N1, param);
-      for (k = 0; k < N1; k++) {
-	vec[0].elements[N] = M1[k];
-	N++;
-	CHECK_REALLOCATE (vec[0].elements, float, NPTS, N, 2000);
+      for (k = 0; k < catalog.average[j].Nm; k++, m++) {
+
+	// extract the relevant values for this measurement
+	for (n = 0; n < Nfields; n++) {
+	  values[n] = dbExtractMeasures (&catalog.average[j], &catalog.secfilt[j*Nsecfilt], &catalog.measure[m], &fields[n]);
+	}
+	
+	// test the conditional statement
+	if (!dbBooleanCond (stack, Nstack, values)) continue;
+	for (n = 0; n < Nreturn; n++) {
+	  vec[n][0].elements[Npts] = values[n];
+	}
+	Npts++;
+	if (Npts >= NPTS) {
+	  NPTS += 2000;
+	  for (n = 0; n < Nreturn; n++) {
+	    REALLOCATE (vec[n][0].elements, float, NPTS);
+	  }
+	}
       }
-      if (M1 != NULL) free (M1);
     }
     dvo_catalog_free (&catalog);
   }
-  vec[0].Nelements = N;
-  REALLOCATE (vec[0].elements, float, MAX(1,N));
+  for (n = 0; n < Nreturn; n++) {
+    vec[n][0].Nelements = Npts;
+    REALLOCATE (vec[n][0].elements, float, MAX(1,Npts));
+  }
+
+  // XXX free fields and stack 
 
   FreeImageSelection ();
Index: /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/photometry.c
===================================================================
--- /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/photometry.c	(revision 13453)
+++ /branches/kapa-mods-2007-05/Ohana/src/opihi/dvo/photometry.c	(revision 13454)
@@ -174,4 +174,6 @@
 }
 
+// XXX moved to dbFields
+# if (0)
 int GetMagMode (char *string) {
 
@@ -188,4 +190,5 @@
   return (mode);
 }
+# endif
 
 int GetMeasureParam (char *parname) {
Index: /branches/kapa-mods-2007-05/Ohana/src/opihi/include/dvoshell.h
===================================================================
--- /branches/kapa-mods-2007-05/Ohana/src/opihi/include/dvoshell.h	(revision 13453)
+++ /branches/kapa-mods-2007-05/Ohana/src/opihi/include/dvoshell.h	(revision 13454)
@@ -7,12 +7,12 @@
 
 /* magnitude types */
-enum {MAG_NONE, MAG_INST, MAG_CAT, MAG_SYS, MAG_REL, MAG_CAL, MAG_AVE, MAG_REF};
+enum {MAG_NONE, MAG_INST, MAG_CAT, MAG_SYS, MAG_REL, MAG_CAL, MAG_AVE, MAG_REF, MAG_ERR, MAG_CHISQ};
 
-/* measure params */
+/* measure fields */
 enum {MEAS_ZERO, MEAS_RA, MEAS_DEC, MEAS_MAG, MEAS_dMAG, MEAS_MINST, MEAS_MCAT, 
       MEAS_MSYS, MEAS_MREL, MEAS_MCAL, MEAS_PHOTCODE, MEAS_TIME, MEAS_dR, MEAS_dD, 
       MEAS_FWHM, MEAS_DOPHOT, MEAS_XCCD, MEAS_YCCD, MEAS_XMOSAIC, MEAS_YMOSAIC, MEAS_FLAGS, MEAS_EXPTIME, MEAS_AIRMASS};
 
-/* average params */
+/* average fields */
 enum {AVE_ZERO, AVE_RA, AVE_DEC, AVE_RA_ERR, AVE_DEC_ERR, AVE_U_RA, AVE_U_DEC, 
       AVE_U_RA_ERR, AVE_U_DEC_ERR, AVE_PAR, AVE_PAR_ERR, AVE_MAG, AVE_REF, AVE_dMAG, 
@@ -30,5 +30,5 @@
   int magMode;
   PhotCode *photcode;
-} dvoField;
+} dbField;
 
 // db boolean operations
@@ -38,5 +38,5 @@
   int     field;
   float   Float;
-} dvoStack;
+} dbStack;
 
 typedef struct {
@@ -116,3 +116,24 @@
 int           RD_to_XYpic           PROTO((double *x, double *y, double r, double d, Coords *coords, double Rmin, double Rmax, double Rmid, int *leftside));
 
+// dvo DB field functions
+dbField     *dbCmdlineFields        PROTO((int argc, char **argv, int table, int *last, int *nfields));
+dbStack     *dbRPN                  PROTO((int argc, char **argv, int *nstack));
+int          dbCheckStack           PROTO((dbStack *stack, int Nstack, int table, dbField **inFields, int *Nfields));
+int          dbBooleanCond          PROTO((dbStack *inStack, int NinStack, float *fields));
+void         dbInitStack            PROTO((dbStack *stack));
+void 	     dbFreeStack            PROTO((dbStack *stack, int Nstack));
+void 	     dbFreeEntry            PROTO((dbStack *stack));
+
+dbStack     *dbBinary               PROTO((dbStack *V1, dbStack *V2, char *op, float *fields));
+dbStack     *dbUnary                PROTO((dbStack *V1, char *op, float *fields));
+
+int          GetMagMode             PROTO((char *string));
+PhotCode    *ParsePhotcodeField     PROTO((char *field, int *mode, int def));
+int          ParseMeasureField      PROTO((dbField *field, char *fieldName));
+int          ParseAverageField      PROTO((dbField *field, char *fieldName));
+
+double       dbExtractAverages      PROTO((Average *average, SecFilt *secfilt, Measure *measure, dbField *field));
+double       dbExtractMeasures      PROTO((Average *average, SecFilt *secfilt, Measure *measure, dbField *field));
+void         dbExtractMeasuresInit  PROTO(());
+
 # endif
