Index: /trunk/Ohana/src/libdvo/Makefile
===================================================================
--- /trunk/Ohana/src/libdvo/Makefile	(revision 31634)
+++ /trunk/Ohana/src/libdvo/Makefile	(revision 31635)
@@ -36,5 +36,5 @@
 $(DESTINC)/ps1_ref_defs.h
 
-INCS = $(DEFS) $(DESTINC)/dvo.h $(DESTINC)/autocode.h $(DESTINC)/dvo_util.h
+INCS = $(DEFS) $(DESTINC)/dvo.h $(DESTINC)/autocode.h $(DESTINC)/dvo_util.h $(DESTINC)/dvodb.h $(DESTINC)/libdvo_astro.h $(DESTINC)/convert.h
 
 OBJS = \
@@ -73,7 +73,27 @@
 $(SRC)/skyregion_gsc.$(ARCH).o    \
 $(SRC)/skyregion_ops.$(ARCH).o \
+$(SRC)/dvo_set_skyregion.$(ARCH).o \
+$(SRC)/dvo_set_catdir.$(ARCH).o \
 $(SRC)/cmf-ps1-v1-alt.$(ARCH).o \
 $(SRC)/cmf-ps1-sv1-alt.$(ARCH).o \
-$(SRC)/dvo_util.$(ARCH).o
+$(SRC)/dvo_util.$(ARCH).o \
+$(SRC)/dbBooleanCond.$(ARCH).o		\
+$(SRC)/dbCheckStack.$(ARCH).o		\
+$(SRC)/dbCmdlineFields.$(ARCH).o	\
+$(SRC)/dbExtractAverages.$(ARCH).o	\
+$(SRC)/dbExtractMeasures.$(ARCH).o	\
+$(SRC)/dbExtractImages.$(ARCH).o	\
+$(SRC)/dbFields.$(ARCH).o	\
+$(SRC)/dbRPN.$(ARCH).o			\
+$(SRC)/dbStackMath.$(ARCH).o		\
+$(SRC)/dbStackOps.$(ARCH).o 		\
+$(SRC)/coord_systems.$(ARCH).o		\
+$(SRC)/LoadImages.$(ARCH).o		\
+$(SRC)/ImageSelection.$(ARCH).o		\
+$(SRC)/ImageOps.$(ARCH).o		\
+$(SRC)/match_image.$(ARCH).o		\
+$(SRC)/db_utils.$(ARCH).o		\
+$(SRC)/convert.$(ARCH).o
+
 
 # $(SRC)/dvo_convert_panstarrs.$(ARCH).o 
Index: /trunk/Ohana/src/libdvo/include/convert.h
===================================================================
--- /trunk/Ohana/src/libdvo/include/convert.h	(revision 31635)
+++ /trunk/Ohana/src/libdvo/include/convert.h	(revision 31635)
@@ -0,0 +1,28 @@
+// # include "external.h"
+
+#include <ohana.h>
+#include <dvo.h>
+
+# ifndef CONVERT_H
+# define CONVERT_H
+
+/*** time/coord conversion functions not supplied by libohana ***/
+time_t        TimeRef               PROTO((double time, time_t TimeReference, int TimeFormat));
+double        TimeValue             PROTO((time_t time, time_t TimeReference, int TimeFormat));
+
+int           hh_hms                PROTO((double hh, int *hr, int *mn, double *sc));
+int           dd_dms                PROTO((double dd, int *dg, int *mn, double *sc));
+int           hms_format            PROTO((char *line, double value));
+int           dms_format            PROTO((char *line, double value));
+int           hh_hm                 PROTO((double hh, int *hr, double *mn));
+int           day_to_sec            PROTO((char *string, time_t *second));
+int           hms_to_sec            PROTO((char *string, time_t *second));
+char         *ohana_sec_to_hms      PROTO((time_t second));
+char         *ohana_sec_to_day      PROTO((time_t second));
+
+char         *meade_deg_to_str      PROTO((double deg));
+char         *meade_ra_to_str       PROTO((double deg));
+char         *meade_dec_to_str      PROTO((double deg));
+char         *strptime              PROTO((const char *s, const char *format, struct tm *tm));
+
+# endif
Index: /trunk/Ohana/src/libdvo/include/dvo.h
===================================================================
--- /trunk/Ohana/src/libdvo/include/dvo.h	(revision 31634)
+++ /trunk/Ohana/src/libdvo/include/dvo.h	(revision 31635)
@@ -1,8 +1,11 @@
+# ifndef DVO_H
+# define DVO_H
+
 # include <ohana.h>
 # include <gfitsio.h>
 # include <autocode.h>
 
-# ifndef DVO_H
-# define DVO_H
+# include <libdvo_astro.h>
+# include <dvodb.h>
 
 /* DVO table modes */
@@ -501,4 +504,10 @@
 SkyList   *SkyListChildrenByBounds_List PROTO((SkyList *table, int depth, double Rmin, double Rmax, double Dmin, double Dmax));
 
+int set_skyregion(double Rs, double Re, double Ds, double De);
+int get_skyregion (double *Rs, double *Re, double *Ds, double *De);
+
+void dvo_set_catdir(char *catdir);
+char *dvo_get_catdir();
+
 /* dvo-specific sorting functions */
 void sortave (Average *ave, off_t N);
@@ -508,3 +517,9 @@
 void sort_regions (SkyRegion *region, off_t N);
 
+#ifdef MOVED_TO_LIBOHANA
+int  print_error(void);
+int  init_error(void);
+int  push_error(char *);
+#endif
+
 # endif
Index: /trunk/Ohana/src/libdvo/include/dvodb.h
===================================================================
--- /trunk/Ohana/src/libdvo/include/dvodb.h	(revision 31635)
+++ /trunk/Ohana/src/libdvo/include/dvodb.h	(revision 31635)
@@ -0,0 +1,337 @@
+# ifndef DVODB_H
+# define DVODB_H
+
+// to get definition of Graphdata
+# include "kapa.h"
+
+typedef enum {
+  DB_STACK_NONE  = 0,
+  DB_STACK_INT   = 0x01,
+  DB_STACK_FIELD = 0x02,
+  DB_STACK_TEMP  = 0x04,
+  DB_STACK_VALUE = 0x08,
+  DB_STACK_CLOSE_PAR = 0x10,
+  DB_STACK_OPEN_PAR,
+  DB_STACK_LOGIC,
+  DB_STACK_COMPARE,
+  DB_STACK_BITWISE,
+  DB_STACK_SUM,
+  DB_STACK_MULTIPLY,
+  DB_STACK_POWER,
+  DB_STACK_UNARY,
+} dbStackTypes;
+
+/* magnitude types */
+enum {MAG_NONE, 
+      MAG_INST, 
+      MAG_CAT, 
+      MAG_APER, 
+      MAG_SYS, 
+      MAG_REL, 
+      MAG_CAL, 
+      MAG_AVE, 
+      MAG_REF, 
+      MAG_ERR, 
+      MAG_AVE_ERR, 
+      MAG_PHOT_FLAGS, 
+      MAG_CHISQ,
+      MAG_NCODE,
+      MAG_NPHOT,
+};
+
+/* measure fields */
+enum {MEAS_ZERO, 
+      MEAS_GLON, 
+      MEAS_GLAT, 
+      MEAS_GLON_AVE, 
+      MEAS_GLAT_AVE,
+      MEAS_ELON, 
+      MEAS_ELAT, 
+      MEAS_ELON_AVE, 
+      MEAS_ELAT_AVE,
+      MEAS_RA, 
+      MEAS_DEC, 
+      MEAS_RA_AVE, 
+      MEAS_DEC_AVE,
+      MEAS_RA_AVE_ERR, 
+      MEAS_DEC_AVE_ERR, 
+      MEAS_U_RA, 
+      MEAS_U_DEC, 
+      MEAS_U_RA_ERR, 
+      MEAS_U_DEC_ERR, 
+      MEAS_PAR, 
+      MEAS_PAR_ERR, 
+      MEAS_RA_OFFSET, 
+      MEAS_DEC_OFFSET, 
+      MEAS_RA_FIT_OFFSET, 
+      MEAS_DEC_FIT_OFFSET, 
+      MEAS_RA_OFFSET_ERR, 
+      MEAS_DEC_OFFSET_ERR, 
+      MEAS_CHISQ_POS, 
+      MEAS_CHISQ_PM,  
+      MEAS_CHISQ_PAR, 
+      MEAS_TMEAN, 
+      MEAS_TRANGE, 
+      MEAS_NMEAS, 
+      MEAS_NMISS, 
+      MEAS_NPOS, 
+      MEAS_OBJ_FLAGS, 
+      MEAS_MAG, 
+      MEAS_MINST, 
+      MEAS_MCAT, 
+      MEAS_MSYS, 
+      MEAS_MREL, 
+      MEAS_MCAL, 
+      MEAS_EXPTIME, 
+      MEAS_AIRMASS, 
+      MEAS_ALT, 
+      MEAS_AZ, 
+      MEAS_PHOTCODE, 
+      MEAS_PHOTCODE_EQUIV, 
+      MEAS_TIME, 
+      MEAS_FWHM, 
+      MEAS_FWHM_MAJ, 
+      MEAS_FWHM_MIN, 
+      MEAS_THETA, 
+      MEAS_POSANGLE, 
+      MEAS_PLATESCALE, 
+      MEAS_MXX, 
+      MEAS_MXY, 
+      MEAS_MYY, 
+      MEAS_DOPHOT, 
+      MEAS_DB_FLAGS, 
+      MEAS_PHOT_FLAGS, 
+      MEAS_XCCD, 
+      MEAS_YCCD, 
+      MEAS_XCCD_ERR, 
+      MEAS_YCCD_ERR, 
+      MEAS_POS_SYS_ERR, 
+      MEAS_XMOSAIC, 
+      MEAS_YMOSAIC, 
+      MEAS_SKY, 
+      MEAS_dSKY, 
+      MEAS_DET_ID, 
+      MEAS_OBJ_ID, 
+      MEAS_CAT_ID, 
+      MEAS_IMAGE_ID, 
+      MEAS_PSF_QF, 
+      MEAS_PSF_QF_PERFECT, 
+      MEAS_PSF_CHISQ, 
+      MEAS_PSF_NDOF,
+      MEAS_PSF_NPIX,
+      MEAS_CR_NSIGMA, 
+      MEAS_EXT_NSIGMA, 
+      MEAS_EXTERN_ID,
+};
+
+/* average fields */
+enum {AVE_ZERO, 
+      AVE_RA, 
+      AVE_DEC, 
+      AVE_RA_ERR, 
+      AVE_DEC_ERR, 
+      AVE_GLON, 
+      AVE_GLAT, 
+      AVE_ELON, 
+      AVE_ELAT, 
+      AVE_U_RA, 
+      AVE_U_DEC, 
+      AVE_U_RA_ERR, 
+      AVE_U_DEC_ERR, 
+      AVE_PAR, 
+      AVE_PAR_ERR, 
+      AVE_CHISQ_POS, 
+      AVE_CHISQ_PM, 
+      AVE_CHISQ_PAR, 
+      AVE_TMEAN,
+      AVE_TRANGE, 
+      AVE_Xp, 
+      AVE_NMEAS, 
+      AVE_NMISS, 
+      AVE_NPOS, 
+      AVE_NPHOT, 
+      AVE_NCODE, 
+      AVE_MAG, 
+      AVE_dMAG, 
+      AVE_Xm, 
+      AVE_OBJ_FLAGS, 
+      AVE_TYPE, 
+      AVE_TYPEFRAC,
+      AVE_OBJID,
+      AVE_CATID,
+      AVE_EXTID_HI,
+      AVE_EXTID_LO,
+};
+
+enum {IMAGE_ZERO, 
+      IMAGE_RA, 
+      IMAGE_DEC, 
+      IMAGE_GLON, 
+      IMAGE_GLAT, 
+      IMAGE_ELON, 
+      IMAGE_ELAT, 
+      IMAGE_XM, 
+      IMAGE_AIRMASS, 
+      IMAGE_MCAL, 
+      IMAGE_dMCAL, 
+      IMAGE_PHOTCODE, 
+      IMAGE_TIME, 
+      IMAGE_FWHM, 
+      IMAGE_FWHM_MEDIAN, 
+      IMAGE_EXPTIME, 
+      IMAGE_NSTAR, 
+      IMAGE_NCAL, 
+      IMAGE_SKY, 
+      IMAGE_FLAGS, 
+      IMAGE_CCDNUM, 
+      IMAGE_NX_PIX, 
+      IMAGE_NY_PIX, 
+      IMAGE_THETA, 
+      IMAGE_SKEW, 
+      IMAGE_SCALE, 
+      IMAGE_DSCALE, 
+      IMAGE_APRESID,
+      IMAGE_DAPRESID,
+      IMAGE_SIDTIME,
+      IMAGE_LATITUDE,
+      IMAGE_DET_LIMIT,
+      IMAGE_SAT_LIMIT,
+      IMAGE_CERROR,
+      IMAGE_FWHM_MAJ,
+      IMAGE_FWHM_MIN,
+      IMAGE_FWHM_MAJ_MEDIAN,
+      IMAGE_FWHM_MIN_MEDIAN,
+      IMAGE_TRATE,
+      IMAGE_IMAGE_ID,
+      IMAGE_EXTERN_ID,
+      IMAGE_SOURCE_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,
+      IMAGE_X_ERR_SYS,
+      IMAGE_Y_ERR_SYS,
+      IMAGE_MAG_ERR_SYS,
+      IMAGE_NFIT_PHOTOM,
+      IMAGE_NFIT_ASTROM,
+      IMAGE_NLINK_PHOTOM,
+      IMAGE_NLINK_ASTROM
+};
+
+enum {DVO_TABLE_AVERAGE, DVO_TABLE_MEASURE, DVO_TABLE_IMAGE};
+enum {DVO_DB_CMDLINE_ERROR, DVO_DB_CMDLINE_IS_END, DVO_DB_CMDLINE_IS_WHERE, DVO_DB_CMDLINE_IS_MATCH}; 
+
+// options for selecting the ra,dec limits of the db selections
+typedef struct {
+  char *name;
+  char *list;
+  int useDisplay;
+  int useSkyregion;
+} SkyRegionSelection;
+
+// a single db field 
+typedef struct {
+  char *name;
+  int extract;
+  int table;
+  int ID;
+  int magMode;
+  char type;
+  PhotCode *photcode;
+} dbField;
+
+// db boolean operations
+typedef struct {
+  char   *name;
+  char    type;
+  int     field;
+  // opihi_flt FltValue;
+  // opihi_int IntValue;
+  double FltValue;
+  int IntValue;
+} dbStack;
+
+typedef struct {
+  // opihi_flt Flt;
+  // opihi_int Int;
+  double Flt;
+  int Int;
+} dbValue;
+
+Image        *LoadImagesDVO         PROTO((off_t *Nimage));
+void          FreeImagesDVO         PROTO((Image *images));
+Image        *MatchImageDVO         PROTO((unsigned int time, short int source, unsigned int imageID));
+Coords       *MatchMosaic           PROTO((unsigned int time, short int source));
+int           GetTimeSelection      PROTO((time_t *tz, time_t *te));
+int           GetTimeFormat         PROTO((time_t *TimeReference, int *TimeFormat));
+double        TimeValue (time_t time, time_t TimeReference, int TimeFormat);
+
+void          image_subset          PROTO((Image *image, off_t Nimage, off_t **Subset, off_t *Nsubset, SkyRegionSelection *selection, unsigned long int tzero, double trange, int TimeSelect));
+off_t         match_image_subset    PROTO((Image *image, off_t *subset, off_t Nsubset, unsigned int T, short int S));
+
+// dvo DB field functions
+dbField     *dbCmdlineFields        PROTO((int argc, char **argv, int table, int *last, int *nfields));
+int          dbCmdlineConditions    PROTO((int argc, char **argv, int first, int *nextField));
+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, dbValue *fields));
+void         dbInitStack            PROTO((dbStack *stack));
+void 	     dbFreeStack            PROTO((dbStack *stack, int Nstack));
+void 	     dbFreeEntry            PROTO((dbStack *stack));
+void         dbFreeTempEntry        PROTO((dbStack *stack));
+
+dbStack     *dbBinary               PROTO((dbStack *V1, dbStack *V2, char *op, dbValue *fields));
+dbStack     *dbUnary                PROTO((dbStack *V1, char *op, dbValue *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));
+int          ParseImageField        PROTO((dbField *field, char *fieldName));
+
+dbValue      dbExtractAverages      PROTO((Average *average, SecFilt *secfilt, Measure *measure, dbField *field));
+dbValue      dbExtractMeasures      PROTO((Average *average, SecFilt *secfilt, Measure *measure, dbField *field));
+dbValue      dbExtractImages        PROTO((Image *image, off_t Nimage, off_t N, dbField *field));
+
+void 	     dbInitField            PROTO((dbField *field));
+void 	     dbFreeFields           PROTO((dbField *fields, int Nfields));
+int          dbAstroRegionLimits    PROTO((dbStack **stack, int *nstack, SkyRegionSelection *selection, int table));
+char        *strfloat               PROTO((float value));
+
+void FreeImageSelection (void);
+
+void FreeSkyRegionSelection (SkyRegionSelection *selection);
+int wordhash (char *word);
+
+int dbExtractMeasuresInitTransform (CoordTransformSystem target);
+int dbExtractMeasuresInitAve (void);
+int dbExtractMeasuresInitMeas (void);
+int dbExtractMeasuresInit (void);
+
+int dbExtractAveragesInitTransform (CoordTransformSystem target);
+int dbExtractAveragesInit (void);
+
+int dbExtractImagesInitTransform (CoordTransformSystem target);
+int dbExtractImagesInit (void);
+int dbExtractImagesReset (void);
+
+// Some values used by code moved to libdvo from opihi.
+enum {OPIHI_FLT, OPIHI_INT};
+#define opihi_flt double
+#define opihi_int int
+
+int GetGraphdata PROTO((Graphdata *data, int *kapa, char *name));
+
+# endif
Index: /trunk/Ohana/src/libdvo/include/libdvo_astro.h
===================================================================
--- /trunk/Ohana/src/libdvo/include/libdvo_astro.h	(revision 31635)
+++ /trunk/Ohana/src/libdvo/include/libdvo_astro.h	(revision 31635)
@@ -0,0 +1,36 @@
+#ifdef notdef
+# include "external.h"
+# include "shell.h"
+# include "dvomath.h"
+# include "convert.h"
+# include "display.h"
+# include "data.h"
+#endif
+
+# ifndef ASTRO_H
+# define ASTRO_H
+
+void InitAstro (void);
+void FreeAstro (void);
+
+typedef struct {
+  int    isIdentity;	      // identity transformation 
+  double phi;		      // saved in radians
+  double Xo;		      // saved in radians
+  double xo;		      // saved in degrees
+  double sin_phi_cos_Xo;      // pre-computed values
+  double sin_phi_sin_Xo;      // pre-computed values
+  double cos_phi_cos_Xo;      // pre-computed values
+  double cos_phi_sin_Xo;      // pre-computed values
+  double cos_phi;	      // pre-computed values
+  double sin_phi;	      // pre-computed values
+  double cos_Xo;	      // pre-computed values
+  double sin_Xo;	      // pre-computed values
+} CoordTransform;
+
+typedef enum {COORD_NONE, COORD_CELESTIAL, COORD_GALACTIC, COORD_ECLIPTIC} CoordTransformSystem;
+
+CoordTransform *InitTransform (CoordTransformSystem input, CoordTransformSystem output);
+int ApplyTransform (double *x, double *y, double X, double Y, CoordTransform *transform);
+
+# endif
Index: /trunk/Ohana/src/libdvo/src/ImageOps.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/ImageOps.c	(revision 31635)
+++ /trunk/Ohana/src/libdvo/src/ImageOps.c	(revision 31635)
@@ -0,0 +1,133 @@
+# include "dvo.h"
+# include "dvodb.h"
+
+void image_subset (Image *image, off_t Nimage, off_t **Subset, off_t *Nsubset,
+		   SkyRegionSelection *selection, 
+		   unsigned long int tzero, double trange, int TimeSelect) 
+{
+
+  int j, flipped, status, InPic;
+  off_t i, n, *subset;
+  int npts;
+  double r, d, X, Y, x[4], y[4], Rmin, Rmax, Rmid;
+  Graphdata graph;
+  SkyRegion patch;
+
+  Rmin = Rmax = Rmid = 0;
+
+  if (selection->useDisplay) {
+    if (!GetGraphdata (&graph, NULL, NULL)) {
+      gprint (GP_ERR, "region display not available\n");
+      return;
+    }
+    Rmin = graph.coords.crval1 - 182.0;
+    Rmax = graph.coords.crval1 + 182.0;
+    Rmid = 0.5*(Rmin + Rmax);
+    BuildChipMatch (image, Nimage);
+  }
+
+  patch.Rmin = 0;
+  patch.Rmax = 0;
+  patch.Dmin = 0;
+  patch.Dmax = 0;
+  if (selection->useSkyregion) {
+    double Rs, Re, Ds, De;
+    get_skyregion (&Rs, &Re, &Ds, &De);
+    patch.Rmin = Rs;
+    patch.Rmax = Re;
+    patch.Dmin = Ds;
+    patch.Dmax = De;
+    Rmin = patch.Rmin - 182.0;
+    Rmax = patch.Rmax + 182.0;
+    Rmid = 0.5*(Rmin + Rmax);
+  }
+
+  if (trange < 0) {
+    tzero = tzero + trange;
+    trange = fabs (trange);
+  }
+
+  npts = 200;
+  ALLOCATE (subset, off_t, npts);
+  n = 0;
+  for (i = 0; i < Nimage; i++) {
+    if (TimeSelect && ((image[i].tzero < tzero) || (image[i].tzero+image[i].trate*image[i].NY > tzero + trange))) continue;
+    if (selection->useDisplay) {
+      if (!FindMosaicForImage (image, Nimage, i)) continue;
+      // first check if region center is in image
+      status = RD_to_XY (&X, &Y, Rmid, graph.coords.crval2, &image[i].coords);
+      if (status && (X >= 0) && (X < image[i].NX) && (Y >= 0) && (Y < image[i].NY)) goto in_region;
+
+      /* project this image to screen display coords */
+      x[0] = 0;           y[0] = 0;
+      x[1] = image[i].NX; y[1] = 0;
+      x[2] = image[i].NX; y[2] = image[i].NY;
+      x[3] = 0;           y[3] = image[i].NY;
+      InPic = flipped = FALSE;
+      for (j = 0; j < 4; j++) {
+	XY_to_RD (&r, &d, x[j], y[j], &image[i].coords);
+	/* use same side of 0,360 boundary for all corners */
+	if ((j == 0) && (r < Rmin)) flipped = TRUE; 
+	if ((j == 0) && (r > Rmax)) flipped = TRUE; 
+	r = ohana_normalize_angle (r);
+	while (flipped && (r < Rmid)) r+= 360.0;
+	while (flipped && (r > Rmid)) r-= 360.0;
+	status = RD_to_XY (&X, &Y, r, d, &graph.coords);
+	if (!status) continue;
+	if (X < graph.xmin) continue;
+	if (X > graph.xmax) continue;
+	if (Y < graph.ymin) continue;
+	if (Y > graph.ymax) continue;
+	goto in_region;
+	/** we miss any images which surround the region.  we are also
+	    missing the DIS images for which the corners don't touch
+	    the region, but which are needed for WRP images with
+	    corners touching the region **/
+      }
+      continue;
+    }
+    if (selection->useSkyregion) {
+      if (!FindMosaicForImage (image, Nimage, i)) continue;
+      /* project this image to screen display coords */
+      x[0] = 0;           y[0] = 0;
+      x[1] = image[i].NX; y[1] = 0;
+      x[2] = image[i].NX; y[2] = image[i].NY;
+      x[3] = 0;           y[3] = image[i].NY;
+      InPic = flipped = FALSE;
+      for (j = 0; j < 4; j++) {
+	XY_to_RD (&r, &d, x[j], y[j], &image[i].coords);
+	/* use same side of 0,360 boundary for all corners */
+	if ((j == 0) && (r < Rmin)) flipped = TRUE; 
+	if ((j == 0) && (r > Rmax)) flipped = TRUE; 
+	while (flipped && (r < Rmid)) r+= 360.0;
+	while (flipped && (r > Rmid)) r-= 360.0;
+	if (r < patch.Rmin) continue;
+	if (r > patch.Rmax) continue;
+	if (d < patch.Dmin) continue;
+	if (d > patch.Dmax) continue;
+	goto in_region;
+	/** we miss any images which surround the region.  we are also
+	    missing the DIS images for which the corners don't touch
+	    the region, but which are needed for WRP images with
+	    corners touching the region **/
+      }
+      continue;
+    }
+  in_region:
+    subset[n] = i;
+    n++;
+    if (n > npts - 1) {
+      npts += 200;
+      REALLOCATE (subset, off_t, npts);
+    }
+  }
+
+  REALLOCATE (subset, off_t, MAX (n, 1));
+  *Subset = subset;
+  *Nsubset = n;
+  return;
+}
+
+/* this routine fills the subset index with the list of selected images.
+   images may be selected on the basis of the region or on a time range 
+*/
Index: /trunk/Ohana/src/libdvo/src/ImageSelection.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/ImageSelection.c	(revision 31635)
+++ /trunk/Ohana/src/libdvo/src/ImageSelection.c	(revision 31635)
@@ -0,0 +1,77 @@
+# include "dvo.h"
+
+/* db image table */
+static Image *image = NULL;
+static off_t *subset = NULL;
+static off_t Nimage = 0;
+static off_t Nsubset = 0;
+static Coords mosaic;
+
+/* load images based on parameters and region, etc */
+int SetImageSelection (int mosaicMode, SkyRegionSelection *selection) {
+
+  int TimeSelect;
+  time_t tzero, tend;
+
+  image = NULL;
+  subset = NULL;
+  
+  TimeSelect = GetTimeSelection (&tzero, &tend);
+
+  if (mosaicMode) {
+      /* mosaic defines a frame with 0,0 at the mosaic center, and 1 arcsec / pixel */
+      mosaic.crpix1 = mosaic.crpix2 = 0.0;
+      mosaic.cdelt1 = mosaic.cdelt2 = 1.0 / 3600;
+      mosaic.pc1_1  = mosaic.pc2_2  = 1.0;
+      mosaic.pc1_2  = mosaic.pc2_1  = 0.0;
+      mosaic.Npolyterms = 0;
+      strcpy (mosaic.ctype, "RA---SIN");
+  }
+
+  if ((image = LoadImagesDVO (&Nimage)) == NULL) return (FALSE);
+  BuildChipMatch (image, Nimage);
+  image_subset (image, Nimage, &subset, &Nsubset, selection, tzero, (double) tend - tzero, TimeSelect);
+  sort_image_subset (image, subset, Nsubset);
+  return (TRUE);
+}
+
+/* free loaded images */
+void FreeImageSelection () {
+  if (image != NULL) FreeImagesDVO(image);
+  if (subset != NULL) free (subset);
+  image = NULL;
+  subset = NULL;
+  return;
+}
+
+Image *MatchImageDVO (unsigned int time, short int source, unsigned int imageID) { 
+
+  int m = -1;
+
+  if ((imageID != 0) && (imageID < Nimage)) {
+    // imageID is in range for the array of images. If the table is still in order and
+    // no images have been deleted the index of the image we are looking for will be imageID - 1
+    // If this is the case, we have it. Otherwise we'll have to go search for it below
+    int guess = (int) imageID - 1;
+    if (image[guess].imageID == imageID) {
+        m = guess;
+    }
+  } 
+  if (m == -1) {
+    m = match_image_subset (image, subset, Nsubset, time, source);
+  }
+  if (m == -1) return (NULL);
+  if (!FindMosaicForImage (image, Nimage, m)) return (NULL);
+  return (&image[m]);
+}
+
+Coords *MatchMosaic (unsigned int time, short int source) { 
+
+  int m;
+
+  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);
+}
Index: /trunk/Ohana/src/libdvo/src/LoadImages.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/LoadImages.c	(revision 31635)
+++ /trunk/Ohana/src/libdvo/src/LoadImages.c	(revision 31635)
@@ -0,0 +1,98 @@
+# include "dvo.h"
+# include "dvodb.h"
+
+// XXX: Maybe make this a command line option
+int dvoUseImageCache = 1;
+
+static char *lastFilename = NULL;
+static time_t lastModified = 0;
+static Image *imageCache = NULL;
+static off_t cacheNimage = 0;
+
+static time_t getLastModified(char *filename);
+
+Image *LoadImagesDVO (off_t *Nimage) {
+
+  int status;
+  char *catdir, filename[256];
+  Image *image;
+  FITS_DB db;
+  
+  /* VarConfig ("IMAGE_CATALOG", "%s", filename); */
+
+  catdir = dvo_get_catdir ();
+  sprintf (filename, "%s/Images.dat", catdir);
+
+  if (lastFilename) {
+    if (dvoUseImageCache && !strcmp(lastFilename, filename)) {
+      // Make sure the file hasn't changed since we loaded it
+      if (getLastModified(filename) == lastModified) {
+        *Nimage = cacheNimage;
+        return  imageCache;
+      }
+    }
+    free(lastFilename);
+    lastFilename = NULL;
+    free(imageCache);
+    imageCache = NULL;
+    cacheNimage = 0;
+    lastModified = 0;
+  }
+
+
+  gfits_db_init (&db);
+  db.lockstate = LCK_SOFT;
+  db.timeout   = 120.0;
+
+  if (!gfits_db_lock (&db, filename)) {
+    gprint (GP_ERR, "error opening image catalog %s (1)\n", filename);
+    return (NULL);
+  }
+
+  if (db.dbstate == LCK_EMPTY) {
+    gprint (GP_ERR, "note: image catalog is empty\n");
+    ALLOCATE (image, Image, 1);
+    *Nimage = 1;
+    return (image);
+  }
+
+  status = dvo_image_load (&db, TRUE, FALSE);
+  gfits_db_close (&db);
+
+  if (!status) {
+    gprint (GP_ERR, "problem loading image database table\n");
+    return (NULL);
+  }
+
+  image = gfits_table_get_Image (&db.ftable, Nimage, &db.swapped);
+  if (!image) {
+    fprintf (stderr, "ERROR: failed to read images\n");
+    return (NULL);
+  }
+  if (dvoUseImageCache && image) {
+    cacheNimage = *Nimage;
+    imageCache = image;
+    lastFilename = strdup(filename);
+    lastModified = getLastModified(filename);
+  }
+
+  return (image);
+}
+
+static time_t getLastModified(char *filename) {
+  struct stat statbuf;
+  if (!stat(filename, &statbuf)) {
+    return statbuf.st_mtime;
+  } else {
+    return 0;
+  }
+}
+
+void FreeImagesDVO(Image *images) {
+  if (!dvoUseImageCache && (images != NULL)) {
+    free(images);
+  } else {
+    // defer free until next LoadImages with a different or modified Images.dat
+  }
+}
+
Index: /trunk/Ohana/src/libdvo/src/convert.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/convert.c	(revision 31635)
+++ /trunk/Ohana/src/libdvo/src/convert.c	(revision 31635)
@@ -0,0 +1,305 @@
+# include "convert.h"
+# define _XOPEN_SOURCE /* glibc2 (strptime) needs this */
+# include <time.h>
+
+/** additional time / coordinate conversions not supplied by libohana **/
+
+int hh_hms (double hh, int *hr, int *mn, double *sc) {
+
+  int N, flag;
+
+  flag = SIGN(hh);
+  hh = fabs(hh);
+
+  // rationalize hh to range -24.0 < hh < 24.0
+  if (hh >= 24.0) {
+    N = (int)(hh/24.0);
+    hh -= 24.0*N;
+  }
+
+  *hr = (int) hh;
+  *mn = (int) 60*(hh - *hr);
+  *sc = 3600.0*(hh - *hr - *mn / 60.0);
+  if (*sc > 59.99) {
+    *sc = 0.0;
+    *mn += 1.0;
+  }
+  *hr *= flag;
+  return (TRUE);
+}
+ 
+int dd_dms (double dd, int *dg, int *mn, double *sc) {
+
+  int flag;
+
+  flag = SIGN(dd);
+  dd = fabs (dd);
+  *dg = (int) dd;
+  *mn = (int) 60*(dd - *dg);
+  *sc = 3600.0*(dd - *dg - *mn/60.0);
+  if (*sc > 59.99) {
+    *sc = 0;
+    *mn += 1.0;
+  }
+  *dg *= flag;
+  return (TRUE);
+}
+ 
+int hms_format (char *line, double value) {
+
+  int hr, mn;
+  double sc;
+
+  hh_hms (value, &hr, &mn, &sc);
+  hr = (int) value;
+  if (isnan (value))
+    sprintf (line, "xx:xx:xx.xx");
+  else {
+    if (value < 0) {
+      sprintf (line, "-%02d:%02d:%05.2f", abs(hr), mn, sc);
+    } else {
+      sprintf (line, "+%02d:%02d:%05.2f", hr, mn, sc);
+    }
+  }      
+  return (TRUE);
+}
+
+int dms_format (char *line, double value) {
+
+  int dg, mn;
+  double sc;
+
+  dd_dms (value, &dg, &mn, &sc);
+  if (value < 0) {
+    sprintf (line, "-%02d:%02d:%05.2f", abs(dg), mn, sc);
+  } else {
+    sprintf (line, "+%02d:%02d:%05.2f", dg, mn, sc);
+  }
+  return (TRUE);
+}
+
+/***** convert 00:00:00 or 00:00 to 0 - 86400 ****/
+int hms_to_sec (char *string, time_t *second) {
+  
+  char *p;
+  struct tm time;
+
+  p = strptime (string, "%H:%M:%S", &time);
+  if (p != NULL) goto valid;
+
+  p = strptime (string, "%H:%M", &time);
+  if (p != NULL) goto valid;
+
+  return (FALSE);
+    
+valid:
+  if (*p) return (FALSE);
+  *second = time.tm_hour*3600 + time.tm_min*60 + time.tm_sec;
+  return (TRUE);
+}
+
+/***** convert Mon[@00:00:00] or 00:00 to 0 - 86400*7 ****/
+int day_to_sec (char *string, time_t *second) {
+  
+  char *p;
+  struct tm time;
+
+  bzero (&time, sizeof(time));
+  p = strptime (string, "%A@%H:%M:%S", &time);
+  if (p != NULL) goto valid;
+
+  p = strptime (string, "%A@%H:%M", &time);
+  if (p != NULL) goto valid;
+
+  p = strptime (string, "%A@%H", &time);
+  if (p != NULL) goto valid;
+
+  p = strptime (string, "%A", &time);
+  if (p != NULL) goto valid;
+
+  return (FALSE);
+
+valid:
+  if (*p) return (FALSE);
+  *second = time.tm_wday*86400 + time.tm_hour*3600 + time.tm_min*60 + time.tm_sec;
+  return (TRUE);
+}
+
+/***** convert seconds to HH:MM:SS ****/
+char *ohana_sec_to_hms (time_t second) {
+  
+  struct tm *gmt;
+  char *line;
+
+  ALLOCATE (line, char, 64);
+  gmt   = gmtime (&second);
+  sprintf (line, "%02d:%02d:%02d", gmt[0].tm_hour, gmt[0].tm_min, gmt[0].tm_sec); 
+  return (line);
+}
+
+/***** convert seconds to Day@HH:MM:SS ****/
+char *ohana_sec_to_day (time_t second) {
+  
+  struct tm *gmt;
+  char *line;
+
+  ALLOCATE (line, char, 64);
+  gmt   = gmtime (&second);
+  switch (gmt[0].tm_wday) {
+    case 0:
+      sprintf (line, "Sun@%02d:%02d:%02d", gmt[0].tm_hour, gmt[0].tm_min, gmt[0].tm_sec); 
+      break;
+    case 1:
+      sprintf (line, "Mon@%02d:%02d:%02d", gmt[0].tm_hour, gmt[0].tm_min, gmt[0].tm_sec); 
+      break;
+    case 2:
+      sprintf (line, "Tue@%02d:%02d:%02d", gmt[0].tm_hour, gmt[0].tm_min, gmt[0].tm_sec); 
+      break;
+    case 3:
+      sprintf (line, "Wed@%02d:%02d:%02d", gmt[0].tm_hour, gmt[0].tm_min, gmt[0].tm_sec); 
+      break;
+    case 4:
+      sprintf (line, "Thu@%02d:%02d:%02d", gmt[0].tm_hour, gmt[0].tm_min, gmt[0].tm_sec); 
+      break;
+    case 5:
+      sprintf (line, "Fri@%02d:%02d:%02d", gmt[0].tm_hour, gmt[0].tm_min, gmt[0].tm_sec); 
+      break;
+    case 6:
+      sprintf (line, "Sat@%02d:%02d:%02d", gmt[0].tm_hour, gmt[0].tm_min, gmt[0].tm_sec); 
+      break;
+  }
+  return (line);
+}
+
+int hh_hm (double hh, int *hr, double *mn) {
+
+  int flag;
+
+  flag = SIGN(hh);
+  hh = fabs (hh);
+
+  *mn = 60.0*(hh - (int)hh);
+  *hr = (int) hh;
+  *hr *= flag;
+  return (TRUE);
+}
+
+char *meade_deg_to_str (double deg) {
+
+  int hr;
+  double mn;
+  char *line;
+
+  ALLOCATE (line, char, 16);
+
+  hh_hm (deg, &hr, &mn);
+
+  sprintf (line, "%03d:%04.1f", abs(hr), mn);
+  return (line);
+}
+
+char *meade_ra_to_str (double deg) {
+
+  int hr;
+  double mn;
+  char *line;
+
+  ALLOCATE (line, char, 16);
+
+  hh_hm (deg/15.0, &hr, &mn);
+
+  sprintf (line, "%02d:%04.1f", abs(hr), mn);
+  return (line);
+}
+
+char *meade_dec_to_str (double deg) {
+
+  int hr;
+  double mn;
+  char *line;
+
+  ALLOCATE (line, char, 16);
+
+  hh_hm (deg, &hr, &mn);
+
+  if (deg < 0) {
+    sprintf (line, "-%02d:%04.1f", abs(hr), mn);
+  } else {
+    sprintf (line, "+%02d:%04.1f", hr, mn);
+  }      
+  return (line);
+}
+
+/* convert UNIX time to a value referenced to the TimeReference in the given unit */
+double TimeValue (time_t time, time_t TimeReference, int TimeFormat) {
+
+  double value, dt;
+
+  dt = (time > TimeReference) ? (time - TimeReference) : -1 * (double)(TimeReference - time);
+  switch (TimeFormat) {
+  case TIME_JD:
+    value = time / 86400.0 + 2440587.5;
+    break;
+  case TIME_MJD:
+    value = time / 86400.0 + 40587.0;
+    break;
+  case TIME_DAYS:
+    value = dt / 86400.0;
+    break;
+  case TIME_HOURS:
+    value = dt / 3600.0;
+    break;
+  case TIME_MINUTES:
+    value = dt / 60.0;
+    break;
+  case TIME_SECONDS:
+  default:
+    value = dt;
+    break;
+  }
+  return (value);
+}
+  
+/* convert time value referenced to the TimeReference in the given unit to UNIX time */
+time_t TimeRef (double value, time_t TimeReference, int TimeFormat) {
+
+  int dt;
+  time_t time;
+
+  switch (TimeFormat) {
+  case TIME_JD:
+    time = (value -  2440587.5) * 86400.0;
+    return (time);
+    break;
+  case TIME_MJD:
+    time = (value -  40587.0) * 86400.0;
+    return (time);
+    break;
+  case TIME_DAYS:
+    dt = value * 86400.0;
+    break;
+  case TIME_HOURS:
+    dt = value * 3600.0;
+    break;
+  case TIME_MINUTES:
+    dt = value * 60.0;
+    break;
+  case TIME_SECONDS:
+  default:
+    dt = value;
+    break;
+  }
+
+  time = TimeReference + dt;
+  return (time);
+}
+
+/* times may be in forms as:
+ * 20040200450s (N seconds since 1970.0)
+ * 2440900.232j (julian date)
+ * 99/02/23,03:22:18 (date string)
+ * (separators may be anything except space, +, -)
+ * 99:02:15:12:23:30
+ * 99:02:15:12h23m30s
+ */
+
Index: /trunk/Ohana/src/libdvo/src/coord_systems.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/coord_systems.c	(revision 31635)
+++ /trunk/Ohana/src/libdvo/src/coord_systems.c	(revision 31635)
@@ -0,0 +1,174 @@
+# include "dvo.h"
+# include "libdvo_astro.h"
+    
+CoordTransform *InitTransform (CoordTransformSystem input, CoordTransformSystem output) {
+
+  CoordTransform *transform;
+  struct timeval now;
+  struct tm *local;
+  double T;
+
+  ALLOCATE (transform, CoordTransform, 1);
+  transform->isIdentity = FALSE;
+  
+  switch (input) {
+    case COORD_CELESTIAL:
+      switch (output) {
+	case COORD_CELESTIAL:
+	  transform->phi = 0.0;
+	  transform->Xo  = 0.0;
+	  transform->xo  = 0.0;
+	  transform->isIdentity = TRUE;
+	  break;
+	case COORD_GALACTIC:
+
+	  // J2000 FK5 transformation from Liu et al 2011 (A&A 526, A16)
+	  transform->phi = -62.8717488056*RAD_DEG;
+	  transform->Xo  = 282.8594812080*RAD_DEG;
+	  transform->xo  =  32.9319185700;
+
+	  // these are derived from their eqn (10):
+	  // \alpha^p_J =  12h 51m 26.27549s
+	  // \delta^p_J = +27d 07' 41.7043"
+	  // \theta_J   = 122.93191857 deg
+	  // phi = -90 - \alpha^p_J
+	  // Xo  = +90 - \delta^p_J
+	  // xo  = \theta_J - 90
+
+	  // Liu et al also propose an alternative ICRS definition using:
+	  // \alpha^p_J =  12h 51m 26.27469s
+	  // \delta^p_J = +27d 07' 41.7087"
+	  // \theta_J   = 122.93192526 deg
+	  // these differ from the above at the several milliarcsec level
+
+
+	  // These values were used in the past, but transform to/from B1950.0
+	  // transform->phi = -62.60*RAD_DEG;
+	  // transform->Xo  = 282.25*RAD_DEG;
+	  // transform->xo  =  33.00;
+
+	  break;
+	case COORD_ECLIPTIC:
+	  gettimeofday (&now, NULL);
+	  local = localtime (&now.tv_sec);
+	  T = local[0].tm_year / 100.0;
+	  transform->phi = -1.0*RAD_DEG*(23.452294 - 0.013013*T - 0.000001639*T*T + 0.000000503*T*T*T);
+	  transform->Xo  = 0.0;
+	  transform->xo  = 0.0;
+	  break;
+	default:
+	  abort();
+      }
+      break;
+    case COORD_ECLIPTIC:
+      switch (output) {
+	case COORD_CELESTIAL:
+	  gettimeofday (&now, (struct timezone *) NULL);
+	  local = localtime (&now.tv_sec);
+	  T = local[0].tm_year / 100.0;
+	  transform->phi = RAD_DEG*(23.452294 - 0.013013*T - 0.000001639*T*T + 0.000000503*T*T*T);
+	  transform->Xo = 0.0;
+	  transform->xo = 0.0;
+	  break;
+	case COORD_GALACTIC:
+	  return NULL;
+	  break;
+	case COORD_ECLIPTIC:
+	  transform->phi = 0.0;
+	  transform->Xo  = 0.0;
+	  transform->xo  = 0.0;
+	  transform->isIdentity = TRUE;
+	  break;
+	default:
+	  abort();
+      }
+      break;
+    case COORD_GALACTIC:
+      switch (output) {
+	case COORD_CELESTIAL:
+	  // J2000 transformation from Liu et al 2011 ()
+	  transform->phi =  62.8717488056*RAD_DEG;
+	  transform->Xo  =  32.9319185700*RAD_DEG;
+	  transform->xo  = 282.8594812080;
+
+	  // These values were used in the past, but transform to/from B1950.0
+	  // transform->phi =  62.60*RAD_DEG;
+	  // transform->Xo  =  33.00*RAD_DEG;
+	  // transform->xo  = 282.25;
+	  break;
+	case COORD_GALACTIC:
+	  transform->phi = 0.0;
+	  transform->Xo  = 0.0;
+	  transform->xo  = 0.0;
+	  transform->isIdentity = TRUE;
+	  break;
+	case COORD_ECLIPTIC:
+	  return NULL;
+	default:
+	  abort();
+      }
+      break;
+    default:
+      abort();
+  }
+ 
+  // pre-calculated constants:
+  transform->sin_phi_cos_Xo = sin(transform->phi)*cos(transform->Xo);
+  transform->sin_phi_sin_Xo = sin(transform->phi)*sin(transform->Xo);
+  transform->cos_phi        = cos(transform->phi);
+  
+  transform->cos_phi_cos_Xo = cos(transform->phi)*cos(transform->Xo);
+  transform->cos_phi_sin_Xo = cos(transform->phi)*sin(transform->Xo);
+  transform->sin_phi        = sin(transform->phi);
+  transform->cos_Xo 	    = cos(transform->Xo);
+  transform->sin_Xo 	    = sin(transform->Xo);
+
+  return transform;
+}
+
+// input and output coordinates are in degrees
+int ApplyTransform (double *x, double *y, double X, double Y, CoordTransform *transform) {
+
+  double sin_x, sin_y, cos_x, cos_y;
+
+
+  if (transform == NULL) return (FALSE);
+
+  if (transform->isIdentity) {
+    *x = X;
+    *y = Y;
+    return (TRUE);
+  }
+
+  X *= RAD_DEG;
+  Y *= RAD_DEG;
+
+  // recast with constants extracted:
+  sin_y = cos(Y)*sin(X)*transform->sin_phi_cos_Xo - cos(Y)*cos(X)*transform->sin_phi_sin_Xo + sin(Y)*transform->cos_phi;
+  cos_y = sqrt (1 - sin_y*sin_y);
+
+  sin_x = cos(Y)*sin(X)*transform->cos_phi_cos_Xo - cos(Y)*cos(X)*transform->cos_phi_sin_Xo - sin(Y)*transform->sin_phi;
+  cos_x = cos(Y)*cos(X)*transform->cos_Xo + cos(Y)*sin(X)*transform->sin_Xo;
+      
+  // atan2 returns -pi : +pi
+  *x = DEG_RAD * atan2 (sin_x, cos_x) + transform->xo;
+  if ((*x) <   0.0) (*x) += 360;
+  if ((*x) > 360.0) (*x) -= 360;
+
+  // should be in range -pi/2 : +pi/2
+  *y = DEG_RAD * atan2 (sin_y, cos_y);
+
+  return (TRUE);
+}
+
+// sin_y = cos(Y)*sin(X - Xo)*sin(phi) + sin(Y)*cos(phi);
+
+// sin_x = (cos(Y)*sin(X - Xo)*cos(phi) - sin(Y)*sin(phi)) /  cos_y;
+// cos_x = cos(Y)*cos(X - Xo) / cos_y;
+
+// multiplying both sides by cos_y:
+// sin_x = (cos(Y)*sin(X - Xo)*cos(phi) - sin(Y)*sin(phi));
+// cos_x = cos(Y)*cos(X - Xo);
+      
+// sin(a - b) = sin(a)*cos(b) - sin(b)*cos(a);
+// cos(a - b) = sin(a)*sin(b) + cos(a)*cos(b);
Index: /trunk/Ohana/src/libdvo/src/dbBooleanCond.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/dbBooleanCond.c	(revision 31635)
+++ /trunk/Ohana/src/libdvo/src/dbBooleanCond.c	(revision 31635)
@@ -0,0 +1,85 @@
+# include "dvo.h"
+
+// evaluate the expression in inStack as a boolean; necessary db field values are
+// supplied by fields, in order 0 - Nfields (validate before calling)
+// XXX fields needs to be typed (dbValue), stack math needs to deal with the type cases
+int dbBooleanCond (dbStack *inStack, int NinStack, dbValue *fields) {
+  
+  float value;
+  int i, j, N, Nstack;
+  dbStack **stack, *output;
+
+  // 'no stack' means 'no where statement'
+  if (NinStack == 0) return (TRUE);
+
+  Nstack = NinStack;
+  ALLOCATE (stack, dbStack *, NinStack);
+  for (i = 0; i < NinStack; i++) {
+    stack[i] = &inStack[i];
+  }
+
+  for (i = 0; i < Nstack; i++) {
+
+    /***** binary operators *****/
+    if ((stack[i][0].type >= DB_STACK_LOGIC) && (stack[i][0].type <= DB_STACK_POWER)) {
+
+      // pre-test that op and entries match
+      output = dbBinary (stack[i-2], stack[i-1], stack[i][0].name, fields); 
+
+      // free temporary stack items, drop external items
+      dbFreeTempEntry (stack[i-2]);
+      dbFreeTempEntry (stack[i-1]);
+
+      stack[i-2] = output;
+      for (j = i + 1; j < Nstack; j++) {
+	stack[j-2] = stack[j];
+      }
+
+      Nstack -= 2;
+      i -= 2;
+      continue;
+    }
+
+    /***** unary operators **/
+    if (stack[i][0].type == DB_STACK_UNARY) {
+
+      // pre-test that op and entries match
+      output = dbUnary (stack[i-1], stack[i][0].name, fields); 
+
+      // free temporary stack items, drop external items
+      dbFreeTempEntry (stack[i-1]);
+
+      stack[i-1] = output;
+      for (j = i + 1; j < Nstack; j++) {
+	stack[j-1] = stack[j];
+      }
+
+      Nstack -= 1;
+      i -= 1;
+      continue;
+    } 
+  }
+
+  // the result here is a single stack entry with a value:
+  if (stack[0][0].type & DB_STACK_FIELD) {
+    N = stack[0][0].field;
+    value = (stack[0][0].type & DB_STACK_INT) ? fields[N].Int : fields[N].Flt;
+  } else {
+    value = (stack[0][0].type & DB_STACK_INT) ? stack[0][0].IntValue : stack[0][0].FltValue;
+  }
+    
+  for (i = 0; i < Nstack; i++) {
+    dbFreeEntry (stack[i]);
+  }
+  free (stack);
+
+  // XXX fix this limit
+  if (fabs(value) > 1e-7) {
+    return (TRUE);
+  } else {
+    return (FALSE);
+  }
+
+  // pre-test that op and entries match
+  return (TRUE);
+}
Index: /trunk/Ohana/src/libdvo/src/dbCheckStack.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/dbCheckStack.c	(revision 31635)
+++ /trunk/Ohana/src/libdvo/src/dbCheckStack.c	(revision 31635)
@@ -0,0 +1,129 @@
+# include "dvo.h"
+
+// XXX we are using a fairly bogus set of char values to distinguish a few cases:
+// 's', 'S' : value is a scalar (upper == float; lower == int)
+// 'f', 'F' : value is a field (upper == float; lower == int)
+// 't', 'T' : value is a temp scalar (upper == float; lower == int)
+// these would be better done using bit values to test for field? temp? float?
+//
+
+#define OPIHI_INT 1
+
+int dbCheckStack (dbStack *stack, int Nstack, int table, dbField **inFields, int *inNfields) {
+
+  int i, j, status, NFIELDS, Nfields;
+  char *c1, *c2;
+  dbField *fields;
+
+  fields = *inFields;
+  Nfields = *inNfields;
+
+  NFIELDS = Nfields + 10;
+  REALLOCATE (fields, dbField, NFIELDS);
+
+  for (i = 0; i < Nstack; i++) {
+    if (stack[i].type == DB_STACK_VALUE) {
+
+      /** if this is a number, put it on the list of scalars and move on.  assume value is
+       * an int unless proven otherwise **/
+      stack[i].FltValue = strtod (stack[i].name, &c1);
+      stack[i].IntValue = strtol (stack[i].name, &c2, 0);
+      if (c2 == stack[i].name + strlen (stack[i].name)) {
+	stack[i].type  |= DB_STACK_INT;
+	continue;
+      } 
+      if (c1 == stack[i].name + strlen (stack[i].name)) {
+	// this is a float value
+	continue;
+      } 
+
+      // the value might be a special type of number: RA,DEC in sexigesimal or 
+      // time in YYYY/MM/DD, etc
+      // status = ohana_str_to_time (stack[i].name, &seconds);
+      // keep as time_t
+      // status = ohana_dms_to_ddd (&ddd, stack[i].name);
+      // keep as either hours (RA) or deg (DEC).
+
+      // strings protected by double quotes should parse to be special types of numbers
+      // (photcodes, dates, ra / dec)
+      if (stack[i].name[0] == '"') {
+	  if (stack[i].name[strlen(stack[i].name) - 1] != '"') {
+	      gprint (GP_ERR, "syntax error for field %s\n", stack[i].name);
+	      goto failure;
+	  }
+	  char *tmpstring;
+	  tmpstring = strncreate (&stack[i].name[1], strlen(stack[i].name) - 2);
+
+	  // attempt to parse the string as a special word:
+	  PhotCode *code;
+	  code = GetPhotcodebyName (tmpstring);
+	  if (code) {
+	      stack[i].IntValue = code->code;
+	      stack[i].type = DB_STACK_INT;
+	      continue;
+	  } 
+
+	  // add in tests for sexigesimal, date/time
+	  // TimeRefPM = ohana_date_to_sec ("2000/01/01");
+	  
+	  gprint (GP_ERR, "syntax error for field %s\n", stack[i].name);
+	  goto failure;
+      }
+
+      // this must be a field : is it already in the list?
+      for (j = 0; (j < Nfields) && strcasecmp (stack[i].name, fields[j].name); j++);
+      if (j < Nfields) {
+	stack[i].field = j;
+	stack[i].type |= DB_STACK_FIELD;
+	if (fields[j].type == OPIHI_INT) {
+	  stack[i].type |= DB_STACK_INT;
+	}
+	stack[i].name  = NULL;
+	stack[i].FltValue = 0.0;
+	stack[i].IntValue =   0;
+	continue;
+      }
+
+      // this must be a field : is it a valid name?
+      status = FALSE;
+      if (table == DVO_TABLE_MEASURE) {
+	status = ParseMeasureField (&fields[Nfields], stack[i].name);
+      } 
+      if (table == DVO_TABLE_AVERAGE) {
+	status = ParseAverageField (&fields[Nfields], stack[i].name);
+      } 
+      if (table == DVO_TABLE_IMAGE) {
+	status = ParseImageField (&fields[Nfields], stack[i].name);
+      } 
+      if (!status) {
+	goto failure;
+      }
+      stack[i].field = Nfields;
+      stack[i].type |= DB_STACK_FIELD;
+      if (fields[Nfields].type == OPIHI_INT) {
+	stack[i].type |= DB_STACK_INT;
+      }
+      stack[i].name  = NULL;
+      stack[i].FltValue = 0.0; // 'F'
+      stack[i].IntValue =   0; // 'f'
+
+      Nfields ++;
+      CHECK_REALLOCATE (fields, dbField, NFIELDS, Nfields, 10);
+    }
+  }
+
+  *inNfields = Nfields;
+  *inFields = fields;
+  return (TRUE);
+
+failure:
+  *inNfields = Nfields;
+  *inFields = fields;
+  return (FALSE);
+}
+
+/* check stack identifies the data elements as plain scalars or table fields
+   operators have already been identified.  
+   check stack returns the total stack dimensionality (0,1,2)
+   on error, check stack returns FALSE
+*/
Index: /trunk/Ohana/src/libdvo/src/dbCmdlineFields.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/dbCmdlineFields.c	(revision 31635)
+++ /trunk/Ohana/src/libdvo/src/dbCmdlineFields.c	(revision 31635)
@@ -0,0 +1,215 @@
+# include "dvo.h"
+
+// check for 'where' or 'matched to'; return first field after the word, and the value
+int dbCmdlineConditions (int argc, char **argv, int first, int *nextField) {
+
+  int isWhere, isMatch;
+
+  *nextField = argc;
+
+  // require 'where' or 'matched to' before boolean math
+  if (first == argc) return DVO_DB_CMDLINE_IS_END;
+
+  isWhere = !strcasecmp(argv[first], "where");
+  isMatch = !strcasecmp(argv[first], "match");
+    
+  if (!isMatch && !isWhere) {
+    gprint (GP_ERR, "WHERE or MATCH TO\n");
+    return DVO_DB_CMDLINE_ERROR;
+  }
+  if (isMatch && ((first + 1 >= argc - 1) || strcasecmp(argv[first+1], "to"))) {
+    gprint (GP_ERR, "missing boolean expression\n");
+    return DVO_DB_CMDLINE_ERROR;
+  }
+  if (isWhere && (first >= argc - 1)) {
+    gprint (GP_ERR, "missing boolean expression\n");
+    return DVO_DB_CMDLINE_ERROR;
+  }
+
+  if (isWhere) {
+    *nextField = first + 1;
+    return DVO_DB_CMDLINE_IS_WHERE;
+  }
+
+  if (isMatch) {
+    *nextField = first + 2;
+    return DVO_DB_CMDLINE_IS_MATCH;
+  }
+
+  gprint (GP_ERR, "programming error?\n");
+  return DVO_DB_CMDLINE_ERROR;
+}
+
+// identify the fields to be extracted (check syntax)
+// the 'last' pointer ends on the first word after the fields (where, match or EOL) 
+dbField *dbCmdlineFields (int argc, char **argv, int table, int *last, int *nfields) {
+
+  int i, status, Nfields, NFIELDS;
+  char *p, *q, *field;
+  dbField *fields;
+
+  *nfields = 0;
+  Nfields = 0;
+  NFIELDS = 10;
+  ALLOCATE (fields, dbField, NFIELDS);
+  dbInitField (&fields[0]);
+
+  status = FALSE;
+
+  // examine each argv[i] entry until we reach a 'where', a 'matched', or the end of the line
+  for (i = 1; (i < argc) && strcasecmp (argv[i], "where") && strcasecmp (argv[i], "match"); i++) {
+    // split the word by ","
+    p = argv[i];
+    while (*p) {
+      q = strchr (p, ',');
+      if (q == NULL) {
+	field = strcreate (p);
+	p = p + strlen(p);
+      } else {
+	field = strncreate (p, q-p);
+	p = q + 1;
+      }
+      // identify field for word
+      // need to know which type of fields to look for...
+      // xxx extend this more generally later
+      if (table == DVO_TABLE_MEASURE) {
+	status = ParseMeasureField (&fields[Nfields], field);
+      } 
+      if (table == DVO_TABLE_AVERAGE) {
+	status = ParseAverageField (&fields[Nfields], field);
+      } 
+      if (table == DVO_TABLE_IMAGE) {
+	status = ParseImageField (&fields[Nfields], field);
+      } 
+      if (!status) {
+	free (field);
+	dbFreeFields (fields, Nfields);
+	return (NULL);
+      }
+      free (field);
+
+      Nfields ++;
+      CHECK_REALLOCATE (fields, dbField, NFIELDS, Nfields, 10);
+      dbInitField (&fields[Nfields]);
+    }
+  }
+
+  *last = i;
+  *nfields = Nfields;
+
+  return (fields);
+}
+
+char *strfloat (float value) {
+
+  int Nbyte;
+  char *output;
+  char tmp;
+
+  Nbyte = snprintf (&tmp, 0, "%f", value);
+  ALLOCATE (output, char, Nbyte + 1);
+  snprintf (output, Nbyte + 1, "%f", value);
+  return output;
+}
+
+// identify the fields to be extracted (test for where, check syntax)
+int dbAstroRegionLimits (dbStack **stack, int *nstack, SkyRegionSelection *selection, int table) {
+  
+  int N;
+  double Rmin, Rmax, Dmin, Dmax;
+  char *Rname, *Dname;
+
+  if (!selection->useDisplay && !selection->useSkyregion) return (TRUE);
+
+  // get the ra,dec limits...
+  if (selection->useDisplay) {
+    return (TRUE);
+    // XXX fix this: be more careful with the projection & limits
+
+    Graphdata graphsky;
+    if (!GetGraphdata (&graphsky, NULL, NULL)) {
+      gprint (GP_ERR, "region display not available\n");
+      return (FALSE);
+    }
+    
+    // XXX the ra and dec range depend on the projection. 
+    // XXX this is wrong...
+    int status;
+    status = XY_to_RD (&Rmin, &Dmin, graphsky.xmin, graphsky.ymin, &graphsky.coords);
+    status = XY_to_RD (&Rmax, &Dmax, graphsky.xmax, graphsky.ymax, &graphsky.coords);
+  }
+
+  if (selection->useSkyregion) {
+    get_skyregion (&Rmin, &Rmax, &Dmin, &Dmax);
+  }    
+
+  N = *nstack;
+  REALLOCATE (*stack, dbStack, N + 20);
+
+  Rname = Dname = NULL;
+  if (table == DVO_TABLE_MEASURE) {
+    Rname = strcreate ("RA:AVE");
+    Dname = strcreate ("DEC:AVE");
+  }
+  if (table == DVO_TABLE_AVERAGE) {
+    Rname = strcreate ("RA");
+    Dname = strcreate ("DEC");
+  }
+  if (table == DVO_TABLE_IMAGE) {
+    Rname = strcreate ("RA");
+    Dname = strcreate ("DEC");
+  } 
+  if (Rname == NULL) return (FALSE);
+
+  // add: ((ra > rmin) && (ra < rmax) && (dec > dmin) && (dec < dmax))
+  // prepend with && if *nstack > 0
+
+  stack[0][N +  0].name = strcreate (Rname);
+  stack[0][N +  0].type = DB_STACK_VALUE;
+  stack[0][N +  1].name = strfloat (Rmin);
+  stack[0][N +  1].type = DB_STACK_VALUE;
+  stack[0][N +  2].name = strcreate (">");
+  stack[0][N +  2].type = DB_STACK_COMPARE;
+
+  stack[0][N +  3].name = strcreate (Rname);
+  stack[0][N +  3].type = DB_STACK_VALUE;
+  stack[0][N +  4].name = strfloat (Rmax);
+  stack[0][N +  4].type = DB_STACK_VALUE;
+  stack[0][N +  5].name = strcreate ("<");
+  stack[0][N +  5].type = DB_STACK_COMPARE;
+  stack[0][N +  6].name = strcreate ("A");
+  stack[0][N +  6].type = DB_STACK_LOGIC;
+
+  stack[0][N +  7].name = strcreate (Dname);
+  stack[0][N +  7].type = DB_STACK_VALUE;
+  stack[0][N +  8].name = strfloat (Dmin);
+  stack[0][N +  8].type = DB_STACK_VALUE;
+  stack[0][N +  9].name = strcreate (">");
+  stack[0][N +  9].type = DB_STACK_COMPARE;
+  stack[0][N + 10].name = strcreate ("A");
+  stack[0][N + 10].type = DB_STACK_LOGIC;
+
+  stack[0][N + 11].name = strcreate (Dname);
+  stack[0][N + 11].type = DB_STACK_VALUE;
+  stack[0][N + 12].name = strfloat (Dmax);
+  stack[0][N + 12].type = DB_STACK_VALUE;
+  stack[0][N + 13].name = strcreate ("<");
+  stack[0][N + 13].type = DB_STACK_COMPARE;
+  stack[0][N + 14].name = strcreate ("A");
+  stack[0][N + 14].type = DB_STACK_LOGIC;
+
+  if (N == 0) {
+    N += 15;
+  } else {
+    stack[0][N + 15].name = strcreate ("A");
+    stack[0][N + 15].type = DB_STACK_LOGIC;
+    N += 16;
+  }    
+
+  free (Rname);
+  free (Dname);
+
+  *nstack = N;
+  return (TRUE);
+}
+
Index: /trunk/Ohana/src/libdvo/src/dbExtractAverages.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/dbExtractAverages.c	(revision 31635)
+++ /trunk/Ohana/src/libdvo/src/dbExtractAverages.c	(revision 31635)
@@ -0,0 +1,241 @@
+# include "dvo.h"
+# include "libdvo_astro.h"
+
+/* time concepts */
+static time_t TimeReference;
+static int TimeFormat;
+
+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 dbExtractAveragesInitTransform (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 dbExtractAveragesInit () {
+  GetTimeFormat (&TimeReference, &TimeFormat);
+  haveGalactic = FALSE;
+  haveEcliptic = FALSE;
+  return (TRUE);
+}
+
+/* return average.field based on the selection */
+dbValue dbExtractAverages (Average *average, SecFilt *secfilt, Measure *measure, dbField *field) {
+
+  off_t i;
+  int Nsec;
+  dbValue value;
+
+  value.Flt = NAN;
+  value.Int =   0;
+
+  /* assign vector values */
+  switch (field->ID) {
+    case AVE_RA:
+      value.Flt = average[0].R;
+      break;
+    case AVE_DEC:
+      value.Flt = average[0].D;
+      break;
+    case AVE_GLON:
+      if (!haveGalactic) {
+	ApplyTransform (&GLON, &GLAT, average[0].R, average[0].D, celestial_to_galactic);
+	haveGalactic = TRUE;
+      }
+      value.Flt = GLON;
+      break;
+    case AVE_GLAT:
+      if (!haveGalactic) {
+	ApplyTransform (&GLON, &GLAT, average[0].R, average[0].D, celestial_to_galactic);
+	haveGalactic = TRUE;
+      }
+      value.Flt = GLAT;
+      break;
+    case AVE_ELON:
+      if (!haveEcliptic) {
+	ApplyTransform (&ELON, &ELAT, average[0].R, average[0].D, celestial_to_ecliptic);
+	haveEcliptic = TRUE;
+      }
+      value.Flt = ELON;
+      break;
+    case AVE_ELAT:
+      if (!haveEcliptic) {
+	ApplyTransform (&ELON, &ELAT, average[0].R, average[0].D, celestial_to_ecliptic);
+	haveEcliptic = TRUE;
+      }
+      value.Flt = ELAT;
+      break;
+    case AVE_RA_ERR:
+      value.Flt = average[0].dR;
+      break;
+    case AVE_DEC_ERR:
+      value.Flt = average[0].dD;
+      break;
+
+    case AVE_U_RA:
+      value.Flt = average[0].uR;
+      break;
+    case AVE_U_DEC:
+      value.Flt = average[0].uD;
+      break;
+    case AVE_U_RA_ERR:
+      value.Flt = average[0].duR;
+      break;
+    case AVE_U_DEC_ERR:
+      value.Flt = average[0].duD;
+      break;
+
+    case AVE_PAR:
+      value.Flt = average[0].P;
+      break;
+    case AVE_PAR_ERR:
+      value.Flt = average[0].dP;
+      break;
+
+    case AVE_NMEAS:
+      value.Int = average[0].Nmeasure;
+      break;
+    case AVE_NMISS:
+      value.Int = average[0].Nmissing;
+      break;
+    case AVE_NPOS:
+      value.Int = average[0].Npos;
+      break;
+
+    case AVE_CHISQ_POS:
+      value.Flt = average[0].ChiSqAve;
+      break;
+    case AVE_CHISQ_PM:
+      value.Flt = average[0].ChiSqPM;
+      break;
+    case AVE_CHISQ_PAR:
+      value.Flt = average[0].ChiSqPar;
+      break;
+
+    case AVE_TMEAN:
+      value.Flt = TimeValue (average[0].Tmean, TimeReference, TimeFormat);
+      break;
+    case AVE_TRANGE:
+      value.Flt = TimeValue (average[0].Trange, 0, TimeFormat);
+      break;
+
+    case AVE_Xp:
+      value.Flt = 0.01*average[0].Xp;
+      break;
+
+    case AVE_OBJ_FLAGS:
+      value.Int = average[0].flags;
+      break;
+    case AVE_OBJID:
+      value.Int = average[0].objID;
+      break;
+    case AVE_CATID:
+      value.Int = average[0].catID;
+      break;
+    case AVE_EXTID_HI:
+      value.Int = (0x00000000FFFFFFFF & (average[0].extID >> 32));
+      break;
+    case AVE_EXTID_LO:
+      value.Int = (0x00000000FFFFFFFF & average[0].extID);
+      break;
+
+    case AVE_MAG:
+      switch (field->magMode) {
+	case MAG_AVE:
+	  value.Flt = PhotAve  (field->photcode, average, secfilt);
+	  break;
+	case MAG_REF:
+	  value.Flt = 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.Flt = NAN;
+	  for (i = 0; i < average[0].Nmeasure; i++) {
+	    if (field->photcode->code != measure[i].photcode) continue;
+	    value.Flt = measure[i].M;
+	    break;
+	  }
+	  break;
+	case MAG_CHISQ:
+	  value.Flt = PhotXm (field->photcode, average, secfilt);
+	  break;
+	case MAG_ERR:
+	  if ((field->photcode->type == PHOT_REF) || (field->photcode->type == PHOT_DEP)) {
+	    for (i = 0; i < average[0].Nmeasure; i++) {
+	      if (field->photcode->code != measure[i].photcode) continue;
+	      value.Flt = measure[i].dM;
+	      break;
+	    }
+	  } else {
+	    value.Flt = PhotdM (field->photcode, average, secfilt);
+	  }
+	  break;
+	case MAG_PHOT_FLAGS:
+	  if ((field->photcode->type == PHOT_REF) || (field->photcode->type == PHOT_DEP)) {
+	    for (i = 0; i < average[0].Nmeasure; i++) {
+	      if (field->photcode->code != measure[i].photcode) continue;
+	      value.Int = measure[i].photFlags;
+	      break;
+	    }
+	  } else {
+	    value.Int = 0;
+	  }
+	  break;
+	case MAG_NCODE:
+	  // XXX push these into dvo_photcode_ops APIs
+	  // XXX do I need to allow for conversion to equiv?
+	  Nsec = GetPhotcodeNsec (field->photcode->code);
+	  if (Nsec == -1) break;
+	  value.Int = secfilt[Nsec].Ncode;
+	  break;
+	case MAG_NPHOT:
+	  Nsec = GetPhotcodeNsec (field->photcode->code);
+	  if (Nsec == -1) break;
+	  value.Int = secfilt[Nsec].Nused;
+	  break;
+
+      }
+      break;
+    case AVE_dMAG:
+      value.Flt = PhotdM (field->photcode, average, secfilt);
+      break;
+    case AVE_Xm:
+      value.Flt = PhotXm (field->photcode, average, secfilt);
+      break;
+    case AVE_TYPE:
+      break;
+    case AVE_TYPEFRAC:
+      break;
+  }
+  return (value);
+}  
+
Index: /trunk/Ohana/src/libdvo/src/dbExtractImages.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/dbExtractImages.c	(revision 31635)
+++ /trunk/Ohana/src/libdvo/src/dbExtractImages.c	(revision 31635)
@@ -0,0 +1,345 @@
+# include "dvo.h"
+
+/* time concepts */
+static time_t TimeReference;
+static int TimeFormat;
+
+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;
+
+static int haveCelestial = FALSE;
+static double RAo = 0.0;
+static double DECo = 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 () {
+  GetTimeFormat (&TimeReference, &TimeFormat);
+  return (TRUE);
+}
+
+int dbExtractImagesReset () {
+  haveGalactic  = FALSE;
+  haveEcliptic  = FALSE;
+  haveCelestial = FALSE;
+  return (TRUE);
+}
+
+/* return image.field based on the selection */
+dbValue dbExtractImages (Image *image, off_t Nimage, off_t N, dbField *field) {
+
+  double x, y;
+  time_t t;
+  dbValue value;
+  off_t Nmosaic;
+
+  value.Flt = NAN;
+  value.Int =   0;
+
+  /* assign vector values */
+  switch (field->ID) {
+    case IMAGE_RA:
+      if (!haveCelestial) {
+	if (!FindMosaicForImage (image, Nimage, N)) return value;
+	x = 0.5*image[N].NX;
+	y = 0.5*image[N].NY;
+	XY_to_RD (&RAo, &DECo, x, y, &image[N].coords);
+	haveCelestial = TRUE;
+      }
+      value.Flt = RAo;
+      break;
+    case IMAGE_DEC:
+      if (!haveCelestial) {
+	if (!FindMosaicForImage (image, Nimage, N)) return value;
+	x = 0.5*image[N].NX;
+	y = 0.5*image[N].NY;
+	XY_to_RD (&RAo, &DECo, x, y, &image[N].coords);
+	haveCelestial = TRUE;
+      }
+      value.Flt = DECo;
+      break;
+    case IMAGE_GLON:
+      if (!haveGalactic) {
+	if (!haveCelestial) {
+	  if (!FindMosaicForImage (image, Nimage, N)) return value;
+	  x = 0.5*image[N].NX;
+	  y = 0.5*image[N].NY;
+	  XY_to_RD (&RAo, &DECo, x, y, &image[N].coords);
+	  haveCelestial = TRUE;
+	}
+	ApplyTransform (&GLON, &GLAT, RAo, DECo, celestial_to_galactic);
+	haveGalactic = TRUE;
+      }
+      value.Flt = GLON;
+      break;
+    case IMAGE_GLAT:
+      if (!haveGalactic) {
+	if (!haveCelestial) {
+	  if (!FindMosaicForImage (image, Nimage, N)) return value;
+	  x = 0.5*image[N].NX;
+	  y = 0.5*image[N].NY;
+	  XY_to_RD (&RAo, &DECo, x, y, &image[N].coords);
+	  haveCelestial = TRUE;
+	}
+	ApplyTransform (&GLON, &GLAT, RAo, DECo, celestial_to_galactic);
+	haveGalactic = TRUE;
+      }
+      value.Flt = GLAT;
+      break;
+    case IMAGE_ELON:
+      if (!haveEcliptic) {
+	if (!haveCelestial) {
+	  if (!FindMosaicForImage (image, Nimage, N)) return value;
+	  x = 0.5*image[N].NX;
+	  y = 0.5*image[N].NY;
+	  XY_to_RD (&RAo, &DECo, x, y, &image[N].coords);
+	  haveCelestial = TRUE;
+	}
+	ApplyTransform (&ELON, &ELAT, RAo, DECo, celestial_to_ecliptic);
+	haveEcliptic = TRUE;
+      }
+      value.Flt = ELON;
+      break;
+    case IMAGE_ELAT:
+      if (!haveEcliptic) {
+	if (!haveCelestial) {
+	  if (!FindMosaicForImage (image, Nimage, N)) return value;
+	  x = 0.5*image[N].NX;
+	  y = 0.5*image[N].NY;
+	  XY_to_RD (&RAo, &DECo, x, y, &image[N].coords);
+	  haveCelestial = TRUE;
+	}
+	ApplyTransform (&ELON, &ELAT, RAo, DECo, celestial_to_ecliptic);
+	haveEcliptic = TRUE;
+      }
+      value.Flt = ELAT;
+      break;
+
+    case IMAGE_THETA: {
+      double theta1, theta2, s1, s2;
+      s1 = SIGN(image[N].coords.pc1_1);
+      s2 = SIGN(image[N].coords.pc2_2);
+      theta1 = DEG_RAD*atan2 (+s1*image[N].coords.pc1_2, s1*image[N].coords.pc1_1);
+      theta2 = DEG_RAD*atan2 (-s2*image[N].coords.pc2_1, s2*image[N].coords.pc2_2);
+      value.Flt = 0.5*(theta1+theta2);
+      break; }
+    case IMAGE_SKEW: {
+      double theta1, theta2, s1, s2;
+      s1 = SIGN(image[N].coords.pc1_1);
+      s2 = SIGN(image[N].coords.pc2_2);
+      theta1 = DEG_RAD*atan2 (+s1*image[N].coords.pc1_2, s1*image[N].coords.pc1_1);
+      theta2 = DEG_RAD*atan2 (-s2*image[N].coords.pc2_1, s2*image[N].coords.pc2_2);
+      value.Flt = (theta1-theta2);
+      break; }
+    case IMAGE_SCALE: {
+      double scale1, scale2;
+      scale1 = fabs(image[N].coords.cdelt1);
+      scale2 = fabs(image[N].coords.cdelt2);
+      value.Flt = 0.5*(scale1+scale2);
+      break; }
+    case IMAGE_DSCALE: {
+      double scale1, scale2;
+      scale1 = fabs(image[N].coords.cdelt1);
+      scale2 = fabs(image[N].coords.cdelt2);
+      value.Flt = (scale1-scale2);
+      break; }
+
+    case IMAGE_TIME:
+      t = image[N].tzero + 0.5*image[N].NY * image[N].trate / 10000;
+      value.Flt = TimeValue (t, TimeReference, TimeFormat);
+      break;
+    case IMAGE_NSTAR:
+      value.Int = image[N].nstar;
+      break;
+    case IMAGE_AIRMASS:
+      value.Flt = image[N].secz;
+      break;
+    case IMAGE_NX_PIX:
+      value.Int = image[N].NX;
+      break;
+    case IMAGE_NY_PIX:
+      value.Int = image[N].NY;
+      break;
+    case IMAGE_APRESID:
+      value.Flt = image[N].apmifit;
+      break;
+    case IMAGE_DAPRESID:
+      value.Flt = image[N].dapmifit;
+      break;
+
+    case IMAGE_MCAL:
+      value.Flt = image[N].Mcal;
+      break;
+    case IMAGE_dMCAL:
+      value.Flt = image[N].dMcal;
+      break;
+    case IMAGE_XM:
+      value.Flt = pow(10.0, 0.01*image[N].Xm);
+      break;
+    case IMAGE_PHOTCODE:
+      value.Int = image[N].photcode;
+      break;
+    case IMAGE_EXPTIME:
+      value.Flt = image[N].exptime;
+      break;
+    case IMAGE_SIDTIME:
+      value.Flt = image[N].sidtime;
+      break;
+
+    case IMAGE_LATITUDE:
+      value.Flt = image[N].latitude;
+      break;
+
+    case IMAGE_DET_LIMIT:
+      value.Flt = image[N].detection_limit * 0.1;
+      break;
+    case IMAGE_SAT_LIMIT:
+      value.Flt = image[N].saturation_limit * 0.1;
+      break;
+    case IMAGE_CERROR:
+      value.Flt = image[N].cerror / 50.0;
+      break;
+
+    case IMAGE_FWHM:
+      value.Flt = (image[N].fwhm_x + image[N].fwhm_y) / 50.0;
+      break;
+    case IMAGE_FWHM_MAJ:
+      value.Flt = image[N].fwhm_x / 25.0;
+      break;
+    case IMAGE_FWHM_MIN:
+      value.Flt = image[N].fwhm_y / 25.0;
+      break;
+
+    case IMAGE_FWHM_MEDIAN:
+      if (!(Nmosaic = FindMosaicForImage (image, Nimage, N))) return value;
+      Nmosaic --; // XXX kind of a hack: FindMosaicForImage returns 0 or the mosaic seq number + 1
+      value.Flt = (image[Nmosaic].fwhm_x + image[Nmosaic].fwhm_y) / 50.0;
+      break;
+    case IMAGE_FWHM_MAJ_MEDIAN:
+      if (!(Nmosaic = FindMosaicForImage (image, Nimage, N))) return value;
+      Nmosaic --; // XXX kind of a hack: FindMosaicForImage returns 0 or the mosaic seq number + 1
+      value.Flt = image[Nmosaic].fwhm_x / 25.0;
+      break;
+    case IMAGE_FWHM_MIN_MEDIAN:
+      if (!(Nmosaic = FindMosaicForImage (image, Nimage, N))) return value;
+      Nmosaic --; // XXX kind of a hack: FindMosaicForImage returns 0 or the mosaic seq number + 1
+      value.Flt = image[Nmosaic].fwhm_y / 25.0;
+      break;
+
+    case IMAGE_TRATE:
+      value.Flt = image[N].trate / 10000.0;
+      break;
+
+    case IMAGE_NCAL:
+      value.Int = image[N].nFitPhotom;
+      break;
+    case IMAGE_SKY:
+      value.Flt = NAN;
+      break;
+    case IMAGE_FLAGS:
+      value.Int = image[N].flags;
+      break;
+    case IMAGE_CCDNUM:
+      value.Int = image[N].ccdnum;
+      break;
+
+    case IMAGE_IMAGE_ID:
+      value.Int = image[N].imageID;
+      break;
+    case IMAGE_EXTERN_ID:
+      value.Int = image[N].externID;
+      break;
+    case IMAGE_SOURCE_ID:
+      value.Int = image[N].sourceID;
+      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[N].NX;
+      break;
+    case IMAGE_Y_UL_CHIP:
+    case IMAGE_Y_UR_CHIP:
+      value.Flt = image[N].NX;
+      break;
+
+    case IMAGE_X_LL_FP:
+    case IMAGE_Y_LL_FP:
+      XY_to_LM (&x, &y, 0.0, 0.0, &image[N].coords);
+      value.Flt = (field->ID == IMAGE_X_LL_FP) ? x : y;
+      break;
+    case IMAGE_X_LR_FP:
+    case IMAGE_Y_LR_FP:
+      XY_to_LM (&x, &y, image[N].NX, 0.0, &image[N].coords);
+      value.Flt = (field->ID == IMAGE_X_LR_FP) ? x : y;
+      break;
+    case IMAGE_X_UL_FP:
+    case IMAGE_Y_UL_FP:
+      XY_to_LM (&x, &y, 0.0, image[N].NY, &image[N].coords);
+      value.Flt = (field->ID == IMAGE_X_UL_FP) ? x : y;
+      break;
+    case IMAGE_X_UR_FP:
+    case IMAGE_Y_UR_FP:
+      XY_to_LM (&x, &y, image[N].NX, image[N].NY, &image[N].coords);
+      value.Flt = (field->ID == IMAGE_X_UR_FP) ? x : y;
+      break;
+
+    case IMAGE_X_ERR_SYS:
+      value.Flt = image[N].dXpixSys;
+      break;
+    case IMAGE_Y_ERR_SYS:
+      value.Flt = image[N].dXpixSys;
+      break;
+    case IMAGE_MAG_ERR_SYS:
+      value.Flt = image[N].dMagSys;
+      break;
+
+    case IMAGE_NFIT_PHOTOM:
+      value.Int = image[N].nFitPhotom;
+      break;
+    case IMAGE_NFIT_ASTROM:
+      value.Int = image[N].nFitAstrom;
+      break;
+    case IMAGE_NLINK_PHOTOM:
+      value.Int = image[N].nLinkPhotom;
+      break;
+    case IMAGE_NLINK_ASTROM:
+      value.Int = image[N].nLinkAstrom;
+      break;
+  }
+  return (value);
+}  
+
Index: /trunk/Ohana/src/libdvo/src/dbExtractMeasures.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/dbExtractMeasures.c	(revision 31635)
+++ /trunk/Ohana/src/libdvo/src/dbExtractMeasures.c	(revision 31635)
@@ -0,0 +1,466 @@
+# include "dvo.h"
+# include "dvodb.h"
+
+// to add a new field to the extractions:
+// 1) add the selection for the field below
+// 2) add the field to the ParseMeasureField in dbFields.c
+// 3) add the field to the measure enum list in dvoshell.h
+
+/* time concepts */
+static time_t TimeReference;
+static int TimeFormat;
+
+static CoordTransform *celestial_to_galactic = NULL;
+static CoordTransform *celestial_to_ecliptic = NULL;
+
+static int haveGalacticAve = FALSE;
+static double GLON_AVE = 0.0;
+static double GLAT_AVE = 0.0;
+
+static int haveEclipticAve = FALSE;
+static double ELON_AVE = 0.0;
+static double ELAT_AVE = 0.0;
+
+static int haveGalacticMeas = FALSE;
+static double GLON_MEAS = 0.0;
+static double GLAT_MEAS = 0.0;
+
+static int haveEclipticMeas = FALSE;
+static double ELON_MEAS = 0.0;
+static double ELAT_MEAS = 0.0;
+
+int dbExtractMeasuresInit () {
+  GetTimeFormat (&TimeReference, &TimeFormat);
+  return (TRUE);
+}
+
+// define a locally-static transform
+int dbExtractMeasuresInitTransform (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 dbExtractMeasuresInitAve () {
+  haveGalacticAve = FALSE;
+  haveEclipticAve = FALSE;
+  return (TRUE);
+}
+
+int dbExtractMeasuresInitMeas () {
+  haveGalacticMeas = FALSE;
+  haveEclipticMeas = FALSE;
+  return (TRUE);
+}
+
+/* return measure.field based on the selection */
+dbValue dbExtractMeasures (Average *average, SecFilt *secfilt, Measure *measure, dbField *field) {
+
+  int Nsec;
+  dbValue value;
+  double ra, dec, x, y, dT;
+
+  Coords *mosaic;
+  PhotCode *equiv;
+
+  value.Flt = NAN;
+  value.Int =   0;
+
+  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;
+      if ((field->photcode->type == PHOT_REF) && (measure[0].photcode == field->photcode->code)) goto valid_photcode;
+      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;
+      break;
+
+  valid_photcode:
+      switch (field->magMode) {
+	case MAG_INST:
+	  value.Flt = PhotInst (measure);  
+	  break;
+	case MAG_CAT:
+	  value.Flt = PhotCat  (measure); 
+	  break;
+	case MAG_SYS:
+	  value.Flt = PhotSys  (measure, average, secfilt); 
+	  break;
+	case MAG_REL:
+	  value.Flt = PhotRel  (measure, average, secfilt); 
+	  break;
+	case MAG_CAL:
+	  value.Flt = PhotCal  (measure, average, secfilt, measure, equiv); 
+	  break;
+	case MAG_AVE:
+	  value.Flt = PhotAve  (equiv, average, secfilt); 
+	  break;
+	case MAG_REF:
+	  value.Flt = PhotRef  (equiv, average, secfilt, measure); 
+	  break;
+	case MAG_APER:
+	  value.Flt = PhotAper  (measure); 
+	  break;
+	case MAG_ERR:
+	  value.Flt = measure[0].dM;
+	  break;
+	case MAG_AVE_ERR:
+	  value.Flt = PhotdM  (equiv, average, secfilt); 
+	  break;
+	case MAG_PHOT_FLAGS:
+	  if ((field->photcode->type == PHOT_REF) || (field->photcode->type == PHOT_DEP)) {
+	    value.Int = measure[0].photFlags;
+	  } else {
+	    value.Int = 0;
+	  }
+	  break;
+	case MAG_CHISQ:
+	  value.Flt = PhotXm  (equiv, average, secfilt); 
+	  break;
+	case MAG_NCODE:
+	  if (equiv == NULL) {
+	    value.Int = 0;
+	    break;
+	  }
+	  Nsec = GetPhotcodeNsec (equiv->code);
+	  if (Nsec == -1) break;
+	  value.Int = secfilt[Nsec].Ncode;
+	  break;
+	case MAG_NPHOT:
+	  if (equiv == NULL) {
+	    value.Int = 0;
+	    break;
+	  }
+	  Nsec = GetPhotcodeNsec (equiv->code);
+	  if (Nsec == -1) break;
+	  value.Int = secfilt[Nsec].Nused;
+	  break;
+      }
+      break;
+    case MEAS_RA: /* OK */
+      value.Flt = average[0].R - measure[0].dR / 3600.0;
+      break;
+    case MEAS_DEC: /* OK */
+      value.Flt = average[0].D - measure[0].dD / 3600.0;
+      break;
+    case MEAS_RA_AVE: /* OK */
+      value.Flt = average[0].R;
+      break;
+    case MEAS_DEC_AVE: /* OK */
+      value.Flt = average[0].D;
+      break;
+
+    case MEAS_GLON:
+      if (!haveGalacticMeas) {
+	ApplyTransform (&GLON_MEAS, &GLAT_MEAS, average[0].R - measure[0].dR / 3600.0, average[0].D - measure[0].dD / 3600.0, celestial_to_galactic);
+	haveGalacticMeas = TRUE;
+      }
+      value.Flt = GLON_MEAS;
+      break;
+    case MEAS_GLAT:
+      if (!haveGalacticMeas) {
+	ApplyTransform (&GLON_MEAS, &GLAT_MEAS, average[0].R - measure[0].dR / 3600.0, average[0].D - measure[0].dD / 3600.0, celestial_to_galactic);
+	haveGalacticMeas = TRUE;
+      }
+      value.Flt = GLAT_MEAS;
+      break;
+    case MEAS_ELON:
+      if (!haveEclipticMeas) {
+	ApplyTransform (&ELON_MEAS, &ELAT_MEAS, average[0].R - measure[0].dR / 3600.0, average[0].D - measure[0].dD / 3600.0, celestial_to_ecliptic);
+	haveEclipticMeas = TRUE;
+      }
+      value.Flt = ELON_MEAS;
+      break;
+    case MEAS_ELAT:
+      if (!haveEclipticMeas) {
+	ApplyTransform (&ELON_MEAS, &ELAT_MEAS, average[0].R - measure[0].dR / 3600.0, average[0].D - measure[0].dD / 3600.0, celestial_to_ecliptic);
+	haveEclipticMeas = TRUE;
+      }
+      value.Flt = ELAT_MEAS;
+      break;
+
+    case MEAS_GLON_AVE:
+      if (!haveGalacticAve) {
+	ApplyTransform (&GLON_AVE, &GLAT_AVE, average[0].R, average[0].D, celestial_to_galactic);
+	haveGalacticAve = TRUE;
+      }
+      value.Flt = GLON_AVE;
+      break;
+    case MEAS_GLAT_AVE:
+      if (!haveGalacticAve) {
+	ApplyTransform (&GLON_AVE, &GLAT_AVE, average[0].R, average[0].D, celestial_to_galactic);
+	haveGalacticAve = TRUE;
+      }
+      value.Flt = GLAT_AVE;
+      break;
+    case MEAS_ELON_AVE:
+      if (!haveEclipticAve) {
+	ApplyTransform (&ELON_AVE, &ELAT_AVE, average[0].R, average[0].D, celestial_to_ecliptic);
+	haveEclipticAve = TRUE;
+      }
+      value.Flt = ELON_AVE;
+      break;
+    case MEAS_ELAT_AVE:
+      if (!haveEclipticAve) {
+	ApplyTransform (&ELON_AVE, &ELAT_AVE, average[0].R, average[0].D, celestial_to_ecliptic);
+	haveEclipticAve = TRUE;
+      }
+      value.Flt = ELAT_AVE;
+      break;
+
+    case MEAS_RA_AVE_ERR: /* OK */
+      value.Flt = average[0].dR;
+      break;
+    case MEAS_DEC_AVE_ERR: /* OK */
+      value.Flt = average[0].dD;
+      break;
+    case MEAS_U_RA: /* OK */
+      value.Flt = average[0].uR;
+      break;
+    case MEAS_U_DEC: /* OK */
+      value.Flt = average[0].uD;
+      break;
+    case MEAS_U_RA_ERR: /* OK */
+      value.Flt = average[0].duR;
+      break;
+    case MEAS_U_DEC_ERR: /* OK */
+      value.Flt = average[0].duD;
+      break;
+    case MEAS_PAR: /* OK */
+      value.Flt = average[0].R;
+      break;
+    case MEAS_PAR_ERR: /* OK */
+      value.Flt = average[0].D;
+      break;
+    case MEAS_CHISQ_POS: /* OK */
+      value.Flt = average[0].ChiSqAve;
+      break;
+    case MEAS_CHISQ_PM: /* OK */
+      value.Flt = average[0].ChiSqPM;
+      break;
+    case MEAS_CHISQ_PAR: /* OK */
+      value.Flt = average[0].ChiSqPar;
+      break;
+    case MEAS_TMEAN: /* OK */
+      value.Flt = TimeValue (average[0].Tmean, TimeReference, TimeFormat);
+      break;
+    case MEAS_TRANGE: /* OK */
+      value.Flt = TimeValue (average[0].Trange, 0, TimeFormat);
+      break;
+    case MEAS_NMEAS: /* OK */
+      value.Int = average[0].Nmeasure;
+      break;
+    case MEAS_NMISS: /* OK */
+      value.Int = average[0].Nmissing;
+      break;
+    case MEAS_NPOS: /* OK */
+      value.Int = average[0].Npos;
+      break;
+    case MEAS_OBJ_FLAGS: /* OK */
+      value.Int = average[0].flags;
+      break;
+    // note that these represent the ra displacement relative to the average, not 
+    // the error.
+    case MEAS_RA_OFFSET: /* OK */
+      value.Flt = measure[0].dR;
+      break;
+    case MEAS_DEC_OFFSET: /* OK */
+      value.Flt = measure[0].dD;
+      break;
+    case MEAS_RA_FIT_OFFSET: /* OK */
+      dT = (measure[0].t - average[0].Tmean) / (86400*365.25);
+      value.Flt = average[0].uR * dT + measure[0].dR;
+      break;
+    case MEAS_DEC_FIT_OFFSET: /* OK */
+      dT = (measure[0].t - average[0].Tmean) / (86400*365.25);
+      value.Flt = average[0].uD * dT + measure[0].dD;
+      break;
+    case MEAS_RA_OFFSET_ERR: /* OK */
+      value.Flt = NAN;
+      break;
+    case MEAS_DEC_OFFSET_ERR: /* OK */
+      value.Flt = NAN;
+      break;
+    case MEAS_AIRMASS: /* OK */
+      value.Flt = measure[0].airmass;
+      break;
+    case MEAS_AZ: /* OK */
+      value.Flt = measure[0].az;
+      break;
+    case MEAS_ALT: /* OK */
+      value.Flt = 90.0 - DEG_RAD*acos(1.0/measure[0].airmass);
+      break;
+    case MEAS_EXPTIME: /* OK */
+      value.Flt = pow (10.0, measure[0].dt * 0.4);
+      break;
+    case MEAS_PHOTCODE_EQUIV: /* OK */
+      value.Int = GetPhotcodeEquivCodebyCode (measure[0].photcode);
+      break;
+    case MEAS_PHOTCODE: /* OK */
+      value.Int = measure[0].photcode;
+      break;
+    case MEAS_TIME: /* OK */
+      value.Flt = TimeValue (measure[0].t, TimeReference, TimeFormat);
+      break;
+    case MEAS_FWHM: /* OK */
+      value.Flt = FromShortPixels(measure[0].FWx + measure[0].FWy) / 2.0;
+      break;
+    case MEAS_FWHM_MAJ: /* OK */
+      value.Flt = FromShortPixels(measure[0].FWx);
+      break;
+    case MEAS_FWHM_MIN: /* OK */
+      value.Flt = FromShortPixels(measure[0].FWy);
+      break;
+    case MEAS_THETA: /* OK */
+      value.Flt = FromShortDegrees(measure[0].theta);
+      break;
+    case MEAS_MXX: /* OK */
+      value.Flt = FromShortPixels(measure[0].Mxx);
+      break;
+    case MEAS_MXY: /* OK */
+      value.Flt = FromShortPixels(measure[0].Mxy);
+      break;
+    case MEAS_MYY: /* OK */
+      value.Flt = FromShortPixels(measure[0].Myy);
+      break;
+    case MEAS_DOPHOT: /* OK */
+      value.Int = (measure[0].photFlags >> 16);
+      break;
+    case MEAS_DB_FLAGS: /* ? */
+      value.Int = measure[0].dbFlags;
+      break;
+    case MEAS_PHOT_FLAGS: /* ? */
+      value.Int = measure[0].photFlags;
+      break;
+    case MEAS_XCCD: /* OK */
+/* I need to perform this conversion for ELIXIR and LONEOS formats on load */      
+# if 1
+      value.Flt = measure[0].Xccd;
+# else
+      { 
+	Image *image;
+	ra  = average[0].R - measure[0].dR / 3600.0;
+	dec = average[0].D - measure[0].dD / 3600.0;
+	image = MatchImageDVO (measure[0].t, measure[0].photcode, measure[0].imageID);
+	if (image == NULL) break;
+	RD_to_XY (&x, &y, ra, dec, &image[0].coords);
+	value.Flt = x;
+      }
+# endif
+      break;
+    case MEAS_YCCD: /* OK */
+/* I need to perform this conversion for ELIXIR and LONEOS formats on load */      
+# if 1
+      value.Flt = measure[0].Yccd;
+# else
+      {
+	Image *image;
+	ra  = average[0].R - measure[0].dR / 3600.0;
+	dec = average[0].D - measure[0].dD / 3600.0;
+	image = MatchImageDVO (measure[0].t, measure[0].photcode, measure[0].imageID);
+	if (image == NULL) break;
+	RD_to_XY (&x, &y, ra, dec, &image[0].coords);
+	value.Flt = y;
+      }
+# endif
+      break;
+    case MEAS_XCCD_ERR: /* OK */
+      value.Flt = FromShortPixels(measure[0].dXccd);
+      break;
+    case MEAS_YCCD_ERR: /* OK */
+      value.Flt = FromShortPixels(measure[0].dYccd);
+      break;
+    case MEAS_POS_SYS_ERR: /* OK */
+      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 = MatchMosaic (measure[0].t, measure[0].photcode);
+      if (mosaic == NULL) break;
+      RD_to_XY (&x, &y, ra, dec, mosaic);
+      value.Flt = 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.Flt = y;
+      break;
+
+    case MEAS_SKY: /* OK */
+      value.Flt = measure[0].Sky;
+      break;
+    case MEAS_dSKY: /* OK */
+      value.Flt = measure[0].dSky;
+      break;
+    case MEAS_DET_ID: /* OK */
+      value.Int = measure[0].detID;
+      break;
+    case MEAS_OBJ_ID: /* OK */
+      value.Int = average[0].objID;
+      break;
+    case MEAS_CAT_ID: /* OK */
+      value.Int = average[0].catID;
+      break;
+    case MEAS_IMAGE_ID: /* OK */
+      value.Int = measure[0].imageID;
+      break;
+    case MEAS_PSF_QF: /* OK */
+      value.Flt = measure[0].psfQual;
+      break;
+    case MEAS_PSF_QF_PERFECT: /* OK */
+      value.Flt = NAN;
+      break;
+    case MEAS_PSF_CHISQ: /* OK */
+      value.Flt = measure[0].psfChisq;
+      break;
+    case MEAS_PSF_NDOF: /* OK */
+      value.Int = measure[0].psfNdof;
+      break;
+    case MEAS_PSF_NPIX: /* OK */
+      value.Int = measure[0].psfNpix;
+      break;
+    case MEAS_CR_NSIGMA: /* OK */
+      value.Flt = measure[0].crNsigma;
+      break;
+    case MEAS_EXT_NSIGMA: /* OK */
+      value.Flt = measure[0].extNsigma;
+      break;
+    case MEAS_EXTERN_ID: /* OK */
+      {
+	Image *image;
+	image = MatchImageDVO (measure[0].t, measure[0].photcode, measure[0].imageID);
+	if (image == NULL) break;
+	value.Int = image->externID;
+      }
+      break;
+
+      // add the star/galaxy sep -- 
+  }
+  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: /trunk/Ohana/src/libdvo/src/dbFields.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/dbFields.c	(revision 31635)
+++ /trunk/Ohana/src/libdvo/src/dbFields.c	(revision 31635)
@@ -0,0 +1,451 @@
+# include "dvo.h"
+
+void dbFreeFields (dbField *fields, int Nfields) {
+
+  int i;
+
+  if (fields == NULL) return;
+
+  for (i = 0; i < Nfields; i++) {
+    if (fields[i].name != NULL) free (fields[i].name);
+    if (fields[i].photcode != NULL) {
+      if (fields[i].photcode[0].type == PHOT_MAG) {
+        free (fields[i].photcode);
+      }
+    }
+  }
+  free (fields);
+}
+
+void dbInitField (dbField *field) {
+  field->name = NULL;
+  field->extract = FALSE;
+  field->table = 0;
+  field->ID = 0;
+  field->type = OPIHI_FLT;
+  field->magMode = 0;
+  field->photcode = NULL;
+}
+
+int GetMagMode (char *string) {
+
+  if (!strcasecmp (string, "inst"))      return (MAG_INST);
+  if (!strcasecmp (string, "cat"))       return (MAG_CAT);
+  if (!strcasecmp (string, "sys"))       return (MAG_SYS);
+  if (!strcasecmp (string, "rel"))       return (MAG_REL);
+  if (!strcasecmp (string, "cal"))       return (MAG_CAL);
+  if (!strcasecmp (string, "ave"))       return (MAG_AVE);
+  if (!strcasecmp (string, "ref"))       return (MAG_REF);
+  if (!strcasecmp (string, "ap"))        return (MAG_APER);
+  if (!strcasecmp (string, "aper"))      return (MAG_APER);
+  if (!strcasecmp (string, "err"))       return (MAG_ERR);
+  if (!strcasecmp (string, "aveerr"))    return (MAG_AVE_ERR);
+  if (!strcasecmp (string, "photflags")) return (MAG_PHOT_FLAGS);
+  if (!strcasecmp (string, "chisq"))     return (MAG_CHISQ);
+  if (!strcasecmp (string, "ncode"))     return (MAG_NCODE);
+  if (!strcasecmp (string, "nphot"))     return (MAG_NPHOT);
+  return (MAG_NONE);
+}
+
+PhotCode *ParsePhotcodeField (char *field, int *mode, int defMode) {
+
+  int useDefault;
+  char *tmpstring, *p;
+  PhotCode *code;
+
+  *mode = defMode;
+  useDefault = TRUE;
+
+  p = strchr (field, ':');
+  if (p != NULL) {
+    *mode = GetMagMode (p + 1);
+    useDefault = FALSE;
+    if (*mode == MAG_NONE) return (NULL);
+    tmpstring = strncreate (field, p - field);
+  } else {
+    tmpstring = strcreate (field);
+  }
+  if (!strcasecmp (tmpstring, "MAG")) {
+    ALLOCATE (code, PhotCode, 1);
+    code[0].code = 0;
+    strcpy (code[0].name, "MAG");
+    code[0].type = PHOT_MAG;
+    free (tmpstring);
+    return (code);
+  }
+  code = GetPhotcodebyName (tmpstring);
+  if (!code) {
+      return NULL;
+  }
+
+  // enforce compatibility
+  if (useDefault) {
+    if (code[0].type == PHOT_REF) {
+      *mode = MAG_CAT;
+    }
+    if (code[0].type == PHOT_DEP) {
+      *mode = MAG_REL;
+    }
+  } 
+  free (tmpstring);
+  return (code);
+}
+
+# define ESCAPE(F,M,T) { \
+  field->ID = (F); \
+  field->magMode = (M); \
+  field->type = (T); \
+  field->photcode = NULL; \
+  return (TRUE); }
+
+int ParseMeasureField (dbField *field, char *fieldName) {
+
+  int mode;
+  PhotCode *code;
+
+  field->table = DVO_TABLE_MEASURE;
+  field->name  = strcreate (fieldName);
+
+  if (!strcasecmp (fieldName, "GLON"))       {
+    dbExtractMeasuresInitTransform (COORD_GALACTIC);
+    ESCAPE (MEAS_GLON, MAG_NONE, OPIHI_FLT);
+  }
+  if (!strcasecmp (fieldName, "GLAT")) {
+    dbExtractMeasuresInitTransform (COORD_GALACTIC);
+    ESCAPE (MEAS_GLAT, MAG_NONE, OPIHI_FLT);
+  }
+  if (!strcasecmp (fieldName, "GLON:AVE")) {
+    dbExtractMeasuresInitTransform (COORD_GALACTIC);
+    ESCAPE (MEAS_GLON_AVE, MAG_NONE, OPIHI_FLT);
+  }
+  if (!strcasecmp (fieldName, "GLAT:AVE")) {
+    dbExtractMeasuresInitTransform (COORD_GALACTIC);
+    ESCAPE (MEAS_GLAT_AVE, MAG_NONE, OPIHI_FLT);
+  }
+
+  if (!strcasecmp (fieldName, "ELON"))       {
+    dbExtractMeasuresInitTransform (COORD_ECLIPTIC);
+    ESCAPE (MEAS_ELON, MAG_NONE, OPIHI_FLT);
+  }
+  if (!strcasecmp (fieldName, "ELAT")) {
+    dbExtractMeasuresInitTransform (COORD_ECLIPTIC);
+    ESCAPE (MEAS_ELAT, MAG_NONE, OPIHI_FLT);
+  }
+  if (!strcasecmp (fieldName, "ELON:AVE")) {
+    dbExtractMeasuresInitTransform (COORD_ECLIPTIC);
+    ESCAPE (MEAS_ELON_AVE, MAG_NONE, OPIHI_FLT);
+  }
+  if (!strcasecmp (fieldName, "ELAT:AVE")) {
+    dbExtractMeasuresInitTransform (COORD_ECLIPTIC);
+    ESCAPE (MEAS_ELAT_AVE, MAG_NONE, OPIHI_FLT);
+  }
+
+  if (!strcasecmp (fieldName, "RA"))         	 ESCAPE (MEAS_RA,             MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "DEC"))        	 ESCAPE (MEAS_DEC,            MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "RA:AVE"))     	 ESCAPE (MEAS_RA_AVE,         MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "DEC:AVE"))    	 ESCAPE (MEAS_DEC_AVE,        MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "RA:ERR"))     	 ESCAPE (MEAS_RA_AVE_ERR,     MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "DEC:ERR"))    	 ESCAPE (MEAS_DEC_AVE_ERR,    MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "uRA"))        	 ESCAPE (MEAS_U_RA,           MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "uDEC"))       	 ESCAPE (MEAS_U_DEC,          MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "duRA"))       	 ESCAPE (MEAS_U_RA_ERR,       MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "duDEC"))      	 ESCAPE (MEAS_U_DEC_ERR,      MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "PAR"))        	 ESCAPE (MEAS_PAR,            MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "dPAR"))       	 ESCAPE (MEAS_PAR_ERR,        MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "dR"))         	 ESCAPE (MEAS_RA_OFFSET,      MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "dD"))         	 ESCAPE (MEAS_DEC_OFFSET,     MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "dR:FIT"))     	 ESCAPE (MEAS_RA_FIT_OFFSET,  MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "dD:FIT"))     	 ESCAPE (MEAS_DEC_FIT_OFFSET, MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "dR:ERR"))     	 ESCAPE (MEAS_RA_OFFSET_ERR,  MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "dD:ERR"))     	 ESCAPE (MEAS_DEC_OFFSET_ERR, MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "ChiSqPos"))       ESCAPE (MEAS_CHISQ_POS,      MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "ChiSqPM"))        ESCAPE (MEAS_CHISQ_PM,       MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "ChiSqPar"))       ESCAPE (MEAS_CHISQ_PAR,      MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "Tmean"))          ESCAPE (MEAS_TMEAN,          MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "Trange"))         ESCAPE (MEAS_TRANGE,         MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "nmeas"))      	 ESCAPE (MEAS_NMEAS,          MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "nmiss"))      	 ESCAPE (MEAS_NMISS,          MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "npos"))      	 ESCAPE (MEAS_NPOS,           MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "OBJFLAGS"))   	 ESCAPE (MEAS_OBJ_FLAGS,      MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "OBJ_FLAGS"))   	 ESCAPE (MEAS_OBJ_FLAGS,      MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "DB_FLAGS"))   	 ESCAPE (MEAS_DB_FLAGS,       MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "PHOT_FLAGS")) 	 ESCAPE (MEAS_PHOT_FLAGS,     MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "DBFLAGS"))   	 ESCAPE (MEAS_DB_FLAGS,       MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "PHOTFLAGS")) 	 ESCAPE (MEAS_PHOT_FLAGS,     MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "AIRMASS"))    	 ESCAPE (MEAS_AIRMASS,        MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "ALT"))        	 ESCAPE (MEAS_ALT,            MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "AZ"))         	 ESCAPE (MEAS_AZ,             MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "EXPTIME"))    	 ESCAPE (MEAS_EXPTIME,        MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "PHOTCODE"))   	 ESCAPE (MEAS_PHOTCODE,       MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "PHOTCODE:EQUIV")) ESCAPE (MEAS_PHOTCODE_EQUIV, MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "TIME"))       	 ESCAPE (MEAS_TIME,           MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "FWHM"))       	 ESCAPE (MEAS_FWHM,           MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "FWHM_MAJ"))   	 ESCAPE (MEAS_FWHM_MAJ,       MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "FWHM_MIN"))   	 ESCAPE (MEAS_FWHM_MIN,       MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "THETA"))      	 ESCAPE (MEAS_THETA,          MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "POSANGLE"))     	 ESCAPE (MEAS_POSANGLE,       MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "PLATESCALE"))   	 ESCAPE (MEAS_PLATESCALE,     MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "MXX"))       	 ESCAPE (MEAS_MXX,            MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "MYY"))       	 ESCAPE (MEAS_MYY,            MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "MXY"))       	 ESCAPE (MEAS_MXY,            MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "DOPHOT"))     	 ESCAPE (MEAS_DOPHOT,         MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "XCCD"))       	 ESCAPE (MEAS_XCCD,           MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "YCCD"))       	 ESCAPE (MEAS_YCCD,           MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "XCCD:ERR"))   	 ESCAPE (MEAS_XCCD_ERR,       MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "YCCD:ERR"))   	 ESCAPE (MEAS_YCCD_ERR,       MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "POS_SYS_ERR"))    ESCAPE (MEAS_POS_SYS_ERR,    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);
+  if (!strcasecmp (fieldName, "XCHIP"))      	 ESCAPE (MEAS_XCCD,           MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "YCHIP"))      	 ESCAPE (MEAS_YCCD,           MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "XFPA"))       	 ESCAPE (MEAS_XMOSAIC,        MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "YFPA"))       	 ESCAPE (MEAS_YMOSAIC,        MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "DETID"))      	 ESCAPE (MEAS_DET_ID,         MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "OBJID"))      	 ESCAPE (MEAS_OBJ_ID,         MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "CATID"))      	 ESCAPE (MEAS_CAT_ID,         MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "IMAGEID"))    	 ESCAPE (MEAS_IMAGE_ID,       MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "PSF_QF"))     	 ESCAPE (MEAS_PSF_QF,         MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "PSF_QF_PERFECT")) ESCAPE (MEAS_PSF_QF_PERFECT, MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "PSF_CHISQ"))  	 ESCAPE (MEAS_PSF_CHISQ,      MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "PSF_NDOF"))  	 ESCAPE (MEAS_PSF_NDOF,       MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "PSF_NPIX"))  	 ESCAPE (MEAS_PSF_NPIX,       MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "CR_NSIGMA"))  	 ESCAPE (MEAS_CR_NSIGMA,      MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "EXT_NSIGMA")) 	 ESCAPE (MEAS_EXT_NSIGMA,     MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "SKY"))        	 ESCAPE (MEAS_SKY,            MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "SKY_ERR"))    	 ESCAPE (MEAS_dSKY,           MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "externID"))    	 ESCAPE (MEAS_EXTERN_ID,      MAG_NONE, OPIHI_INT);
+
+  // for words that don't parse, try a photcode
+
+  // check for code:mode in photcode name 
+  code = ParsePhotcodeField (fieldName, &mode, MAG_REL);
+  if (code == NULL) {
+    gprint (GP_ERR, "unknown field '%s' for measurement table in DVO database\n", fieldName);
+    return (FALSE);
+  }
+
+  field->ID = MEAS_MAG;
+  field->magMode = mode;
+  switch (mode) {
+    case MAG_NCODE:
+    case MAG_NPHOT:
+    case MAG_PHOT_FLAGS:
+      field->type = OPIHI_INT;
+      break;
+    default:
+      field->type = OPIHI_FLT;
+      break;
+  }
+  field->photcode = code;
+  return (TRUE);
+}
+
+int ParseAverageField (dbField *field, char *fieldName) {
+
+  int mode;
+  PhotCode *code;
+
+  field->table = DVO_TABLE_AVERAGE;
+  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"))  { 
+    dbExtractAveragesInitTransform (COORD_GALACTIC);
+    ESCAPE (AVE_GLON, MAG_NONE, OPIHI_FLT);
+  }
+  if (!strcasecmp (fieldName, "GLAT"))  {
+    dbExtractAveragesInitTransform (COORD_GALACTIC);
+    ESCAPE (AVE_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"))  { 
+    dbExtractAveragesInitTransform (COORD_ECLIPTIC);
+    ESCAPE (AVE_ELON, MAG_NONE, OPIHI_FLT);
+  }
+  if (!strcasecmp (fieldName, "ELAT"))  {
+    dbExtractAveragesInitTransform (COORD_ECLIPTIC);
+    ESCAPE (AVE_ELAT, MAG_NONE, OPIHI_FLT);
+  }
+
+  if (!strcasecmp (fieldName, "RA"))        ESCAPE (AVE_RA,        MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "DEC"))       ESCAPE (AVE_DEC,       MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "GLON"))      ESCAPE (AVE_GLON,      MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "GLAT"))      ESCAPE (AVE_GLAT,      MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "ELON"))      ESCAPE (AVE_ELON,      MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "ELAT"))      ESCAPE (AVE_ELAT,      MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "dRA"))       ESCAPE (AVE_RA_ERR,    MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "dDEC"))      ESCAPE (AVE_DEC_ERR,   MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "uRA"))       ESCAPE (AVE_U_RA,      MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "uDEC"))      ESCAPE (AVE_U_DEC,     MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "duRA"))      ESCAPE (AVE_U_RA_ERR,  MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "duDEC"))     ESCAPE (AVE_U_DEC_ERR, MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "PAR"))       ESCAPE (AVE_PAR,       MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "dPAR"))      ESCAPE (AVE_PAR_ERR,   MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "ChiSqPos"))  ESCAPE (AVE_CHISQ_POS, MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "ChiSqPM"))   ESCAPE (AVE_CHISQ_PM, MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "ChiSqPar"))  ESCAPE (AVE_CHISQ_PAR, MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "Tmean"))     ESCAPE (AVE_TMEAN,     MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "Trange"))    ESCAPE (AVE_TRANGE,    MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "NMEAS"))     ESCAPE (AVE_NMEAS,     MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "NMISS"))     ESCAPE (AVE_NMISS,     MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "NPOS"))      ESCAPE (AVE_NPOS,      MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "NASTROM"))   ESCAPE (AVE_NPOS,      MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "FLAGS"))     ESCAPE (AVE_OBJ_FLAGS, MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "OBJ_FLAGS")) ESCAPE (AVE_OBJ_FLAGS, MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "OBJFLAGS"))  ESCAPE (AVE_OBJ_FLAGS, MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "OBJID"))     ESCAPE (AVE_OBJID,     MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "CATID"))     ESCAPE (AVE_CATID,     MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "EXTID_HI"))  ESCAPE (AVE_EXTID_HI,  MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "EXTID_LO"))  ESCAPE (AVE_EXTID_LO,  MAG_NONE, OPIHI_INT);
+
+  // if (!strcasecmp (fieldName, "Xp"))      ESCAPE (AVE_Xp,        MAG_NONE, OPIHI_FLT);
+  // if (!strcasecmp (fieldName, "TYPE"))    ESCAPE (AVE_TYPE,      MAG_NONE, OPIHI_INT);
+  // for words that don't parse, try a photcode
+
+  // check for code:mode in photcode name 
+  code = ParsePhotcodeField (fieldName, &mode, MAG_AVE);
+  if (code == NULL) {
+    gprint (GP_ERR, "unknown field '%s' for average table in DVO database\n", fieldName);
+    return (FALSE);
+  }
+
+  if (code[0].type == PHOT_MAG) {
+    gprint (GP_ERR, "'mag' is ambiguous for avextract\n");
+    free (code);
+    return (FALSE);
+  }
+
+  field->ID = AVE_MAG;
+  field->magMode = mode;
+  switch (mode) {
+    case MAG_NCODE:
+    case MAG_NPHOT:
+    case MAG_PHOT_FLAGS:
+      field->type = OPIHI_INT;
+      break;
+    default:
+      field->type = OPIHI_FLT;
+      break;
+  }
+  field->photcode = code;
+  return (TRUE);
+}
+
+
+int ParseImageField (dbField *field, char *fieldName) {
+
+  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, "GLON"     )) ESCAPE (IMAGE_GLON,      MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "GLAT"     )) ESCAPE (IMAGE_GLAT,      MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "ELON"     )) ESCAPE (IMAGE_ELON,      MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "ELAT"     )) ESCAPE (IMAGE_ELAT,      MAG_NONE, OPIHI_FLT);
+
+  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, "time"     )) ESCAPE (IMAGE_TIME,      MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "nstar"    )) ESCAPE (IMAGE_NSTAR,     MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "airmass"  )) ESCAPE (IMAGE_AIRMASS,   MAG_NONE, OPIHI_FLT);
+  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, "apresid"  )) ESCAPE (IMAGE_APRESID,   MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "dapresid" )) ESCAPE (IMAGE_DAPRESID,  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, "Xm"       )) ESCAPE (IMAGE_XM,        MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "photcode" )) ESCAPE (IMAGE_PHOTCODE,  MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "exptime"  )) ESCAPE (IMAGE_EXPTIME,   MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "sidtime"  )) ESCAPE (IMAGE_SIDTIME,   MAG_NONE, OPIHI_FLT);
+
+  if (!strcasecmp (fieldName, "latitude" )) ESCAPE (IMAGE_LATITUDE,  MAG_NONE, OPIHI_FLT);
+
+  if (!strcasecmp (fieldName, "detlimit" )) ESCAPE (IMAGE_DET_LIMIT, MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "satlimit" )) ESCAPE (IMAGE_SAT_LIMIT, MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "cerror"   )) ESCAPE (IMAGE_CERROR,    MAG_NONE, OPIHI_FLT);
+
+  if (!strcasecmp (fieldName, "FWHM"       )) ESCAPE (IMAGE_FWHM,      MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "FWHM_MAJ"   )) ESCAPE (IMAGE_FWHM_MAJ,  MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "FWHM_MIN"   )) ESCAPE (IMAGE_FWHM_MIN,  MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "FWHM_MAJOR" )) ESCAPE (IMAGE_FWHM_MAJ,  MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "FWHM_MINOR" )) ESCAPE (IMAGE_FWHM_MIN,  MAG_NONE, OPIHI_FLT);
+
+  if (!strcasecmp (fieldName, "FWHM_MEDIAN"    ))   ESCAPE (IMAGE_FWHM_MEDIAN,      MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "FWHM_MAJ_MEDIAN"))   ESCAPE (IMAGE_FWHM_MAJ_MEDIAN,  MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "FWHM_MIN_MEDIAN"))   ESCAPE (IMAGE_FWHM_MIN_MEDIAN,  MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "FWHM_MAJOR_MEDIAN")) ESCAPE (IMAGE_FWHM_MAJ_MEDIAN,  MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "FWHM_MINOR_MEDIAN")) ESCAPE (IMAGE_FWHM_MIN_MEDIAN,  MAG_NONE, OPIHI_FLT);
+
+  if (!strcasecmp (fieldName, "trate"    )) ESCAPE (IMAGE_TRATE,     MAG_NONE, OPIHI_FLT);
+
+  if (!strcasecmp (fieldName, "ncal"     )) ESCAPE (IMAGE_NCAL,      MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "sky"      )) ESCAPE (IMAGE_SKY,       MAG_NONE, OPIHI_FLT); // deprecated for now
+
+  if (!strcasecmp (fieldName, "imflags"  )) ESCAPE (IMAGE_FLAGS,     MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "flags"    )) ESCAPE (IMAGE_FLAGS,     MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "ccdnum"   )) ESCAPE (IMAGE_CCDNUM,    MAG_NONE, OPIHI_INT);
+
+  if (!strcasecmp (fieldName, "imageID"  )) ESCAPE (IMAGE_IMAGE_ID,  MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "externID" )) ESCAPE (IMAGE_EXTERN_ID, MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "sourceID" )) ESCAPE (IMAGE_SOURCE_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);
+
+  if (!strcasecmp (fieldName, "dX_SYS"  )) ESCAPE (IMAGE_X_ERR_SYS,  MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "dY_SYS"  )) ESCAPE (IMAGE_Y_ERR_SYS,  MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "dM_SYS"  )) ESCAPE (IMAGE_MAG_ERR_SYS,MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "NFIT_PHOTOM")) ESCAPE (IMAGE_NFIT_PHOTOM,MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "NFIT_ASTROM")) ESCAPE (IMAGE_NFIT_ASTROM,MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "NLINK_PHOTOM")) ESCAPE (IMAGE_NLINK_PHOTOM,MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "NLINK_ASTROM")) ESCAPE (IMAGE_NLINK_ASTROM,MAG_NONE, OPIHI_INT);
+
+  // for words that don't parse, try a photcode
+  gprint (GP_ERR, "unknown field '%s' for image table in DVO database\n", fieldName);
+  return (FALSE);
+}
Index: /trunk/Ohana/src/libdvo/src/dbRPN.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/dbRPN.c	(revision 31635)
+++ /trunk/Ohana/src/libdvo/src/dbRPN.c	(revision 31635)
@@ -0,0 +1,206 @@
+# include "dvo.h"
+# define DUMPSTACK 0
+
+dbStack *dbRPN (int argc, char **argv, int *nstack) {
+  
+  int type, Nx, Ny;
+  int i, j, Nstack, Nop_stack, NSTACK;
+  dbStack *stack, *op_stack;
+
+  /* max total stack size is argc, though should be less, this is safe */
+  NSTACK = argc + 5;
+  ALLOCATE (stack, dbStack, NSTACK);
+  ALLOCATE (op_stack, dbStack, NSTACK);
+  for (i = 0; i < NSTACK; i++) {
+    dbInitStack (&stack[i]);
+    dbInitStack (&op_stack[i]);
+  }
+  
+  Nx = Ny = Nstack = Nop_stack = 0;
+  for (i = 0; i < argc; i++) {
+    
+    /* decide on priority of object */
+    type = DB_STACK_NONE;
+    /* unary operations */
+    if (!strcmp (argv[i], "abs"))    { type = DB_STACK_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "int"))    { type = DB_STACK_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "exp"))    { type = DB_STACK_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "ten"))    { type = DB_STACK_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "log"))    { type = DB_STACK_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "ln"))     { type = DB_STACK_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "sqrt"))   { type = DB_STACK_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "erf"))    { type = DB_STACK_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "sinh"))   { type = DB_STACK_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "cosh"))   { type = DB_STACK_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "asinh"))  { type = DB_STACK_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "acosh"))  { type = DB_STACK_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "sin"))    { type = DB_STACK_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "cos"))    { type = DB_STACK_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "tan"))    { type = DB_STACK_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "dsin"))   { type = DB_STACK_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "dcos"))   { type = DB_STACK_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "dtan"))   { type = DB_STACK_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "asin"))   { type = DB_STACK_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "acos"))   { type = DB_STACK_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "atan"))   { type = DB_STACK_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "dasin"))  { type = DB_STACK_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "dacos"))  { type = DB_STACK_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "datan"))  { type = DB_STACK_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "lgamma")) { type = DB_STACK_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "rnd"))    { type = DB_STACK_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "xramp"))  { type = DB_STACK_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "yramp"))  { type = DB_STACK_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "ramp"))   { type = DB_STACK_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "zero"))   { type = DB_STACK_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "--"))     { type = DB_STACK_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "not"))    { type = DB_STACK_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "isinf"))  { type = DB_STACK_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "isnan"))  { type = DB_STACK_UNARY; goto gotit; }
+
+    /* binary operations */
+    if (!strcmp (argv[i], "^"))      { type = DB_STACK_POWER; goto gotit; }
+
+    if (!strcmp (argv[i], "@"))      { type = DB_STACK_MULTIPLY; goto gotit; }
+    if (!strcmp (argv[i], "/"))      { type = DB_STACK_MULTIPLY; goto gotit; }
+    if (!strcmp (argv[i], "*"))      { type = DB_STACK_MULTIPLY; goto gotit; }
+    if (!strcmp (argv[i], "%"))      { type = DB_STACK_MULTIPLY; goto gotit; }
+
+    if (!strcmp (argv[i], "+"))      { type = DB_STACK_SUM; goto gotit; }
+    if (!strcmp (argv[i], "-"))      { type = DB_STACK_SUM; goto gotit; }
+	
+    if (!strcmp (argv[i], "&"))      { type = DB_STACK_BITWISE; goto gotit; }
+    if (!strcmp (argv[i], "|"))      { type = DB_STACK_BITWISE; goto gotit; }
+
+    if (!strcmp (argv[i], "<"))      { type = DB_STACK_COMPARE; goto gotit; }
+    if (!strcmp (argv[i], ">"))      { type = DB_STACK_COMPARE; goto gotit; }
+    if (!strcmp (argv[i], "=="))     { type = DB_STACK_COMPARE; strcpy (argv[i], "E"); goto gotit; }
+    if (!strcmp (argv[i], "!="))     { type = DB_STACK_COMPARE; strcpy (argv[i], "N"); goto gotit; }
+    if (!strcmp (argv[i], "<="))     { type = DB_STACK_COMPARE; strcpy (argv[i], "L"); goto gotit; }
+    if (!strcmp (argv[i], ">="))     { type = DB_STACK_COMPARE; strcpy (argv[i], "G"); goto gotit; }
+    if (!strcmp (argv[i], ">>"))     { type = DB_STACK_COMPARE; strcpy (argv[i], "U"); goto gotit; }
+    if (!strcmp (argv[i], "<<"))     { type = DB_STACK_COMPARE; strcpy (argv[i], "D"); goto gotit; }
+
+    if (!strcmp (argv[i], "&&"))     { type = DB_STACK_LOGIC; strcpy (argv[i], "A"); goto gotit; }
+    if (!strcmp (argv[i], "||"))     { type = DB_STACK_LOGIC; strcpy (argv[i], "O"); goto gotit; }
+
+    if (!strcmp (argv[i], "("))      { type = DB_STACK_OPEN_PAR; goto gotit; }
+    if (!strcmp (argv[i], ")"))      { type = DB_STACK_CLOSE_PAR; goto gotit; }
+
+  gotit:
+    /* choose how to deal with object */
+    switch (type) {
+      case DB_STACK_POWER:  /* exponentiation: 2^2^3 = 64 != 256 (precedence is right-to-left, not left-to-right!) */
+	/* pop previous, higher operators from OP stack to stack */
+	for (j = Nop_stack - 1; (j >= 0) && (op_stack[j].type > type); j--) {
+	  stack[Nstack] = op_stack[j];
+	  op_stack[j].name = NULL;
+	  Nstack ++;
+	  Nop_stack --;
+	}
+	/* push operator on OP stack */
+	op_stack[Nop_stack].name = strcreate (argv[i]);
+	op_stack[Nop_stack].type = type;
+	Nop_stack ++;
+	break;
+      case DB_STACK_UNARY: /* unary OPs */
+      case DB_STACK_MULTIPLY: /* binary OPs */
+      case DB_STACK_SUM:
+      case DB_STACK_BITWISE: 
+      case DB_STACK_COMPARE: 
+      case DB_STACK_LOGIC: 
+	/* pop previous, higher or equal operators from OP stack to stack */
+	for (j = Nop_stack - 1; (j >= 0) && (op_stack[j].type >= type); j--) {
+	  stack[Nstack] = op_stack[j];
+	  op_stack[j].name = NULL;
+	  Nstack ++;
+	  Nop_stack --;
+	}
+	/* push operator on OP stack */
+	op_stack[Nop_stack].name = strcreate (argv[i]);
+	op_stack[Nop_stack].type = type;
+	Nop_stack ++;
+	break;
+      case DB_STACK_OPEN_PAR:  
+	/* push operator on OP stack */
+	op_stack[Nop_stack].name = strcreate (argv[i]);
+	op_stack[Nop_stack].type = type;
+	Nop_stack ++;
+	break;
+      case DB_STACK_CLOSE_PAR: 
+	/* pop rest of operators from OP stack to stack, looking for '(' */
+	for (j = Nop_stack - 1; (j >= 0) && (op_stack[j].type != DB_STACK_OPEN_PAR); j--) {
+	  stack[Nstack] = op_stack[j];
+	  op_stack[j].name = NULL;
+	  Nstack ++;
+	  Nop_stack --;
+	}
+	if ((j == -1) || (op_stack[j].type != DB_STACK_OPEN_PAR)) {
+	  push_error ("syntax error: mismatched parenthesis");
+	  Nstack = 0;
+	  goto cleanup;
+	}
+	Nop_stack --;
+	break;
+      case 0:
+	/* place the value (number or vector/matrix name) on stack */
+	/* value of 'X' is used as sentinel until we sort out values */
+	stack[Nstack].name = strcreate (argv[i]);
+	stack[Nstack].type = DB_STACK_VALUE;
+	Nstack ++;
+	break;
+    }
+  }
+
+  /* dump remaining operators on stack, checking for '(' */
+  for (j = Nop_stack - 1; j >= 0; j--) {
+    if (op_stack[j].type == DB_STACK_OPEN_PAR) {
+      push_error ("syntax error: mismatched parenthesis");
+      Nstack = 0;
+      goto cleanup;
+    }
+    stack[Nstack] = op_stack[j];
+    op_stack[j].name = NULL;
+    Nstack ++;
+  }
+
+cleanup: 
+  /*** free up unused stack space ***/
+  dbFreeStack (op_stack, NSTACK);
+  free (op_stack);
+  dbFreeStack (&stack[Nstack], NSTACK - Nstack);
+  REALLOCATE (stack, dbStack, MAX (Nstack, 1));
+  *nstack = Nstack;
+
+  for (i = 0; i < argc; i++) {
+    free (argv[i]);
+  }
+  free (argv);
+
+# if (DUMPSTACK)
+  for (i = 0; i < Nstack; i++) {
+    gprint (GP_ERR, "%s ", stack[i].name);
+  }
+  if (Nstack > 0) gprint (GP_ERR, "\n");
+  for (i = 0; i < Nstack; i++) {
+    gprint (GP_ERR, "%d ", stack[i].type);
+  }
+  if (Nstack > 0) gprint (GP_ERR, "\n");
+# endif
+
+  return (stack);
+
+}
+
+/* here are the rules for parsing a math AOL expression to RPN:
+
+1) if object is a number, push on stack
+2) if object is a third order operand (exp, sin, cos), push on op stack
+3) if object is an open paren, push on op stack,
+4) if object is a second order operand, push on stack
+5) if object is a first order operand, pop all second order operands from stack 
+until paren, push on stack
+6) if object is an end paren, pop all objects from stack until paren, 
+pop next stack, if third order op
+7) if end of line, pop all remaining objects, second order first, etc.
+   
+*/
Index: /trunk/Ohana/src/libdvo/src/dbStackMath.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/dbStackMath.c	(revision 31635)
+++ /trunk/Ohana/src/libdvo/src/dbStackMath.c	(revision 31635)
@@ -0,0 +1,151 @@
+# include "dvo.h"
+
+static int NallocBinary = 0;
+static int NallocUnary = 0;
+
+dbStack *dbBinary (dbStack *V1, dbStack *V2, char *op, dbValue *fields) {
+
+  dbStack *OUT;
+  
+# define SS_FUNC(OP) {							\
+    if (!(V1->type & DB_STACK_INT) && !(V2->type & DB_STACK_INT)) {	\
+      opihi_flt M1 = (V1->type & DB_STACK_FIELD) ? fields[V1->field].Flt : V1->FltValue; \
+      opihi_flt M2 = (V2->type & DB_STACK_FIELD) ? fields[V2->field].Flt : V2->FltValue; \
+      OUT[0].type = DB_STACK_VALUE | DB_STACK_TEMP;			\
+      OUT[0].FltValue = OP;						\
+      break;								\
+    }									\
+    if ((V1->type & DB_STACK_INT) && !(V2->type & DB_STACK_INT)) {	\
+      opihi_int M1 = (V1->type & DB_STACK_FIELD) ? fields[V1->field].Int : V1->IntValue; \
+      opihi_flt M2 = (V2->type & DB_STACK_FIELD) ? fields[V2->field].Flt : V2->FltValue; \
+      OUT[0].type = DB_STACK_VALUE | DB_STACK_TEMP;			\
+      OUT[0].FltValue = OP;						\
+      break;								\
+    }									\
+    if (!(V1->type & DB_STACK_INT) && (V2->type & DB_STACK_INT)) {	\
+      opihi_flt M1 = (V1->type & DB_STACK_FIELD) ? fields[V1->field].Flt : V1->FltValue; \
+      opihi_int M2 = (V2->type & DB_STACK_FIELD) ? fields[V2->field].Int : V2->IntValue; \
+      OUT[0].type = DB_STACK_VALUE | DB_STACK_TEMP;			\
+      OUT[0].FltValue = OP;						\
+      break;								\
+    }									\
+    if ((V1->type & DB_STACK_INT) && (V2->type & DB_STACK_INT)) {	\
+      opihi_int M1 = (V1->type & DB_STACK_FIELD) ? fields[V1->field].Int : V1->IntValue; \
+      opihi_int M2 = (V2->type & DB_STACK_FIELD) ? fields[V2->field].Int : V2->IntValue; \
+      OUT[0].type = DB_STACK_VALUE | DB_STACK_TEMP | DB_STACK_INT;	\
+      OUT[0].IntValue = OP;						\
+      break;								\
+    }									\
+  }
+
+  NallocBinary ++;
+  ALLOCATE (OUT, dbStack, 1);
+  OUT->name = NULL;
+
+  // XXX use an enum for the op...
+  switch (op[0]) { 
+    case '+': SS_FUNC(M1 + M2);
+    case '-': SS_FUNC(M1 - M2);
+    case '*': SS_FUNC(M1 * M2);
+    case '/': SS_FUNC(M1 / M2);
+    case '%': SS_FUNC((int) M1 % (int) M2);
+    case '^': SS_FUNC(pow (M1, M2));
+    case 'D': SS_FUNC(MIN (M1, M2));
+    case 'U': SS_FUNC(MAX (M1, M2));
+    case '<': SS_FUNC((M1 < M2) ? 1 : 0);
+    case '>': SS_FUNC((M1 > M2) ? 1 : 0);
+    case '&': SS_FUNC(((int)M1 & (int)M2));
+    case '|': SS_FUNC(((int)M1 | (int)M2));
+    case 'E': SS_FUNC((M1 == M2) ? 1 : 0);
+    case 'N': SS_FUNC((M1 != M2) ? 1 : 0);
+    case 'L': SS_FUNC((M1 <= M2) ? 1 : 0);
+    case 'G': SS_FUNC((M1 >= M2) ? 1 : 0);
+    case 'A': SS_FUNC((M1 && M2) ? 1 : 0);
+    case 'O': SS_FUNC((M1 || M2) ? 1 : 0);
+  default:
+    return (NULL);
+  }
+# undef SS_FUNC
+  
+  return (OUT);
+}
+
+dbStack *dbUnary (dbStack *V1, char *op, dbValue *fields) {
+
+  dbStack *OUT;
+  
+# define S_FUNC(OP,FTYPE) {						\
+    if (!(V1->type & DB_STACK_INT)) {					\
+      opihi_flt M1 = (V1->type & DB_STACK_FIELD) ? fields[V1->field].Flt : V1->FltValue; \
+      OUT[0].type = DB_STACK_VALUE | DB_STACK_TEMP;			\
+      OUT[0].FltValue = OP;						\
+      return (OUT);							\
+    }									\
+    if ((FTYPE != DB_STACK_INT) && (V1->type & DB_STACK_INT)) {		\
+      opihi_int M1 = (V1->type & DB_STACK_FIELD) ? fields[V1->field].Int : V1->IntValue; \
+      OUT[0].type = DB_STACK_VALUE | DB_STACK_TEMP;			\
+      OUT[0].FltValue = OP;						\
+      return (OUT);							\
+    }									\
+    if ((FTYPE == DB_STACK_INT) && (V1->type & DB_STACK_INT)) {		\
+      opihi_int M1 = (V1->type & DB_STACK_FIELD) ? fields[V1->field].Int : V1->IntValue; \
+      OUT[0].type = DB_STACK_VALUE | DB_STACK_TEMP | DB_STACK_INT;	\
+      OUT[0].IntValue = OP;						\
+      return (OUT);							\
+    }									\
+  }
+
+  NallocUnary ++;
+  ALLOCATE (OUT, dbStack, 1);
+  OUT->name = NULL;
+
+  if (!strcmp (op, "="))      S_FUNC(M1,0);
+  if (!strcmp (op, "abs"))    S_FUNC(fabs(M1),0);
+  if (!strcmp (op, "int"))    S_FUNC((int)(M1),DB_STACK_INT);
+  if (!strcmp (op, "exp"))    S_FUNC(exp (M1),0);
+  if (!strcmp (op, "ten"))    S_FUNC(pow (10.0,M1),0);
+  if (!strcmp (op, "log"))    S_FUNC(log10 (M1),0);
+  if (!strcmp (op, "ln"))     S_FUNC(log (M1),0);
+  if (!strcmp (op, "sqrt"))   S_FUNC(sqrt (M1),0);
+  if (!strcmp (op, "erf"))    S_FUNC(erf (M1),0);
+
+  if (!strcmp (op, "sinh"))   S_FUNC(sinh (M1),0);
+  if (!strcmp (op, "cosh"))   S_FUNC(cosh (M1),0);
+  if (!strcmp (op, "asinh"))  S_FUNC(asinh (M1),0);
+  if (!strcmp (op, "acosh"))  S_FUNC(acosh (M1),0);
+  if (!strcmp (op, "lgamma")) S_FUNC(lgamma (M1),0);
+
+  if (!strcmp (op, "sin"))    S_FUNC(sin (M1),0);
+  if (!strcmp (op, "cos"))    S_FUNC(cos (M1),0);
+  if (!strcmp (op, "tan"))    S_FUNC(tan (M1),0);
+  if (!strcmp (op, "dsin"))   S_FUNC(sin (M1*RAD_DEG),0);
+  if (!strcmp (op, "dcos"))   S_FUNC(cos (M1*RAD_DEG),0);
+  if (!strcmp (op, "dtan"))   S_FUNC(tan (M1*RAD_DEG),0);
+  if (!strcmp (op, "asin"))   S_FUNC(asin (M1),0);
+  if (!strcmp (op, "acos"))   S_FUNC(acos (M1),0);
+  if (!strcmp (op, "atan"))   S_FUNC(atan (M1),0);
+  if (!strcmp (op, "dasin"))  S_FUNC(asin (M1)*DEG_RAD,0);
+  if (!strcmp (op, "dacos"))  S_FUNC(acos (M1)*DEG_RAD,0);
+  if (!strcmp (op, "datan"))  S_FUNC(atan (M1)*DEG_RAD,0);
+  if (!strcmp (op, "rnd"))    S_FUNC(M1*0.0 + drand48(),0);
+  if (!strcmp (op, "not"))    S_FUNC(!(M1),DB_STACK_INT);
+  if (!strcmp (op, "--"))     S_FUNC(- (M1),DB_STACK_INT);
+  if (!strcmp (op, "isinf"))  S_FUNC(!finite(M1),DB_STACK_INT);
+  if (!strcmp (op, "isnan"))  S_FUNC(isnan(M1),DB_STACK_INT);
+
+  return (OUT);
+}
+
+int dbStackAllocPrint () {
+
+  fprintf (stderr, "dbAllocBinary: %d\n", NallocBinary);
+  fprintf (stderr, "dbAllocUnary:  %d\n", NallocUnary);
+  return (TRUE);
+}
+
+int dbStackAllocReset () {
+
+  NallocBinary = 0;
+  NallocUnary = 0;
+  return (TRUE);
+}
Index: /trunk/Ohana/src/libdvo/src/dbStackOps.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/dbStackOps.c	(revision 31635)
+++ /trunk/Ohana/src/libdvo/src/dbStackOps.c	(revision 31635)
@@ -0,0 +1,54 @@
+# include "dvo.h"
+
+void dbInitStack (dbStack *stack) {
+  stack[0].type   = DB_STACK_NONE;
+  stack[0].name   = NULL;
+  stack[0].field  = 0;
+  stack[0].FltValue = 0.0;
+  stack[0].IntValue = 0;
+}
+
+// free data for stack entries (free stack explicitly)
+void dbFreeStack (dbStack *stack, int Nstack) {
+
+  int i;
+
+  if (stack == NULL) return;
+
+  for (i = 0; i < Nstack; i++) {
+    if (stack[i].name != NULL) {
+      free (stack[i].name);
+      stack[i].name = NULL;
+    }
+  }
+}
+
+static int NfreeStack = 0;
+
+/* delete name and data */
+void dbFreeEntry (dbStack *stack) {
+
+  if (stack[0].name != NULL)  free (stack[0].name);
+  free (stack);
+  NfreeStack ++;
+}
+
+/* delete name and data */
+void dbFreeTempEntry (dbStack *stack) {
+
+  if (!(stack->type & DB_STACK_TEMP)) return;
+
+  if (stack[0].name != NULL)  free (stack[0].name);
+  free (stack);
+  NfreeStack ++;
+}
+
+void dbStackFreePrint () {
+
+  fprintf (stderr, "dbFreeStack: %d\n", NfreeStack);
+}
+
+void dbStackFreeReset () {
+
+  NfreeStack = 0;
+}
Index: /trunk/Ohana/src/libdvo/src/db_utils.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/db_utils.c	(revision 31635)
+++ /trunk/Ohana/src/libdvo/src/db_utils.c	(revision 31635)
@@ -0,0 +1,28 @@
+# include "dvo.h"
+
+// This file contains some functions used by the libdvo db lookup functions
+// that are really specific to dvo.
+//
+// These are declared weak so they can be overridden by the program.
+
+// overridden for opihi in opihi/lib.data/open_kapa.c
+// by default, no graphdata 
+int GetGraphdata(Graphdata *graph, int *kapa, char *name) {
+    return FALSE;
+}
+
+// overridden for opihi programs in opihi/lib.shell/timeformat.c
+int
+GetTimeFormat(time_t *TimeReference, int *TimeFormat) {
+    *TimeReference = 0;
+    *TimeFormat = TIME_SECONDS;
+    return (TRUE);
+}
+
+// overridden for dvo in opihi/dvo/photometry.c
+int GetTimeSelection (time_t *tz, time_t *te) {
+
+  *tz = 0;
+  *te = 0;
+  return (TRUE);
+}
Index: /trunk/Ohana/src/libdvo/src/dvo_set_catdir.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/dvo_set_catdir.c	(revision 31635)
+++ /trunk/Ohana/src/libdvo/src/dvo_set_catdir.c	(revision 31635)
@@ -0,0 +1,19 @@
+# include "ohana.h"
+
+// functions to set and get the current catdir.
+static char *current_catdir = NULL;
+
+char * dvo_get_catdir() {
+
+  return current_catdir;
+}
+
+void dvo_set_catdir (char *catdir) {
+    if (current_catdir) {
+        free(current_catdir);
+        current_catdir = NULL;
+    }
+    if (catdir) {
+        current_catdir = strdup(catdir);
+    }
+}
Index: /trunk/Ohana/src/libdvo/src/dvo_set_skyregion.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/dvo_set_skyregion.c	(revision 31635)
+++ /trunk/Ohana/src/libdvo/src/dvo_set_skyregion.c	(revision 31635)
@@ -0,0 +1,25 @@
+# include "ohana.h"
+
+// functions to set and get the current skyregion.
+static double RAs = 0.0;
+static double RAe = 0.0;
+static double DECs = 0.0;
+static double DECe = 0.0;
+
+int get_skyregion (double *Rs, double *Re, double *Ds, double *De) {
+  *Rs = RAs;
+  *Re = RAe;
+  *Ds = DECs;
+  *De = DECe;
+
+  return TRUE;
+}
+
+int set_skyregion (double Rs, double Re, double Ds, double De) {
+  RAs  = Rs;
+  RAe  = Re;
+  DECs = Ds;
+  DECe = De;
+
+  return TRUE;
+}
Index: /trunk/Ohana/src/libdvo/src/match_image.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/match_image.c	(revision 31635)
+++ /trunk/Ohana/src/libdvo/src/match_image.c	(revision 31635)
@@ -0,0 +1,73 @@
+# include "dvo.h"
+
+off_t match_image (Image *image, off_t Nimage, unsigned int T, short int S) {
+
+  off_t N, Nlo, Nhi, N1, N2;
+
+  /* bracket first value of interest */
+  Nlo = 0; Nhi = Nimage;
+  while (Nhi - Nlo > 10) {
+    N = 0.5*(Nlo + Nhi);
+    if (image[N].tzero < T) {
+      Nlo = N;
+    } else {
+      Nhi = N + 1;
+    }
+  }
+  N1 = Nlo;
+
+  /* bracket last value of interest */
+  Nlo = 0; Nhi = Nimage;
+  while (Nhi - Nlo > 10) {
+    N = 0.5*(Nlo + Nhi);
+    if (image[N].tzero > T) {
+      Nhi = N;
+    } else {
+      Nlo = N - 1;
+    }
+  }
+  N2 = Nhi;
+
+  for (N = N1; N < N2; N++) {
+    if ((image[N].tzero == T) && (image[N].photcode == S)) {
+      return (N);
+    }
+  }
+  return (-1);
+}
+
+off_t match_image_subset (Image *image, off_t *subset, off_t Nsubset, unsigned int T, short int S) {
+
+  off_t N, Nlo, Nhi, N1, N2;
+
+  /* bracket first value of interest */
+  Nlo = 0; Nhi = Nsubset;
+  while (Nhi - Nlo > 10) {
+    N = 0.5*(Nlo + Nhi);
+    if (image[subset[N]].tzero < T) {
+      Nlo = N;
+    } else {
+      Nhi = N + 1;
+    }
+  }
+  N1 = Nlo;
+
+  /* bracket last value of interest */
+  Nlo = 0; Nhi = Nsubset;
+  while (Nhi - Nlo > 10) {
+    N = 0.5*(Nlo + Nhi);
+    if (image[subset[N]].tzero > T) {
+      Nhi = N;
+    } else {
+      Nlo = N - 1;
+    }
+  }
+  N2 = Nhi;
+
+  for (N = N1; N < N2; N++) {
+    if ((image[subset[N]].tzero == T) && (image[subset[N]].photcode == S)) {
+      return (subset[N]);
+    }
+  }
+  return (-1);
+}
Index: /trunk/Ohana/src/libohana/Makefile
===================================================================
--- /trunk/Ohana/src/libohana/Makefile	(revision 31634)
+++ /trunk/Ohana/src/libohana/Makefile	(revision 31635)
@@ -39,4 +39,7 @@
 $(SRC)/IOBufferOps.$(ARCH).o	 \
 $(SRC)/CommOps.$(ARCH).o	 \
+$(SRC)/isolate_elements.$(ARCH).o	 \
+$(SRC)/errors.$(ARCH).o	 \
+$(SRC)/gprint.$(ARCH).o	 \
 $(SRC)/version.$(ARCH).o
 
Index: /trunk/Ohana/src/libohana/include/ohana.h
===================================================================
--- /trunk/Ohana/src/libohana/include/ohana.h	(revision 31634)
+++ /trunk/Ohana/src/libohana/include/ohana.h	(revision 31635)
@@ -94,4 +94,6 @@
 };
 
+typedef enum {GP_LOG, GP_ERR} gpDest;
+
 /* Some notes on the Ohana BYTE_SWAP macros:
 
@@ -317,4 +319,14 @@
 off_t   Fwrite                 PROTO((void *ptr, off_t size, off_t nitems, FILE *f, char *type));
 
+char   **isolate_elements      PROTO((int argc, char **argv, int *nstack));
+
+// functions used to manage "last error message"
+int    init_error                PROTO((void));
+int    push_error                PROTO((char *line));
+int    print_error               PROTO((void));
+
+// gprint gets a stub implementation in libohana. opihi implements the real one.
+int    gprint (gpDest dest, char *format, ...);
+
 /*
 #   define F_SETFL         4   
Index: /trunk/Ohana/src/libohana/src/errors.c
===================================================================
--- /trunk/Ohana/src/libohana/src/errors.c	(revision 31635)
+++ /trunk/Ohana/src/libohana/src/errors.c	(revision 31635)
@@ -0,0 +1,22 @@
+# include "ohana.h"
+
+static char errorline[1024];
+
+int init_error () {
+
+  bzero (errorline, 1024);
+  return (TRUE);
+}
+
+int push_error (char *line) {
+
+  bzero (errorline, 1024);
+  strncpy (errorline, line, 1023);
+  return (TRUE);
+}
+
+int print_error () {
+
+  gprint (GP_ERR, "%s\n", errorline);
+  return (TRUE);
+}
Index: /trunk/Ohana/src/libohana/src/gprint.c
===================================================================
--- /trunk/Ohana/src/libohana/src/gprint.c	(revision 31635)
+++ /trunk/Ohana/src/libohana/src/gprint.c	(revision 31635)
@@ -0,0 +1,17 @@
+# include "ohana.h"
+
+// print to stdout or stderr depending on dest.
+// opihi overrides this with the real gprint
+
+int gprint (gpDest dest, char *format, ...) {
+
+  int status;
+  va_list argp;  
+
+  FILE *file = (dest == GP_LOG) ?  stdout : stderr;
+
+  va_start (argp, format);
+  status = vfprintf (file, format, argp);
+  va_end (argp);
+  return (status);
+}
Index: /trunk/Ohana/src/libohana/src/isolate_elements.c
===================================================================
--- /trunk/Ohana/src/libohana/src/isolate_elements.c	(revision 31635)
+++ /trunk/Ohana/src/libohana/src/isolate_elements.c	(revision 31635)
@@ -0,0 +1,212 @@
+// # include "opihi.h"
+//
+#include "ohana.h"
+
+/* local private functions */
+char **InsertValue (char **myOutput, int *Nout, int *Nchar, int *NCHAR, char c);
+char **EndOfString (char **myOutput, int *Nout, int *Nchar, int *NOUT, int *NCHAR);
+int IsAnOp (char *c);
+int IsTwoOp (char *c);
+
+char **isolate_elements (int Nin, char **in, int *nout) {
+  
+  /* local private static variables */
+  int NCHAR, Nchar, Nout, NOUT;
+  char **myOutput;
+
+  int i, j, minus, negate, plus, posate, OpStat, SciNotation;
+
+  NOUT = Nin;
+  Nchar = Nout = 0;
+  NCHAR = 256;
+  ALLOCATE (myOutput, char *, NOUT);
+  ALLOCATE (myOutput[Nout], char, NCHAR);
+
+  for (i = 0; i < Nin; i++) {
+    for (j = 0; j < strlen(in[i]); j++) {
+      SciNotation = FALSE;
+      /* identify 'negate' or 'minus' ops */
+      negate = minus = FALSE;
+      if (in[i][j] == '-') { 
+	minus = TRUE;  
+	/* if - is first thing on line, must be a negator */
+	if ((Nout == 0) && (Nchar == 0)) {  
+	  minus = FALSE;
+	  negate = TRUE;
+	  goto skip1;
+	}
+	/* check previous entry on line */
+	if (Nchar) {
+	  OpStat = IsAnOp (myOutput[Nout]);
+	  if (myOutput[Nout][0] == ')') OpStat = FALSE;
+	} else {
+	  OpStat = IsAnOp (myOutput[Nout-1]);
+	  if (myOutput[Nout-1][0] == ')') OpStat = FALSE;
+	}
+	/* if - follows an operator, must be negator */
+	if (OpStat) {
+	  minus = FALSE;
+	  negate = TRUE;
+	  goto skip1;
+	}
+	/* if - follows 'e' is part of 1e-5 */
+	if (j == 0) goto skip1;
+	if ((in[i][j-1] == 'e') || (in[i][j-1] == 'E')) {
+	  SciNotation = TRUE;
+	  negate = minus = FALSE;
+	}
+      }
+    skip1:
+      /* idenfity 'posate' or 'plus' ops */
+      posate = plus = FALSE;
+      if (in[i][j] == '+') { 
+	plus = TRUE;  
+	/* if + is first thing on line, must be a posator */
+	if ((Nout == 0) && (Nchar == 0)) {  
+	  plus = FALSE;
+	  posate = TRUE;
+	  goto skip2;
+	}
+	/* check previous entry on line */
+	if (Nchar) {
+	  OpStat = IsAnOp (myOutput[Nout]);
+	  if (myOutput[Nout][0] == ')') OpStat = FALSE;
+	} else {
+	  OpStat = IsAnOp (myOutput[Nout-1]);
+	  if (myOutput[Nout-1][0] == ')') OpStat = FALSE;
+	}
+	/* if + follows an operator, must be posator */
+	if (OpStat) {
+	  plus = FALSE;
+	  posate = TRUE;
+	  goto skip2;
+	}
+	/* if + follows 'e' is part of 1e+5 */
+	if (j == 0) goto skip2;
+	if ((in[i][j-1] == 'e') || (in[i][j-1] == 'E')) {
+	  SciNotation = TRUE;
+	  posate = plus = FALSE;
+	}
+      }
+    skip2:
+      /* operators */
+      if (negate || minus || posate || plus || (IsAnOp (&in[i][j]) && !SciNotation)) {
+	if (posate) continue;
+	myOutput = EndOfString (myOutput, &Nout, &Nchar, &NOUT, &NCHAR);
+	/* copy operator to myOutput[Nout] */
+	myOutput = InsertValue (myOutput, &Nout, &Nchar, &NCHAR, in[i][j]);
+	if (negate) {
+	  myOutput = InsertValue (myOutput, &Nout, &Nchar, &NCHAR, '-');
+	}
+
+	if (IsTwoOp (&in[i][j])) {
+	  myOutput = InsertValue (myOutput, &Nout, &Nchar, &NCHAR, in[i][j+1]);
+	  j++;
+	} 
+	myOutput = EndOfString (myOutput, &Nout, &Nchar, &NOUT, &NCHAR);
+	continue;
+      }
+      /* quoted string */
+      if (in[i][j] == '"') {
+	myOutput = InsertValue (myOutput, &Nout, &Nchar, &NCHAR, in[i][j]);
+	j++;
+	while ((j < strlen(in[i])) && (in[i][j] != '"')) {
+	  myOutput = InsertValue (myOutput, &Nout, &Nchar, &NCHAR, in[i][j]);
+	  j++;
+	}
+	if (in[i][j] != '"') continue;
+	/* 
+	  gprint (GP_ERR, "mismatched quotes\n");
+	  return (FALSE);
+	}
+	*/
+	myOutput = InsertValue (myOutput, &Nout, &Nchar, &NCHAR, in[i][j]);
+	myOutput = EndOfString (myOutput, &Nout, &Nchar, &NOUT, &NCHAR);
+	continue;
+      }
+      /* not an operator, not a quoted string */
+      if (!OHANA_WHITESPACE (in[i][j])) {
+	myOutput = InsertValue (myOutput, &Nout, &Nchar, &NCHAR, in[i][j]);
+      } else {
+	myOutput = EndOfString (myOutput, &Nout, &Nchar, &NOUT, &NCHAR);
+      }
+    }
+	myOutput = EndOfString (myOutput, &Nout, &Nchar, &NOUT, &NCHAR);
+  }
+
+  /* one extra entry is allocated, free here */
+  free (myOutput[Nout]);
+  *nout = Nout;
+  return (myOutput);
+
+}
+
+char **InsertValue (char **myOutput, int *Nout, int *Nchar, int *NCHAR, char c) {
+  myOutput[*Nout][*Nchar] = c;
+  (*Nchar) ++;
+  if ((*Nchar) >= (*NCHAR) - 2) {
+    (*NCHAR) += 256;
+    REALLOCATE (myOutput[*Nout], char, *NCHAR);
+  }
+  myOutput[*Nout][*Nchar] = 0;
+  return (myOutput);
+}
+
+char **EndOfString (char **myOutput, int *Nout, int *Nchar, int *NOUT, int *NCHAR) {
+  if ((*Nchar) > 0) {
+    myOutput[*Nout][*Nchar] = 0;
+    (*Nout) ++;
+    (*Nchar) = 0;
+    
+    if ((*Nout) >= (*NOUT) - 1) {
+      (*NOUT) += 10; 
+      REALLOCATE (myOutput, char *, (*NOUT)); 
+    } 
+    (*NCHAR) = 256;
+    ALLOCATE (myOutput[*Nout], char, (*NCHAR)); 
+  }
+  return (myOutput);
+}
+
+int IsAnOp (char *c) {
+
+  if (!strncmp (c, "*",  1)) return (TRUE);
+  if (!strncmp (c, "/",  1)) return (TRUE);
+  if (!strncmp (c, "+",  1)) return (TRUE);
+  if (!strncmp (c, "-",  1)) return (TRUE);
+  if (!strncmp (c, "^",  1)) return (TRUE);
+  if (!strncmp (c, "@",  1)) return (TRUE);
+  if (!strncmp (c, "(",  1)) return (TRUE);
+  if (!strncmp (c, ")",  1)) return (TRUE);
+  if (!strncmp (c, "&",  1)) return (TRUE);
+  if (!strncmp (c, "|",  1)) return (TRUE);
+  if (!strncmp (c, ">",  1)) return (TRUE);
+  if (!strncmp (c, "<",  1)) return (TRUE);
+  if (!strncmp (c, "<",  1)) return (TRUE);
+  if (!strncmp (c, "<<", 2)) return (TRUE);
+  if (!strncmp (c, ">>", 2)) return (TRUE);
+  if (!strncmp (c, "&&", 2)) return (TRUE);
+  if (!strncmp (c, "||", 2)) return (TRUE);
+  if (!strncmp (c, "==", 2)) return (TRUE);
+  if (!strncmp (c, "!=", 2)) return (TRUE);
+  if (!strncmp (c, "<=", 2)) return (TRUE);
+  if (!strncmp (c, ">=", 2)) return (TRUE);
+
+  return (FALSE);
+
+}
+
+int IsTwoOp (char *c) {
+
+  if (!strncmp (c, "<<", 2)) return (TRUE);
+  if (!strncmp (c, ">>", 2)) return (TRUE);
+  if (!strncmp (c, "&&", 2)) return (TRUE);
+  if (!strncmp (c, "||", 2)) return (TRUE);
+  if (!strncmp (c, "==", 2)) return (TRUE);
+  if (!strncmp (c, "!=", 2)) return (TRUE);
+  if (!strncmp (c, "<=", 2)) return (TRUE);
+  if (!strncmp (c, ">=", 2)) return (TRUE);
+
+  return (FALSE);
+
+}
Index: /trunk/Ohana/src/opihi/cmd.astro/Makefile
===================================================================
--- /trunk/Ohana/src/opihi/cmd.astro/Makefile	(revision 31634)
+++ /trunk/Ohana/src/opihi/cmd.astro/Makefile	(revision 31635)
@@ -25,5 +25,4 @@
 $(SRC)/cplot.$(ARCH).o		   \
 $(SRC)/csystem.$(ARCH).o	   \
-$(SRC)/coord_systems.$(ARCH).o	   \
 $(SRC)/ctimes.$(ARCH).o	   \
 $(SRC)/cval.$(ARCH).o		   \
@@ -77,5 +76,4 @@
 $(INC)/shell.h \
 $(INC)/dvomath.h \
-$(INC)/convert.h \
 $(INC)/display.h 
 
Index: unk/Ohana/src/opihi/cmd.astro/coord_systems.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.astro/coord_systems.c	(revision 31634)
+++ 	(revision )
@@ -1,173 +1,0 @@
-# include "astro.h"
-    
-CoordTransform *InitTransform (CoordTransformSystem input, CoordTransformSystem output) {
-
-  CoordTransform *transform;
-  struct timeval now;
-  struct tm *local;
-  double T;
-
-  ALLOCATE (transform, CoordTransform, 1);
-  transform->isIdentity = FALSE;
-  
-  switch (input) {
-    case COORD_CELESTIAL:
-      switch (output) {
-	case COORD_CELESTIAL:
-	  transform->phi = 0.0;
-	  transform->Xo  = 0.0;
-	  transform->xo  = 0.0;
-	  transform->isIdentity = TRUE;
-	  break;
-	case COORD_GALACTIC:
-
-	  // J2000 FK5 transformation from Liu et al 2011 (A&A 526, A16)
-	  transform->phi = -62.8717488056*RAD_DEG;
-	  transform->Xo  = 282.8594812080*RAD_DEG;
-	  transform->xo  =  32.9319185700;
-
-	  // these are derived from their eqn (10):
-	  // \alpha^p_J =  12h 51m 26.27549s
-	  // \delta^p_J = +27d 07' 41.7043"
-	  // \theta_J   = 122.93191857 deg
-	  // phi = -90 - \alpha^p_J
-	  // Xo  = +90 - \delta^p_J
-	  // xo  = \theta_J - 90
-
-	  // Liu et al also propose an alternative ICRS definition using:
-	  // \alpha^p_J =  12h 51m 26.27469s
-	  // \delta^p_J = +27d 07' 41.7087"
-	  // \theta_J   = 122.93192526 deg
-	  // these differ from the above at the several milliarcsec level
-
-
-	  // These values were used in the past, but transform to/from B1950.0
-	  // transform->phi = -62.60*RAD_DEG;
-	  // transform->Xo  = 282.25*RAD_DEG;
-	  // transform->xo  =  33.00;
-
-	  break;
-	case COORD_ECLIPTIC:
-	  gettimeofday (&now, NULL);
-	  local = localtime (&now.tv_sec);
-	  T = local[0].tm_year / 100.0;
-	  transform->phi = -1.0*RAD_DEG*(23.452294 - 0.013013*T - 0.000001639*T*T + 0.000000503*T*T*T);
-	  transform->Xo  = 0.0;
-	  transform->xo  = 0.0;
-	  break;
-	default:
-	  abort();
-      }
-      break;
-    case COORD_ECLIPTIC:
-      switch (output) {
-	case COORD_CELESTIAL:
-	  gettimeofday (&now, (struct timezone *) NULL);
-	  local = localtime (&now.tv_sec);
-	  T = local[0].tm_year / 100.0;
-	  transform->phi = RAD_DEG*(23.452294 - 0.013013*T - 0.000001639*T*T + 0.000000503*T*T*T);
-	  transform->Xo = 0.0;
-	  transform->xo = 0.0;
-	  break;
-	case COORD_GALACTIC:
-	  return NULL;
-	  break;
-	case COORD_ECLIPTIC:
-	  transform->phi = 0.0;
-	  transform->Xo  = 0.0;
-	  transform->xo  = 0.0;
-	  transform->isIdentity = TRUE;
-	  break;
-	default:
-	  abort();
-      }
-      break;
-    case COORD_GALACTIC:
-      switch (output) {
-	case COORD_CELESTIAL:
-	  // J2000 transformation from Liu et al 2011 ()
-	  transform->phi =  62.8717488056*RAD_DEG;
-	  transform->Xo  =  32.9319185700*RAD_DEG;
-	  transform->xo  = 282.8594812080;
-
-	  // These values were used in the past, but transform to/from B1950.0
-	  // transform->phi =  62.60*RAD_DEG;
-	  // transform->Xo  =  33.00*RAD_DEG;
-	  // transform->xo  = 282.25;
-	  break;
-	case COORD_GALACTIC:
-	  transform->phi = 0.0;
-	  transform->Xo  = 0.0;
-	  transform->xo  = 0.0;
-	  transform->isIdentity = TRUE;
-	  break;
-	case COORD_ECLIPTIC:
-	  return NULL;
-	default:
-	  abort();
-      }
-      break;
-    default:
-      abort();
-  }
- 
-  // pre-calculated constants:
-  transform->sin_phi_cos_Xo = sin(transform->phi)*cos(transform->Xo);
-  transform->sin_phi_sin_Xo = sin(transform->phi)*sin(transform->Xo);
-  transform->cos_phi        = cos(transform->phi);
-  
-  transform->cos_phi_cos_Xo = cos(transform->phi)*cos(transform->Xo);
-  transform->cos_phi_sin_Xo = cos(transform->phi)*sin(transform->Xo);
-  transform->sin_phi        = sin(transform->phi);
-  transform->cos_Xo 	    = cos(transform->Xo);
-  transform->sin_Xo 	    = sin(transform->Xo);
-
-  return transform;
-}
-
-// input and output coordinates are in degrees
-int ApplyTransform (double *x, double *y, double X, double Y, CoordTransform *transform) {
-
-  double sin_x, sin_y, cos_x, cos_y;
-
-
-  if (transform == NULL) return (FALSE);
-
-  if (transform->isIdentity) {
-    *x = X;
-    *y = Y;
-    return (TRUE);
-  }
-
-  X *= RAD_DEG;
-  Y *= RAD_DEG;
-
-  // recast with constants extracted:
-  sin_y = cos(Y)*sin(X)*transform->sin_phi_cos_Xo - cos(Y)*cos(X)*transform->sin_phi_sin_Xo + sin(Y)*transform->cos_phi;
-  cos_y = sqrt (1 - sin_y*sin_y);
-
-  sin_x = cos(Y)*sin(X)*transform->cos_phi_cos_Xo - cos(Y)*cos(X)*transform->cos_phi_sin_Xo - sin(Y)*transform->sin_phi;
-  cos_x = cos(Y)*cos(X)*transform->cos_Xo + cos(Y)*sin(X)*transform->sin_Xo;
-      
-  // atan2 returns -pi : +pi
-  *x = DEG_RAD * atan2 (sin_x, cos_x) + transform->xo;
-  if ((*x) <   0.0) (*x) += 360;
-  if ((*x) > 360.0) (*x) -= 360;
-
-  // should be in range -pi/2 : +pi/2
-  *y = DEG_RAD * atan2 (sin_y, cos_y);
-
-  return (TRUE);
-}
-
-// sin_y = cos(Y)*sin(X - Xo)*sin(phi) + sin(Y)*cos(phi);
-
-// sin_x = (cos(Y)*sin(X - Xo)*cos(phi) - sin(Y)*sin(phi)) /  cos_y;
-// cos_x = cos(Y)*cos(X - Xo) / cos_y;
-
-// multiplying both sides by cos_y:
-// sin_x = (cos(Y)*sin(X - Xo)*cos(phi) - sin(Y)*sin(phi));
-// cos_x = cos(Y)*cos(X - Xo);
-      
-// sin(a - b) = sin(a)*cos(b) - sin(b)*cos(a);
-// cos(a - b) = sin(a)*sin(b) + cos(a)*cos(b);
Index: /trunk/Ohana/src/opihi/cmd.basic/Makefile
===================================================================
--- /trunk/Ohana/src/opihi/cmd.basic/Makefile	(revision 31634)
+++ /trunk/Ohana/src/opihi/cmd.basic/Makefile	(revision 31635)
@@ -66,5 +66,4 @@
 $(INC)/shell.h \
 $(INC)/dvomath.h \
-$(INC)/convert.h \
 $(INC)/display.h 
 
Index: /trunk/Ohana/src/opihi/cmd.data/Makefile
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/Makefile	(revision 31634)
+++ /trunk/Ohana/src/opihi/cmd.data/Makefile	(revision 31635)
@@ -155,5 +155,4 @@
 $(INC)/shell.h \
 $(INC)/dvomath.h \
-$(INC)/convert.h \
 $(INC)/display.h 
 
Index: /trunk/Ohana/src/opihi/cmd.data/cursor.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/cursor.c	(revision 31634)
+++ /trunk/Ohana/src/opihi/cmd.data/cursor.c	(revision 31635)
@@ -20,5 +20,5 @@
     remove_argument (N, &argc, argv);
   }
-  if (!GetGraphData (NULL, &kapa, name)) return (FALSE);
+  if (!GetGraphdata (NULL, &kapa, name)) return (FALSE);
   FREE (name);
 
Index: /trunk/Ohana/src/opihi/cmd.data/ps.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/ps.c	(revision 31634)
+++ /trunk/Ohana/src/opihi/cmd.data/ps.c	(revision 31635)
@@ -56,5 +56,5 @@
 
   // get the connection to kapa, false if none available
-  if (!GetGraphData (NULL, &kapa, name)) return (FALSE);
+  if (!GetGraphdata (NULL, &kapa, name)) return (FALSE);
   FREE (name);
 
Index: unk/Ohana/src/opihi/dvo/ImageOps.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/ImageOps.c	(revision 31634)
+++ 	(revision )
@@ -1,132 +1,0 @@
-# include "dvoshell.h"
-
-void image_subset (Image *image, off_t Nimage, off_t **Subset, off_t *Nsubset,
-		   SkyRegionSelection *selection, 
-		   unsigned long int tzero, double trange, int TimeSelect) 
-{
-
-  int j, flipped, status, InPic;
-  off_t i, n, *subset;
-  int npts;
-  double r, d, X, Y, x[4], y[4], Rmin, Rmax, Rmid;
-  Graphdata graph;
-  SkyRegion patch;
-
-  Rmin = Rmax = Rmid = 0;
-
-  if (selection->useDisplay) {
-    if (!GetGraphData (&graph, NULL, NULL)) {
-      gprint (GP_ERR, "region display not available\n");
-      return;
-    }
-    Rmin = graph.coords.crval1 - 182.0;
-    Rmax = graph.coords.crval1 + 182.0;
-    Rmid = 0.5*(Rmin + Rmax);
-    BuildChipMatch (image, Nimage);
-  }
-
-  patch.Rmin = 0;
-  patch.Rmax = 0;
-  patch.Dmin = 0;
-  patch.Dmax = 0;
-  if (selection->useSkyregion) {
-    double Rs, Re, Ds, De;
-    get_skyregion (&Rs, &Re, &Ds, &De);
-    patch.Rmin = Rs;
-    patch.Rmax = Re;
-    patch.Dmin = Ds;
-    patch.Dmax = De;
-    Rmin = patch.Rmin - 182.0;
-    Rmax = patch.Rmax + 182.0;
-    Rmid = 0.5*(Rmin + Rmax);
-  }
-
-  if (trange < 0) {
-    tzero = tzero + trange;
-    trange = fabs (trange);
-  }
-
-  npts = 200;
-  ALLOCATE (subset, off_t, npts);
-  n = 0;
-  for (i = 0; i < Nimage; i++) {
-    if (TimeSelect && ((image[i].tzero < tzero) || (image[i].tzero+image[i].trate*image[i].NY > tzero + trange))) continue;
-    if (selection->useDisplay) {
-      if (!FindMosaicForImage (image, Nimage, i)) continue;
-      // first check if region center is in image
-      status = RD_to_XY (&X, &Y, Rmid, graph.coords.crval2, &image[i].coords);
-      if (status && (X >= 0) && (X < image[i].NX) && (Y >= 0) && (Y < image[i].NY)) goto in_region;
-
-      /* project this image to screen display coords */
-      x[0] = 0;           y[0] = 0;
-      x[1] = image[i].NX; y[1] = 0;
-      x[2] = image[i].NX; y[2] = image[i].NY;
-      x[3] = 0;           y[3] = image[i].NY;
-      InPic = flipped = FALSE;
-      for (j = 0; j < 4; j++) {
-	XY_to_RD (&r, &d, x[j], y[j], &image[i].coords);
-	/* use same side of 0,360 boundary for all corners */
-	if ((j == 0) && (r < Rmin)) flipped = TRUE; 
-	if ((j == 0) && (r > Rmax)) flipped = TRUE; 
-	r = ohana_normalize_angle (r);
-	while (flipped && (r < Rmid)) r+= 360.0;
-	while (flipped && (r > Rmid)) r-= 360.0;
-	status = RD_to_XY (&X, &Y, r, d, &graph.coords);
-	if (!status) continue;
-	if (X < graph.xmin) continue;
-	if (X > graph.xmax) continue;
-	if (Y < graph.ymin) continue;
-	if (Y > graph.ymax) continue;
-	goto in_region;
-	/** we miss any images which surround the region.  we are also
-	    missing the DIS images for which the corners don't touch
-	    the region, but which are needed for WRP images with
-	    corners touching the region **/
-      }
-      continue;
-    }
-    if (selection->useSkyregion) {
-      if (!FindMosaicForImage (image, Nimage, i)) continue;
-      /* project this image to screen display coords */
-      x[0] = 0;           y[0] = 0;
-      x[1] = image[i].NX; y[1] = 0;
-      x[2] = image[i].NX; y[2] = image[i].NY;
-      x[3] = 0;           y[3] = image[i].NY;
-      InPic = flipped = FALSE;
-      for (j = 0; j < 4; j++) {
-	XY_to_RD (&r, &d, x[j], y[j], &image[i].coords);
-	/* use same side of 0,360 boundary for all corners */
-	if ((j == 0) && (r < Rmin)) flipped = TRUE; 
-	if ((j == 0) && (r > Rmax)) flipped = TRUE; 
-	while (flipped && (r < Rmid)) r+= 360.0;
-	while (flipped && (r > Rmid)) r-= 360.0;
-	if (r < patch.Rmin) continue;
-	if (r > patch.Rmax) continue;
-	if (d < patch.Dmin) continue;
-	if (d > patch.Dmax) continue;
-	goto in_region;
-	/** we miss any images which surround the region.  we are also
-	    missing the DIS images for which the corners don't touch
-	    the region, but which are needed for WRP images with
-	    corners touching the region **/
-      }
-      continue;
-    }
-  in_region:
-    subset[n] = i;
-    n++;
-    if (n > npts - 1) {
-      npts += 200;
-      REALLOCATE (subset, off_t, npts);
-    }
-  }
-
-  REALLOCATE (subset, off_t, MAX (n, 1));
-  *Subset = subset;
-  *Nsubset = n;
-  return;
-}
-
-/* this routine fills the subset index with the list of selected images.
-   images may be selected on the basis of the region or on a time range 
-*/
Index: unk/Ohana/src/opihi/dvo/ImageSelection.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/ImageSelection.c	(revision 31634)
+++ 	(revision )
@@ -1,77 +1,0 @@
-# include "dvoshell.h"
-
-/* db image table */
-static Image *image = NULL;
-static off_t *subset = NULL;
-static off_t Nimage = 0;
-static off_t Nsubset = 0;
-static Coords mosaic;
-
-/* load images based on parameters and region, etc */
-int SetImageSelection (int mosaicMode, SkyRegionSelection *selection) {
-
-  int TimeSelect;
-  time_t tzero, tend;
-
-  image = NULL;
-  subset = NULL;
-  
-  TimeSelect = GetTimeSelection (&tzero, &tend);
-
-  if (mosaicMode) {
-      /* mosaic defines a frame with 0,0 at the mosaic center, and 1 arcsec / pixel */
-      mosaic.crpix1 = mosaic.crpix2 = 0.0;
-      mosaic.cdelt1 = mosaic.cdelt2 = 1.0 / 3600;
-      mosaic.pc1_1  = mosaic.pc2_2  = 1.0;
-      mosaic.pc1_2  = mosaic.pc2_1  = 0.0;
-      mosaic.Npolyterms = 0;
-      strcpy (mosaic.ctype, "RA---SIN");
-  }
-
-  if ((image = LoadImages (&Nimage)) == NULL) return (FALSE);
-  BuildChipMatch (image, Nimage);
-  image_subset (image, Nimage, &subset, &Nsubset, selection, tzero, (double) tend - tzero, TimeSelect);
-  sort_image_subset (image, subset, Nsubset);
-  return (TRUE);
-}
-
-/* free loaded images */
-void FreeImageSelection () {
-  if (image != NULL) FreeImages(image);
-  if (subset != NULL) free (subset);
-  image = NULL;
-  subset = NULL;
-  return;
-}
-
-Image *MatchImage (unsigned int time, short int source, unsigned int imageID) { 
-
-  int m = -1;
-
-  if ((imageID != 0) && (imageID < Nimage)) {
-    // imageID is in range for the array of images. If the table is still in order and
-    // no images have been deleted the index of the image we are looking for will be imageID - 1
-    // If this is the case, we have it. Otherwise we'll have to go search for it below
-    int guess = (int) imageID - 1;
-    if (image[guess].imageID == imageID) {
-        m = guess;
-    }
-  } 
-  if (m == -1) {
-    m = match_image_subset (image, subset, Nsubset, time, source);
-  }
-  if (m == -1) return (NULL);
-  if (!FindMosaicForImage (image, Nimage, m)) return (NULL);
-  return (&image[m]);
-}
-
-Coords *MatchMosaic (unsigned int time, short int source) { 
-
-  int m;
-
-  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);
-}
Index: unk/Ohana/src/opihi/dvo/LoadImages.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/LoadImages.c	(revision 31634)
+++ 	(revision )
@@ -1,97 +1,0 @@
-# include "dvoshell.h"
-
-// XXX: Maybe make this a command line option
-int dvoUseImageCache = 1;
-
-static char *lastFilename = NULL;
-static time_t lastModified = 0;
-static Image *imageCache = NULL;
-static off_t cacheNimage = 0;
-
-static time_t getLastModified(char *filename);
-
-Image *LoadImages (off_t *Nimage) {
-
-  int status;
-  char *catdir, filename[256];
-  Image *image;
-  FITS_DB db;
-  
-  /* VarConfig ("IMAGE_CATALOG", "%s", filename); */
-
-  catdir = GetCATDIR ();
-  sprintf (filename, "%s/Images.dat", catdir);
-
-  if (lastFilename) {
-    if (dvoUseImageCache && !strcmp(lastFilename, filename)) {
-      // Make sure the file hasn't changed since we loaded it
-      if (getLastModified(filename) == lastModified) {
-        *Nimage = cacheNimage;
-        return  imageCache;
-      }
-    }
-    free(lastFilename);
-    lastFilename = NULL;
-    free(imageCache);
-    imageCache = NULL;
-    cacheNimage = 0;
-    lastModified = 0;
-  }
-
-
-  gfits_db_init (&db);
-  db.lockstate = LCK_SOFT;
-  db.timeout   = 120.0;
-
-  if (!gfits_db_lock (&db, filename)) {
-    gprint (GP_ERR, "error opening image catalog %s (1)\n", filename);
-    return (NULL);
-  }
-
-  if (db.dbstate == LCK_EMPTY) {
-    gprint (GP_ERR, "note: image catalog is empty\n");
-    ALLOCATE (image, Image, 1);
-    *Nimage = 1;
-    return (image);
-  }
-
-  status = dvo_image_load (&db, TRUE, FALSE);
-  gfits_db_close (&db);
-
-  if (!status) {
-    gprint (GP_ERR, "problem loading image database table\n");
-    return (NULL);
-  }
-
-  image = gfits_table_get_Image (&db.ftable, Nimage, &db.swapped);
-  if (!image) {
-    fprintf (stderr, "ERROR: failed to read images\n");
-    return (NULL);
-  }
-  if (dvoUseImageCache && image) {
-    cacheNimage = *Nimage;
-    imageCache = image;
-    lastFilename = strdup(filename);
-    lastModified = getLastModified(filename);
-  }
-
-  return (image);
-}
-
-static time_t getLastModified(char *filename) {
-  struct stat statbuf;
-  if (!stat(filename, &statbuf)) {
-    return statbuf.st_mtime;
-  } else {
-    return 0;
-  }
-}
-
-void FreeImages(Image *images) {
-  if (!dvoUseImageCache && (images != NULL)) {
-    free(images);
-  } else {
-    // defer free until next LoadImages with a different or modified Images.dat
-  }
-}
-
Index: /trunk/Ohana/src/opihi/dvo/Makefile
===================================================================
--- /trunk/Ohana/src/opihi/dvo/Makefile	(revision 31634)
+++ /trunk/Ohana/src/opihi/dvo/Makefile	(revision 31635)
@@ -20,24 +20,10 @@
 funcs = \
 $(SRC)/init.$(ARCH).o            	\
-$(SRC)/ImageOps.$(ARCH).o		\
-$(SRC)/ImageSelection.$(ARCH).o	        \
-$(SRC)/LoadImages.$(ARCH).o		\
 $(SRC)/cmpReadFile.$(ARCH).o		\
 $(SRC)/compare.$(ARCH).o                \
-$(SRC)/match_image.$(ARCH).o		\
 $(SRC)/dvomisc.$(ARCH).o		\
 $(SRC)/region_list.$(ARCH).o		\
 $(SRC)/find_matches.$(ARCH).o		\
 $(SRC)/photometry.$(ARCH).o             \
-$(SRC)/dbBooleanCond.$(ARCH).o		\
-$(SRC)/dbCheckStack.$(ARCH).o		\
-$(SRC)/dbCmdlineFields.$(ARCH).o	\
-$(SRC)/dbExtractAverages.$(ARCH).o	\
-$(SRC)/dbExtractMeasures.$(ARCH).o	\
-$(SRC)/dbExtractImages.$(ARCH).o	\
-$(SRC)/dbFields.$(ARCH).o		\
-$(SRC)/dbRPN.$(ARCH).o			\
-$(SRC)/dbStackMath.$(ARCH).o		\
-$(SRC)/dbStackOps.$(ARCH).o		\
 $(SRC)/dvo.$(ARCH).o
 
Index: /trunk/Ohana/src/opihi/dvo/badimages.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/badimages.c	(revision 31634)
+++ /trunk/Ohana/src/opihi/dvo/badimages.c	(revision 31635)
@@ -20,5 +20,5 @@
   }
   
-  image = LoadImages (&Nimage);
+  image = LoadImagesDVO (&Nimage);
 
   Cross = FALSE;
@@ -70,5 +70,5 @@
   }
   
-  FreeImages(image);
+  FreeImagesDVO(image);
   return (TRUE);
 }
Index: unk/Ohana/src/opihi/dvo/dbBooleanCond.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/dbBooleanCond.c	(revision 31634)
+++ 	(revision )
@@ -1,85 +1,0 @@
-# include "dvoshell.h"
-
-// evaluate the expression in inStack as a boolean; necessary db field values are
-// supplied by fields, in order 0 - Nfields (validate before calling)
-// XXX fields needs to be typed (dbValue), stack math needs to deal with the type cases
-int dbBooleanCond (dbStack *inStack, int NinStack, dbValue *fields) {
-  
-  float value;
-  int i, j, N, Nstack;
-  dbStack **stack, *output;
-
-  // 'no stack' means 'no where statement'
-  if (NinStack == 0) return (TRUE);
-
-  Nstack = NinStack;
-  ALLOCATE (stack, dbStack *, NinStack);
-  for (i = 0; i < NinStack; i++) {
-    stack[i] = &inStack[i];
-  }
-
-  for (i = 0; i < Nstack; i++) {
-
-    /***** binary operators *****/
-    if ((stack[i][0].type >= DB_STACK_LOGIC) && (stack[i][0].type <= DB_STACK_POWER)) {
-
-      // pre-test that op and entries match
-      output = dbBinary (stack[i-2], stack[i-1], stack[i][0].name, fields); 
-
-      // free temporary stack items, drop external items
-      dbFreeTempEntry (stack[i-2]);
-      dbFreeTempEntry (stack[i-1]);
-
-      stack[i-2] = output;
-      for (j = i + 1; j < Nstack; j++) {
-	stack[j-2] = stack[j];
-      }
-
-      Nstack -= 2;
-      i -= 2;
-      continue;
-    }
-
-    /***** unary operators **/
-    if (stack[i][0].type == DB_STACK_UNARY) {
-
-      // pre-test that op and entries match
-      output = dbUnary (stack[i-1], stack[i][0].name, fields); 
-
-      // free temporary stack items, drop external items
-      dbFreeTempEntry (stack[i-1]);
-
-      stack[i-1] = output;
-      for (j = i + 1; j < Nstack; j++) {
-	stack[j-1] = stack[j];
-      }
-
-      Nstack -= 1;
-      i -= 1;
-      continue;
-    } 
-  }
-
-  // the result here is a single stack entry with a value:
-  if (stack[0][0].type & DB_STACK_FIELD) {
-    N = stack[0][0].field;
-    value = (stack[0][0].type & DB_STACK_INT) ? fields[N].Int : fields[N].Flt;
-  } else {
-    value = (stack[0][0].type & DB_STACK_INT) ? stack[0][0].IntValue : stack[0][0].FltValue;
-  }
-    
-  for (i = 0; i < Nstack; i++) {
-    dbFreeEntry (stack[i]);
-  }
-  free (stack);
-
-  // XXX fix this limit
-  if (fabs(value) > 1e-7) {
-    return (TRUE);
-  } else {
-    return (FALSE);
-  }
-
-  // pre-test that op and entries match
-  return (TRUE);
-}
Index: unk/Ohana/src/opihi/dvo/dbCheckStack.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/dbCheckStack.c	(revision 31634)
+++ 	(revision )
@@ -1,126 +1,0 @@
-# include "dvoshell.h"
-
-// XXX we are using a fairly bogus set of char values to distinguish a few cases:
-// 's', 'S' : value is a scalar (upper == float; lower == int)
-// 'f', 'F' : value is a field (upper == float; lower == int)
-// 't', 'T' : value is a temp scalar (upper == float; lower == int)
-// these would be better done using bit values to test for field? temp? float?
-
-int dbCheckStack (dbStack *stack, int Nstack, int table, dbField **inFields, int *inNfields) {
-
-  int i, j, status, NFIELDS, Nfields;
-  char *c1, *c2;
-  dbField *fields;
-
-  fields = *inFields;
-  Nfields = *inNfields;
-
-  NFIELDS = Nfields + 10;
-  REALLOCATE (fields, dbField, NFIELDS);
-
-  for (i = 0; i < Nstack; i++) {
-    if (stack[i].type == DB_STACK_VALUE) {
-
-      /** if this is a number, put it on the list of scalars and move on.  assume value is
-       * an int unless proven otherwise **/
-      stack[i].FltValue = strtod (stack[i].name, &c1);
-      stack[i].IntValue = strtol (stack[i].name, &c2, 0);
-      if (c2 == stack[i].name + strlen (stack[i].name)) {
-	stack[i].type  |= DB_STACK_INT;
-	continue;
-      } 
-      if (c1 == stack[i].name + strlen (stack[i].name)) {
-	// this is a float value
-	continue;
-      } 
-
-      // the value might be a special type of number: RA,DEC in sexigesimal or 
-      // time in YYYY/MM/DD, etc
-      // status = ohana_str_to_time (stack[i].name, &seconds);
-      // keep as time_t
-      // status = ohana_dms_to_ddd (&ddd, stack[i].name);
-      // keep as either hours (RA) or deg (DEC).
-
-      // strings protected by double quotes should parse to be special types of numbers
-      // (photcodes, dates, ra / dec)
-      if (stack[i].name[0] == '"') {
-	  if (stack[i].name[strlen(stack[i].name) - 1] != '"') {
-	      gprint (GP_ERR, "syntax error for field %s\n", stack[i].name);
-	      goto failure;
-	  }
-	  char *tmpstring;
-	  tmpstring = strncreate (&stack[i].name[1], strlen(stack[i].name) - 2);
-
-	  // attempt to parse the string as a special word:
-	  PhotCode *code;
-	  code = GetPhotcodebyName (tmpstring);
-	  if (code) {
-	      stack[i].IntValue = code->code;
-	      stack[i].type = DB_STACK_INT;
-	      continue;
-	  } 
-
-	  // add in tests for sexigesimal, date/time
-	  // TimeRefPM = ohana_date_to_sec ("2000/01/01");
-	  
-	  gprint (GP_ERR, "syntax error for field %s\n", stack[i].name);
-	  goto failure;
-      }
-
-      // this must be a field : is it already in the list?
-      for (j = 0; (j < Nfields) && strcasecmp (stack[i].name, fields[j].name); j++);
-      if (j < Nfields) {
-	stack[i].field = j;
-	stack[i].type |= DB_STACK_FIELD;
-	if (fields[j].type == OPIHI_INT) {
-	  stack[i].type |= DB_STACK_INT;
-	}
-	stack[i].name  = NULL;
-	stack[i].FltValue = 0.0;
-	stack[i].IntValue =   0;
-	continue;
-      }
-
-      // this must be a field : is it a valid name?
-      status = FALSE;
-      if (table == DVO_TABLE_MEASURE) {
-	status = ParseMeasureField (&fields[Nfields], stack[i].name);
-      } 
-      if (table == DVO_TABLE_AVERAGE) {
-	status = ParseAverageField (&fields[Nfields], stack[i].name);
-      } 
-      if (table == DVO_TABLE_IMAGE) {
-	status = ParseImageField (&fields[Nfields], stack[i].name);
-      } 
-      if (!status) {
-	goto failure;
-      }
-      stack[i].field = Nfields;
-      stack[i].type |= DB_STACK_FIELD;
-      if (fields[Nfields].type == OPIHI_INT) {
-	stack[i].type |= DB_STACK_INT;
-      }
-      stack[i].name  = NULL;
-      stack[i].FltValue = 0.0; // 'F'
-      stack[i].IntValue =   0; // 'f'
-
-      Nfields ++;
-      CHECK_REALLOCATE (fields, dbField, NFIELDS, Nfields, 10);
-    }
-  }
-
-  *inNfields = Nfields;
-  *inFields = fields;
-  return (TRUE);
-
-failure:
-  *inNfields = Nfields;
-  *inFields = fields;
-  return (FALSE);
-}
-
-/* check stack identifies the data elements as plain scalars or table fields
-   operators have already been identified.  
-   check stack returns the total stack dimensionality (0,1,2)
-   on error, check stack returns FALSE
-*/
Index: unk/Ohana/src/opihi/dvo/dbCmdlineFields.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/dbCmdlineFields.c	(revision 31634)
+++ 	(revision )
@@ -1,215 +1,0 @@
-# include "dvoshell.h"
-
-// check for 'where' or 'matched to'; return first field after the word, and the value
-int dbCmdlineConditions (int argc, char **argv, int first, int *nextField) {
-
-  int isWhere, isMatch;
-
-  *nextField = argc;
-
-  // require 'where' or 'matched to' before boolean math
-  if (first == argc) return DVO_DB_CMDLINE_IS_END;
-
-  isWhere = !strcasecmp(argv[first], "where");
-  isMatch = !strcasecmp(argv[first], "match");
-    
-  if (!isMatch && !isWhere) {
-    gprint (GP_ERR, "WHERE or MATCH TO\n");
-    return DVO_DB_CMDLINE_ERROR;
-  }
-  if (isMatch && ((first + 1 >= argc - 1) || strcasecmp(argv[first+1], "to"))) {
-    gprint (GP_ERR, "missing boolean expression\n");
-    return DVO_DB_CMDLINE_ERROR;
-  }
-  if (isWhere && (first >= argc - 1)) {
-    gprint (GP_ERR, "missing boolean expression\n");
-    return DVO_DB_CMDLINE_ERROR;
-  }
-
-  if (isWhere) {
-    *nextField = first + 1;
-    return DVO_DB_CMDLINE_IS_WHERE;
-  }
-
-  if (isMatch) {
-    *nextField = first + 2;
-    return DVO_DB_CMDLINE_IS_MATCH;
-  }
-
-  gprint (GP_ERR, "programming error?\n");
-  return DVO_DB_CMDLINE_ERROR;
-}
-
-// identify the fields to be extracted (check syntax)
-// the 'last' pointer ends on the first word after the fields (where, match or EOL) 
-dbField *dbCmdlineFields (int argc, char **argv, int table, int *last, int *nfields) {
-
-  int i, status, Nfields, NFIELDS;
-  char *p, *q, *field;
-  dbField *fields;
-
-  *nfields = 0;
-  Nfields = 0;
-  NFIELDS = 10;
-  ALLOCATE (fields, dbField, NFIELDS);
-  dbInitField (&fields[0]);
-
-  status = FALSE;
-
-  // examine each argv[i] entry until we reach a 'where', a 'matched', or the end of the line
-  for (i = 1; (i < argc) && strcasecmp (argv[i], "where") && strcasecmp (argv[i], "match"); i++) {
-    // split the word by ","
-    p = argv[i];
-    while (*p) {
-      q = strchr (p, ',');
-      if (q == NULL) {
-	field = strcreate (p);
-	p = p + strlen(p);
-      } else {
-	field = strncreate (p, q-p);
-	p = q + 1;
-      }
-      // identify field for word
-      // need to know which type of fields to look for...
-      // xxx extend this more generally later
-      if (table == DVO_TABLE_MEASURE) {
-	status = ParseMeasureField (&fields[Nfields], field);
-      } 
-      if (table == DVO_TABLE_AVERAGE) {
-	status = ParseAverageField (&fields[Nfields], field);
-      } 
-      if (table == DVO_TABLE_IMAGE) {
-	status = ParseImageField (&fields[Nfields], field);
-      } 
-      if (!status) {
-	free (field);
-	dbFreeFields (fields, Nfields);
-	return (NULL);
-      }
-      free (field);
-
-      Nfields ++;
-      CHECK_REALLOCATE (fields, dbField, NFIELDS, Nfields, 10);
-      dbInitField (&fields[Nfields]);
-    }
-  }
-
-  *last = i;
-  *nfields = Nfields;
-
-  return (fields);
-}
-
-char *strfloat (float value) {
-
-  int Nbyte;
-  char *output;
-  char tmp;
-
-  Nbyte = snprintf (&tmp, 0, "%f", value);
-  ALLOCATE (output, char, Nbyte + 1);
-  snprintf (output, Nbyte + 1, "%f", value);
-  return output;
-}
-
-// identify the fields to be extracted (test for where, check syntax)
-int dbAstroRegionLimits (dbStack **stack, int *nstack, SkyRegionSelection *selection, int table) {
-  
-  int N;
-  double Rmin, Rmax, Dmin, Dmax;
-  char *Rname, *Dname;
-
-  if (!selection->useDisplay && !selection->useSkyregion) return (TRUE);
-
-  // get the ra,dec limits...
-  if (selection->useDisplay) {
-    return (TRUE);
-    // XXX fix this: be more careful with the projection & limits
-
-    Graphdata graphsky;
-    if (!GetGraphData (&graphsky, NULL, NULL)) {
-      gprint (GP_ERR, "region display not available\n");
-      return (FALSE);
-    }
-    
-    // XXX the ra and dec range depend on the projection. 
-    // XXX this is wrong...
-    int status;
-    status = XY_to_RD (&Rmin, &Dmin, graphsky.xmin, graphsky.ymin, &graphsky.coords);
-    status = XY_to_RD (&Rmax, &Dmax, graphsky.xmax, graphsky.ymax, &graphsky.coords);
-  }
-
-  if (selection->useSkyregion) {
-    get_skyregion (&Rmin, &Rmax, &Dmin, &Dmax);
-  }    
-
-  N = *nstack;
-  REALLOCATE (*stack, dbStack, N + 20);
-
-  Rname = Dname = NULL;
-  if (table == DVO_TABLE_MEASURE) {
-    Rname = strcreate ("RA:AVE");
-    Dname = strcreate ("DEC:AVE");
-  }
-  if (table == DVO_TABLE_AVERAGE) {
-    Rname = strcreate ("RA");
-    Dname = strcreate ("DEC");
-  }
-  if (table == DVO_TABLE_IMAGE) {
-    Rname = strcreate ("RA");
-    Dname = strcreate ("DEC");
-  } 
-  if (Rname == NULL) return (FALSE);
-
-  // add: ((ra > rmin) && (ra < rmax) && (dec > dmin) && (dec < dmax))
-  // prepend with && if *nstack > 0
-
-  stack[0][N +  0].name = strcreate (Rname);
-  stack[0][N +  0].type = DB_STACK_VALUE;
-  stack[0][N +  1].name = strfloat (Rmin);
-  stack[0][N +  1].type = DB_STACK_VALUE;
-  stack[0][N +  2].name = strcreate (">");
-  stack[0][N +  2].type = DB_STACK_COMPARE;
-
-  stack[0][N +  3].name = strcreate (Rname);
-  stack[0][N +  3].type = DB_STACK_VALUE;
-  stack[0][N +  4].name = strfloat (Rmax);
-  stack[0][N +  4].type = DB_STACK_VALUE;
-  stack[0][N +  5].name = strcreate ("<");
-  stack[0][N +  5].type = DB_STACK_COMPARE;
-  stack[0][N +  6].name = strcreate ("A");
-  stack[0][N +  6].type = DB_STACK_LOGIC;
-
-  stack[0][N +  7].name = strcreate (Dname);
-  stack[0][N +  7].type = DB_STACK_VALUE;
-  stack[0][N +  8].name = strfloat (Dmin);
-  stack[0][N +  8].type = DB_STACK_VALUE;
-  stack[0][N +  9].name = strcreate (">");
-  stack[0][N +  9].type = DB_STACK_COMPARE;
-  stack[0][N + 10].name = strcreate ("A");
-  stack[0][N + 10].type = DB_STACK_LOGIC;
-
-  stack[0][N + 11].name = strcreate (Dname);
-  stack[0][N + 11].type = DB_STACK_VALUE;
-  stack[0][N + 12].name = strfloat (Dmax);
-  stack[0][N + 12].type = DB_STACK_VALUE;
-  stack[0][N + 13].name = strcreate ("<");
-  stack[0][N + 13].type = DB_STACK_COMPARE;
-  stack[0][N + 14].name = strcreate ("A");
-  stack[0][N + 14].type = DB_STACK_LOGIC;
-
-  if (N == 0) {
-    N += 15;
-  } else {
-    stack[0][N + 15].name = strcreate ("A");
-    stack[0][N + 15].type = DB_STACK_LOGIC;
-    N += 16;
-  }    
-
-  free (Rname);
-  free (Dname);
-
-  *nstack = N;
-  return (TRUE);
-}
-
Index: unk/Ohana/src/opihi/dvo/dbExtractAverages.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/dbExtractAverages.c	(revision 31634)
+++ 	(revision )
@@ -1,240 +1,0 @@
-# include "dvoshell.h"
-
-/* time concepts */
-static time_t TimeReference;
-static int TimeFormat;
-
-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 dbExtractAveragesInitTransform (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 dbExtractAveragesInit () {
-  GetTimeFormat (&TimeReference, &TimeFormat);
-  haveGalactic = FALSE;
-  haveEcliptic = FALSE;
-  return (TRUE);
-}
-
-/* return average.field based on the selection */
-dbValue dbExtractAverages (Average *average, SecFilt *secfilt, Measure *measure, dbField *field) {
-
-  off_t i;
-  int Nsec;
-  dbValue value;
-
-  value.Flt = NAN;
-  value.Int =   0;
-
-  /* assign vector values */
-  switch (field->ID) {
-    case AVE_RA:
-      value.Flt = average[0].R;
-      break;
-    case AVE_DEC:
-      value.Flt = average[0].D;
-      break;
-    case AVE_GLON:
-      if (!haveGalactic) {
-	ApplyTransform (&GLON, &GLAT, average[0].R, average[0].D, celestial_to_galactic);
-	haveGalactic = TRUE;
-      }
-      value.Flt = GLON;
-      break;
-    case AVE_GLAT:
-      if (!haveGalactic) {
-	ApplyTransform (&GLON, &GLAT, average[0].R, average[0].D, celestial_to_galactic);
-	haveGalactic = TRUE;
-      }
-      value.Flt = GLAT;
-      break;
-    case AVE_ELON:
-      if (!haveEcliptic) {
-	ApplyTransform (&ELON, &ELAT, average[0].R, average[0].D, celestial_to_ecliptic);
-	haveEcliptic = TRUE;
-      }
-      value.Flt = ELON;
-      break;
-    case AVE_ELAT:
-      if (!haveEcliptic) {
-	ApplyTransform (&ELON, &ELAT, average[0].R, average[0].D, celestial_to_ecliptic);
-	haveEcliptic = TRUE;
-      }
-      value.Flt = ELAT;
-      break;
-    case AVE_RA_ERR:
-      value.Flt = average[0].dR;
-      break;
-    case AVE_DEC_ERR:
-      value.Flt = average[0].dD;
-      break;
-
-    case AVE_U_RA:
-      value.Flt = average[0].uR;
-      break;
-    case AVE_U_DEC:
-      value.Flt = average[0].uD;
-      break;
-    case AVE_U_RA_ERR:
-      value.Flt = average[0].duR;
-      break;
-    case AVE_U_DEC_ERR:
-      value.Flt = average[0].duD;
-      break;
-
-    case AVE_PAR:
-      value.Flt = average[0].P;
-      break;
-    case AVE_PAR_ERR:
-      value.Flt = average[0].dP;
-      break;
-
-    case AVE_NMEAS:
-      value.Int = average[0].Nmeasure;
-      break;
-    case AVE_NMISS:
-      value.Int = average[0].Nmissing;
-      break;
-    case AVE_NPOS:
-      value.Int = average[0].Npos;
-      break;
-
-    case AVE_CHISQ_POS:
-      value.Flt = average[0].ChiSqAve;
-      break;
-    case AVE_CHISQ_PM:
-      value.Flt = average[0].ChiSqPM;
-      break;
-    case AVE_CHISQ_PAR:
-      value.Flt = average[0].ChiSqPar;
-      break;
-
-    case AVE_TMEAN:
-      value.Flt = TimeValue (average[0].Tmean, TimeReference, TimeFormat);
-      break;
-    case AVE_TRANGE:
-      value.Flt = TimeValue (average[0].Trange, 0, TimeFormat);
-      break;
-
-    case AVE_Xp:
-      value.Flt = 0.01*average[0].Xp;
-      break;
-
-    case AVE_OBJ_FLAGS:
-      value.Int = average[0].flags;
-      break;
-    case AVE_OBJID:
-      value.Int = average[0].objID;
-      break;
-    case AVE_CATID:
-      value.Int = average[0].catID;
-      break;
-    case AVE_EXTID_HI:
-      value.Int = (0x00000000FFFFFFFF & (average[0].extID >> 32));
-      break;
-    case AVE_EXTID_LO:
-      value.Int = (0x00000000FFFFFFFF & average[0].extID);
-      break;
-
-    case AVE_MAG:
-      switch (field->magMode) {
-	case MAG_AVE:
-	  value.Flt = PhotAve  (field->photcode, average, secfilt);
-	  break;
-	case MAG_REF:
-	  value.Flt = 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.Flt = NAN;
-	  for (i = 0; i < average[0].Nmeasure; i++) {
-	    if (field->photcode->code != measure[i].photcode) continue;
-	    value.Flt = measure[i].M;
-	    break;
-	  }
-	  break;
-	case MAG_CHISQ:
-	  value.Flt = PhotXm (field->photcode, average, secfilt);
-	  break;
-	case MAG_ERR:
-	  if ((field->photcode->type == PHOT_REF) || (field->photcode->type == PHOT_DEP)) {
-	    for (i = 0; i < average[0].Nmeasure; i++) {
-	      if (field->photcode->code != measure[i].photcode) continue;
-	      value.Flt = measure[i].dM;
-	      break;
-	    }
-	  } else {
-	    value.Flt = PhotdM (field->photcode, average, secfilt);
-	  }
-	  break;
-	case MAG_PHOT_FLAGS:
-	  if ((field->photcode->type == PHOT_REF) || (field->photcode->type == PHOT_DEP)) {
-	    for (i = 0; i < average[0].Nmeasure; i++) {
-	      if (field->photcode->code != measure[i].photcode) continue;
-	      value.Int = measure[i].photFlags;
-	      break;
-	    }
-	  } else {
-	    value.Int = 0;
-	  }
-	  break;
-	case MAG_NCODE:
-	  // XXX push these into dvo_photcode_ops APIs
-	  // XXX do I need to allow for conversion to equiv?
-	  Nsec = GetPhotcodeNsec (field->photcode->code);
-	  if (Nsec == -1) break;
-	  value.Int = secfilt[Nsec].Ncode;
-	  break;
-	case MAG_NPHOT:
-	  Nsec = GetPhotcodeNsec (field->photcode->code);
-	  if (Nsec == -1) break;
-	  value.Int = secfilt[Nsec].Nused;
-	  break;
-
-      }
-      break;
-    case AVE_dMAG:
-      value.Flt = PhotdM (field->photcode, average, secfilt);
-      break;
-    case AVE_Xm:
-      value.Flt = PhotXm (field->photcode, average, secfilt);
-      break;
-    case AVE_TYPE:
-      break;
-    case AVE_TYPEFRAC:
-      break;
-  }
-  return (value);
-}  
-
Index: unk/Ohana/src/opihi/dvo/dbExtractImages.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/dbExtractImages.c	(revision 31634)
+++ 	(revision )
@@ -1,345 +1,0 @@
-# include "dvoshell.h"
-
-/* time concepts */
-static time_t TimeReference;
-static int TimeFormat;
-
-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;
-
-static int haveCelestial = FALSE;
-static double RAo = 0.0;
-static double DECo = 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 () {
-  GetTimeFormat (&TimeReference, &TimeFormat);
-  return (TRUE);
-}
-
-int dbExtractImagesReset () {
-  haveGalactic  = FALSE;
-  haveEcliptic  = FALSE;
-  haveCelestial = FALSE;
-  return (TRUE);
-}
-
-/* return image.field based on the selection */
-dbValue dbExtractImages (Image *image, off_t Nimage, off_t N, dbField *field) {
-
-  double x, y;
-  time_t t;
-  dbValue value;
-  off_t Nmosaic;
-
-  value.Flt = NAN;
-  value.Int =   0;
-
-  /* assign vector values */
-  switch (field->ID) {
-    case IMAGE_RA:
-      if (!haveCelestial) {
-	if (!FindMosaicForImage (image, Nimage, N)) return value;
-	x = 0.5*image[N].NX;
-	y = 0.5*image[N].NY;
-	XY_to_RD (&RAo, &DECo, x, y, &image[N].coords);
-	haveCelestial = TRUE;
-      }
-      value.Flt = RAo;
-      break;
-    case IMAGE_DEC:
-      if (!haveCelestial) {
-	if (!FindMosaicForImage (image, Nimage, N)) return value;
-	x = 0.5*image[N].NX;
-	y = 0.5*image[N].NY;
-	XY_to_RD (&RAo, &DECo, x, y, &image[N].coords);
-	haveCelestial = TRUE;
-      }
-      value.Flt = DECo;
-      break;
-    case IMAGE_GLON:
-      if (!haveGalactic) {
-	if (!haveCelestial) {
-	  if (!FindMosaicForImage (image, Nimage, N)) return value;
-	  x = 0.5*image[N].NX;
-	  y = 0.5*image[N].NY;
-	  XY_to_RD (&RAo, &DECo, x, y, &image[N].coords);
-	  haveCelestial = TRUE;
-	}
-	ApplyTransform (&GLON, &GLAT, RAo, DECo, celestial_to_galactic);
-	haveGalactic = TRUE;
-      }
-      value.Flt = GLON;
-      break;
-    case IMAGE_GLAT:
-      if (!haveGalactic) {
-	if (!haveCelestial) {
-	  if (!FindMosaicForImage (image, Nimage, N)) return value;
-	  x = 0.5*image[N].NX;
-	  y = 0.5*image[N].NY;
-	  XY_to_RD (&RAo, &DECo, x, y, &image[N].coords);
-	  haveCelestial = TRUE;
-	}
-	ApplyTransform (&GLON, &GLAT, RAo, DECo, celestial_to_galactic);
-	haveGalactic = TRUE;
-      }
-      value.Flt = GLAT;
-      break;
-    case IMAGE_ELON:
-      if (!haveEcliptic) {
-	if (!haveCelestial) {
-	  if (!FindMosaicForImage (image, Nimage, N)) return value;
-	  x = 0.5*image[N].NX;
-	  y = 0.5*image[N].NY;
-	  XY_to_RD (&RAo, &DECo, x, y, &image[N].coords);
-	  haveCelestial = TRUE;
-	}
-	ApplyTransform (&ELON, &ELAT, RAo, DECo, celestial_to_ecliptic);
-	haveEcliptic = TRUE;
-      }
-      value.Flt = ELON;
-      break;
-    case IMAGE_ELAT:
-      if (!haveEcliptic) {
-	if (!haveCelestial) {
-	  if (!FindMosaicForImage (image, Nimage, N)) return value;
-	  x = 0.5*image[N].NX;
-	  y = 0.5*image[N].NY;
-	  XY_to_RD (&RAo, &DECo, x, y, &image[N].coords);
-	  haveCelestial = TRUE;
-	}
-	ApplyTransform (&ELON, &ELAT, RAo, DECo, celestial_to_ecliptic);
-	haveEcliptic = TRUE;
-      }
-      value.Flt = ELAT;
-      break;
-
-    case IMAGE_THETA: {
-      double theta1, theta2, s1, s2;
-      s1 = SIGN(image[N].coords.pc1_1);
-      s2 = SIGN(image[N].coords.pc2_2);
-      theta1 = DEG_RAD*atan2 (+s1*image[N].coords.pc1_2, s1*image[N].coords.pc1_1);
-      theta2 = DEG_RAD*atan2 (-s2*image[N].coords.pc2_1, s2*image[N].coords.pc2_2);
-      value.Flt = 0.5*(theta1+theta2);
-      break; }
-    case IMAGE_SKEW: {
-      double theta1, theta2, s1, s2;
-      s1 = SIGN(image[N].coords.pc1_1);
-      s2 = SIGN(image[N].coords.pc2_2);
-      theta1 = DEG_RAD*atan2 (+s1*image[N].coords.pc1_2, s1*image[N].coords.pc1_1);
-      theta2 = DEG_RAD*atan2 (-s2*image[N].coords.pc2_1, s2*image[N].coords.pc2_2);
-      value.Flt = (theta1-theta2);
-      break; }
-    case IMAGE_SCALE: {
-      double scale1, scale2;
-      scale1 = fabs(image[N].coords.cdelt1);
-      scale2 = fabs(image[N].coords.cdelt2);
-      value.Flt = 0.5*(scale1+scale2);
-      break; }
-    case IMAGE_DSCALE: {
-      double scale1, scale2;
-      scale1 = fabs(image[N].coords.cdelt1);
-      scale2 = fabs(image[N].coords.cdelt2);
-      value.Flt = (scale1-scale2);
-      break; }
-
-    case IMAGE_TIME:
-      t = image[N].tzero + 0.5*image[N].NY * image[N].trate / 10000;
-      value.Flt = TimeValue (t, TimeReference, TimeFormat);
-      break;
-    case IMAGE_NSTAR:
-      value.Int = image[N].nstar;
-      break;
-    case IMAGE_AIRMASS:
-      value.Flt = image[N].secz;
-      break;
-    case IMAGE_NX_PIX:
-      value.Int = image[N].NX;
-      break;
-    case IMAGE_NY_PIX:
-      value.Int = image[N].NY;
-      break;
-    case IMAGE_APRESID:
-      value.Flt = image[N].apmifit;
-      break;
-    case IMAGE_DAPRESID:
-      value.Flt = image[N].dapmifit;
-      break;
-
-    case IMAGE_MCAL:
-      value.Flt = image[N].Mcal;
-      break;
-    case IMAGE_dMCAL:
-      value.Flt = image[N].dMcal;
-      break;
-    case IMAGE_XM:
-      value.Flt = pow(10.0, 0.01*image[N].Xm);
-      break;
-    case IMAGE_PHOTCODE:
-      value.Int = image[N].photcode;
-      break;
-    case IMAGE_EXPTIME:
-      value.Flt = image[N].exptime;
-      break;
-    case IMAGE_SIDTIME:
-      value.Flt = image[N].sidtime;
-      break;
-
-    case IMAGE_LATITUDE:
-      value.Flt = image[N].latitude;
-      break;
-
-    case IMAGE_DET_LIMIT:
-      value.Flt = image[N].detection_limit * 0.1;
-      break;
-    case IMAGE_SAT_LIMIT:
-      value.Flt = image[N].saturation_limit * 0.1;
-      break;
-    case IMAGE_CERROR:
-      value.Flt = image[N].cerror / 50.0;
-      break;
-
-    case IMAGE_FWHM:
-      value.Flt = (image[N].fwhm_x + image[N].fwhm_y) / 50.0;
-      break;
-    case IMAGE_FWHM_MAJ:
-      value.Flt = image[N].fwhm_x / 25.0;
-      break;
-    case IMAGE_FWHM_MIN:
-      value.Flt = image[N].fwhm_y / 25.0;
-      break;
-
-    case IMAGE_FWHM_MEDIAN:
-      if (!(Nmosaic = FindMosaicForImage (image, Nimage, N))) return value;
-      Nmosaic --; // XXX kind of a hack: FindMosaicForImage returns 0 or the mosaic seq number + 1
-      value.Flt = (image[Nmosaic].fwhm_x + image[Nmosaic].fwhm_y) / 50.0;
-      break;
-    case IMAGE_FWHM_MAJ_MEDIAN:
-      if (!(Nmosaic = FindMosaicForImage (image, Nimage, N))) return value;
-      Nmosaic --; // XXX kind of a hack: FindMosaicForImage returns 0 or the mosaic seq number + 1
-      value.Flt = image[Nmosaic].fwhm_x / 25.0;
-      break;
-    case IMAGE_FWHM_MIN_MEDIAN:
-      if (!(Nmosaic = FindMosaicForImage (image, Nimage, N))) return value;
-      Nmosaic --; // XXX kind of a hack: FindMosaicForImage returns 0 or the mosaic seq number + 1
-      value.Flt = image[Nmosaic].fwhm_y / 25.0;
-      break;
-
-    case IMAGE_TRATE:
-      value.Flt = image[N].trate / 10000.0;
-      break;
-
-    case IMAGE_NCAL:
-      value.Int = image[N].nFitPhotom;
-      break;
-    case IMAGE_SKY:
-      value.Flt = NAN;
-      break;
-    case IMAGE_FLAGS:
-      value.Int = image[N].flags;
-      break;
-    case IMAGE_CCDNUM:
-      value.Int = image[N].ccdnum;
-      break;
-
-    case IMAGE_IMAGE_ID:
-      value.Int = image[N].imageID;
-      break;
-    case IMAGE_EXTERN_ID:
-      value.Int = image[N].externID;
-      break;
-    case IMAGE_SOURCE_ID:
-      value.Int = image[N].sourceID;
-      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[N].NX;
-      break;
-    case IMAGE_Y_UL_CHIP:
-    case IMAGE_Y_UR_CHIP:
-      value.Flt = image[N].NX;
-      break;
-
-    case IMAGE_X_LL_FP:
-    case IMAGE_Y_LL_FP:
-      XY_to_LM (&x, &y, 0.0, 0.0, &image[N].coords);
-      value.Flt = (field->ID == IMAGE_X_LL_FP) ? x : y;
-      break;
-    case IMAGE_X_LR_FP:
-    case IMAGE_Y_LR_FP:
-      XY_to_LM (&x, &y, image[N].NX, 0.0, &image[N].coords);
-      value.Flt = (field->ID == IMAGE_X_LR_FP) ? x : y;
-      break;
-    case IMAGE_X_UL_FP:
-    case IMAGE_Y_UL_FP:
-      XY_to_LM (&x, &y, 0.0, image[N].NY, &image[N].coords);
-      value.Flt = (field->ID == IMAGE_X_UL_FP) ? x : y;
-      break;
-    case IMAGE_X_UR_FP:
-    case IMAGE_Y_UR_FP:
-      XY_to_LM (&x, &y, image[N].NX, image[N].NY, &image[N].coords);
-      value.Flt = (field->ID == IMAGE_X_UR_FP) ? x : y;
-      break;
-
-    case IMAGE_X_ERR_SYS:
-      value.Flt = image[N].dXpixSys;
-      break;
-    case IMAGE_Y_ERR_SYS:
-      value.Flt = image[N].dXpixSys;
-      break;
-    case IMAGE_MAG_ERR_SYS:
-      value.Flt = image[N].dMagSys;
-      break;
-
-    case IMAGE_NFIT_PHOTOM:
-      value.Int = image[N].nFitPhotom;
-      break;
-    case IMAGE_NFIT_ASTROM:
-      value.Int = image[N].nFitAstrom;
-      break;
-    case IMAGE_NLINK_PHOTOM:
-      value.Int = image[N].nLinkPhotom;
-      break;
-    case IMAGE_NLINK_ASTROM:
-      value.Int = image[N].nLinkAstrom;
-      break;
-  }
-  return (value);
-}  
-
Index: unk/Ohana/src/opihi/dvo/dbExtractMeasures.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/dbExtractMeasures.c	(revision 31634)
+++ 	(revision )
@@ -1,465 +1,0 @@
-# include "dvoshell.h"
-
-// to add a new field to the extractions:
-// 1) add the selection for the field below
-// 2) add the field to the ParseMeasureField in dbFields.c
-// 3) add the field to the measure enum list in dvoshell.h
-
-/* time concepts */
-static time_t TimeReference;
-static int TimeFormat;
-
-static CoordTransform *celestial_to_galactic = NULL;
-static CoordTransform *celestial_to_ecliptic = NULL;
-
-static int haveGalacticAve = FALSE;
-static double GLON_AVE = 0.0;
-static double GLAT_AVE = 0.0;
-
-static int haveEclipticAve = FALSE;
-static double ELON_AVE = 0.0;
-static double ELAT_AVE = 0.0;
-
-static int haveGalacticMeas = FALSE;
-static double GLON_MEAS = 0.0;
-static double GLAT_MEAS = 0.0;
-
-static int haveEclipticMeas = FALSE;
-static double ELON_MEAS = 0.0;
-static double ELAT_MEAS = 0.0;
-
-int dbExtractMeasuresInit () {
-  GetTimeFormat (&TimeReference, &TimeFormat);
-  return (TRUE);
-}
-
-// define a locally-static transform
-int dbExtractMeasuresInitTransform (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 dbExtractMeasuresInitAve () {
-  haveGalacticAve = FALSE;
-  haveEclipticAve = FALSE;
-  return (TRUE);
-}
-
-int dbExtractMeasuresInitMeas () {
-  haveGalacticMeas = FALSE;
-  haveEclipticMeas = FALSE;
-  return (TRUE);
-}
-
-/* return measure.field based on the selection */
-dbValue dbExtractMeasures (Average *average, SecFilt *secfilt, Measure *measure, dbField *field) {
-
-  int Nsec;
-  dbValue value;
-  double ra, dec, x, y, dT;
-
-  Coords *mosaic;
-  PhotCode *equiv;
-
-  value.Flt = NAN;
-  value.Int =   0;
-
-  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;
-      if ((field->photcode->type == PHOT_REF) && (measure[0].photcode == field->photcode->code)) goto valid_photcode;
-      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;
-      break;
-
-  valid_photcode:
-      switch (field->magMode) {
-	case MAG_INST:
-	  value.Flt = PhotInst (measure);  
-	  break;
-	case MAG_CAT:
-	  value.Flt = PhotCat  (measure); 
-	  break;
-	case MAG_SYS:
-	  value.Flt = PhotSys  (measure, average, secfilt); 
-	  break;
-	case MAG_REL:
-	  value.Flt = PhotRel  (measure, average, secfilt); 
-	  break;
-	case MAG_CAL:
-	  value.Flt = PhotCal  (measure, average, secfilt, measure, equiv); 
-	  break;
-	case MAG_AVE:
-	  value.Flt = PhotAve  (equiv, average, secfilt); 
-	  break;
-	case MAG_REF:
-	  value.Flt = PhotRef  (equiv, average, secfilt, measure); 
-	  break;
-	case MAG_APER:
-	  value.Flt = PhotAper  (measure); 
-	  break;
-	case MAG_ERR:
-	  value.Flt = measure[0].dM;
-	  break;
-	case MAG_AVE_ERR:
-	  value.Flt = PhotdM  (equiv, average, secfilt); 
-	  break;
-	case MAG_PHOT_FLAGS:
-	  if ((field->photcode->type == PHOT_REF) || (field->photcode->type == PHOT_DEP)) {
-	    value.Int = measure[0].photFlags;
-	  } else {
-	    value.Int = 0;
-	  }
-	  break;
-	case MAG_CHISQ:
-	  value.Flt = PhotXm  (equiv, average, secfilt); 
-	  break;
-	case MAG_NCODE:
-	  if (equiv == NULL) {
-	    value.Int = 0;
-	    break;
-	  }
-	  Nsec = GetPhotcodeNsec (equiv->code);
-	  if (Nsec == -1) break;
-	  value.Int = secfilt[Nsec].Ncode;
-	  break;
-	case MAG_NPHOT:
-	  if (equiv == NULL) {
-	    value.Int = 0;
-	    break;
-	  }
-	  Nsec = GetPhotcodeNsec (equiv->code);
-	  if (Nsec == -1) break;
-	  value.Int = secfilt[Nsec].Nused;
-	  break;
-      }
-      break;
-    case MEAS_RA: /* OK */
-      value.Flt = average[0].R - measure[0].dR / 3600.0;
-      break;
-    case MEAS_DEC: /* OK */
-      value.Flt = average[0].D - measure[0].dD / 3600.0;
-      break;
-    case MEAS_RA_AVE: /* OK */
-      value.Flt = average[0].R;
-      break;
-    case MEAS_DEC_AVE: /* OK */
-      value.Flt = average[0].D;
-      break;
-
-    case MEAS_GLON:
-      if (!haveGalacticMeas) {
-	ApplyTransform (&GLON_MEAS, &GLAT_MEAS, average[0].R - measure[0].dR / 3600.0, average[0].D - measure[0].dD / 3600.0, celestial_to_galactic);
-	haveGalacticMeas = TRUE;
-      }
-      value.Flt = GLON_MEAS;
-      break;
-    case MEAS_GLAT:
-      if (!haveGalacticMeas) {
-	ApplyTransform (&GLON_MEAS, &GLAT_MEAS, average[0].R - measure[0].dR / 3600.0, average[0].D - measure[0].dD / 3600.0, celestial_to_galactic);
-	haveGalacticMeas = TRUE;
-      }
-      value.Flt = GLAT_MEAS;
-      break;
-    case MEAS_ELON:
-      if (!haveEclipticMeas) {
-	ApplyTransform (&ELON_MEAS, &ELAT_MEAS, average[0].R - measure[0].dR / 3600.0, average[0].D - measure[0].dD / 3600.0, celestial_to_ecliptic);
-	haveEclipticMeas = TRUE;
-      }
-      value.Flt = ELON_MEAS;
-      break;
-    case MEAS_ELAT:
-      if (!haveEclipticMeas) {
-	ApplyTransform (&ELON_MEAS, &ELAT_MEAS, average[0].R - measure[0].dR / 3600.0, average[0].D - measure[0].dD / 3600.0, celestial_to_ecliptic);
-	haveEclipticMeas = TRUE;
-      }
-      value.Flt = ELAT_MEAS;
-      break;
-
-    case MEAS_GLON_AVE:
-      if (!haveGalacticAve) {
-	ApplyTransform (&GLON_AVE, &GLAT_AVE, average[0].R, average[0].D, celestial_to_galactic);
-	haveGalacticAve = TRUE;
-      }
-      value.Flt = GLON_AVE;
-      break;
-    case MEAS_GLAT_AVE:
-      if (!haveGalacticAve) {
-	ApplyTransform (&GLON_AVE, &GLAT_AVE, average[0].R, average[0].D, celestial_to_galactic);
-	haveGalacticAve = TRUE;
-      }
-      value.Flt = GLAT_AVE;
-      break;
-    case MEAS_ELON_AVE:
-      if (!haveEclipticAve) {
-	ApplyTransform (&ELON_AVE, &ELAT_AVE, average[0].R, average[0].D, celestial_to_ecliptic);
-	haveEclipticAve = TRUE;
-      }
-      value.Flt = ELON_AVE;
-      break;
-    case MEAS_ELAT_AVE:
-      if (!haveEclipticAve) {
-	ApplyTransform (&ELON_AVE, &ELAT_AVE, average[0].R, average[0].D, celestial_to_ecliptic);
-	haveEclipticAve = TRUE;
-      }
-      value.Flt = ELAT_AVE;
-      break;
-
-    case MEAS_RA_AVE_ERR: /* OK */
-      value.Flt = average[0].dR;
-      break;
-    case MEAS_DEC_AVE_ERR: /* OK */
-      value.Flt = average[0].dD;
-      break;
-    case MEAS_U_RA: /* OK */
-      value.Flt = average[0].uR;
-      break;
-    case MEAS_U_DEC: /* OK */
-      value.Flt = average[0].uD;
-      break;
-    case MEAS_U_RA_ERR: /* OK */
-      value.Flt = average[0].duR;
-      break;
-    case MEAS_U_DEC_ERR: /* OK */
-      value.Flt = average[0].duD;
-      break;
-    case MEAS_PAR: /* OK */
-      value.Flt = average[0].R;
-      break;
-    case MEAS_PAR_ERR: /* OK */
-      value.Flt = average[0].D;
-      break;
-    case MEAS_CHISQ_POS: /* OK */
-      value.Flt = average[0].ChiSqAve;
-      break;
-    case MEAS_CHISQ_PM: /* OK */
-      value.Flt = average[0].ChiSqPM;
-      break;
-    case MEAS_CHISQ_PAR: /* OK */
-      value.Flt = average[0].ChiSqPar;
-      break;
-    case MEAS_TMEAN: /* OK */
-      value.Flt = TimeValue (average[0].Tmean, TimeReference, TimeFormat);
-      break;
-    case MEAS_TRANGE: /* OK */
-      value.Flt = TimeValue (average[0].Trange, 0, TimeFormat);
-      break;
-    case MEAS_NMEAS: /* OK */
-      value.Int = average[0].Nmeasure;
-      break;
-    case MEAS_NMISS: /* OK */
-      value.Int = average[0].Nmissing;
-      break;
-    case MEAS_NPOS: /* OK */
-      value.Int = average[0].Npos;
-      break;
-    case MEAS_OBJ_FLAGS: /* OK */
-      value.Int = average[0].flags;
-      break;
-    // note that these represent the ra displacement relative to the average, not 
-    // the error.
-    case MEAS_RA_OFFSET: /* OK */
-      value.Flt = measure[0].dR;
-      break;
-    case MEAS_DEC_OFFSET: /* OK */
-      value.Flt = measure[0].dD;
-      break;
-    case MEAS_RA_FIT_OFFSET: /* OK */
-      dT = (measure[0].t - average[0].Tmean) / (86400*365.25);
-      value.Flt = average[0].uR * dT + measure[0].dR;
-      break;
-    case MEAS_DEC_FIT_OFFSET: /* OK */
-      dT = (measure[0].t - average[0].Tmean) / (86400*365.25);
-      value.Flt = average[0].uD * dT + measure[0].dD;
-      break;
-    case MEAS_RA_OFFSET_ERR: /* OK */
-      value.Flt = NAN;
-      break;
-    case MEAS_DEC_OFFSET_ERR: /* OK */
-      value.Flt = NAN;
-      break;
-    case MEAS_AIRMASS: /* OK */
-      value.Flt = measure[0].airmass;
-      break;
-    case MEAS_AZ: /* OK */
-      value.Flt = measure[0].az;
-      break;
-    case MEAS_ALT: /* OK */
-      value.Flt = 90.0 - DEG_RAD*acos(1.0/measure[0].airmass);
-      break;
-    case MEAS_EXPTIME: /* OK */
-      value.Flt = pow (10.0, measure[0].dt * 0.4);
-      break;
-    case MEAS_PHOTCODE_EQUIV: /* OK */
-      value.Int = GetPhotcodeEquivCodebyCode (measure[0].photcode);
-      break;
-    case MEAS_PHOTCODE: /* OK */
-      value.Int = measure[0].photcode;
-      break;
-    case MEAS_TIME: /* OK */
-      value.Flt = TimeValue (measure[0].t, TimeReference, TimeFormat);
-      break;
-    case MEAS_FWHM: /* OK */
-      value.Flt = FromShortPixels(measure[0].FWx + measure[0].FWy) / 2.0;
-      break;
-    case MEAS_FWHM_MAJ: /* OK */
-      value.Flt = FromShortPixels(measure[0].FWx);
-      break;
-    case MEAS_FWHM_MIN: /* OK */
-      value.Flt = FromShortPixels(measure[0].FWy);
-      break;
-    case MEAS_THETA: /* OK */
-      value.Flt = FromShortDegrees(measure[0].theta);
-      break;
-    case MEAS_MXX: /* OK */
-      value.Flt = FromShortPixels(measure[0].Mxx);
-      break;
-    case MEAS_MXY: /* OK */
-      value.Flt = FromShortPixels(measure[0].Mxy);
-      break;
-    case MEAS_MYY: /* OK */
-      value.Flt = FromShortPixels(measure[0].Myy);
-      break;
-    case MEAS_DOPHOT: /* OK */
-      value.Int = (measure[0].photFlags >> 16);
-      break;
-    case MEAS_DB_FLAGS: /* ? */
-      value.Int = measure[0].dbFlags;
-      break;
-    case MEAS_PHOT_FLAGS: /* ? */
-      value.Int = measure[0].photFlags;
-      break;
-    case MEAS_XCCD: /* OK */
-/* I need to perform this conversion for ELIXIR and LONEOS formats on load */      
-# if 1
-      value.Flt = measure[0].Xccd;
-# else
-      { 
-	Image *image;
-	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, measure[0].imageID);
-	if (image == NULL) break;
-	RD_to_XY (&x, &y, ra, dec, &image[0].coords);
-	value.Flt = x;
-      }
-# endif
-      break;
-    case MEAS_YCCD: /* OK */
-/* I need to perform this conversion for ELIXIR and LONEOS formats on load */      
-# if 1
-      value.Flt = measure[0].Yccd;
-# else
-      {
-	Image *image;
-	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, measure[0].imageID);
-	if (image == NULL) break;
-	RD_to_XY (&x, &y, ra, dec, &image[0].coords);
-	value.Flt = y;
-      }
-# endif
-      break;
-    case MEAS_XCCD_ERR: /* OK */
-      value.Flt = FromShortPixels(measure[0].dXccd);
-      break;
-    case MEAS_YCCD_ERR: /* OK */
-      value.Flt = FromShortPixels(measure[0].dYccd);
-      break;
-    case MEAS_POS_SYS_ERR: /* OK */
-      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 = MatchMosaic (measure[0].t, measure[0].photcode);
-      if (mosaic == NULL) break;
-      RD_to_XY (&x, &y, ra, dec, mosaic);
-      value.Flt = 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.Flt = y;
-      break;
-
-    case MEAS_SKY: /* OK */
-      value.Flt = measure[0].Sky;
-      break;
-    case MEAS_dSKY: /* OK */
-      value.Flt = measure[0].dSky;
-      break;
-    case MEAS_DET_ID: /* OK */
-      value.Int = measure[0].detID;
-      break;
-    case MEAS_OBJ_ID: /* OK */
-      value.Int = average[0].objID;
-      break;
-    case MEAS_CAT_ID: /* OK */
-      value.Int = average[0].catID;
-      break;
-    case MEAS_IMAGE_ID: /* OK */
-      value.Int = measure[0].imageID;
-      break;
-    case MEAS_PSF_QF: /* OK */
-      value.Flt = measure[0].psfQual;
-      break;
-    case MEAS_PSF_QF_PERFECT: /* OK */
-      value.Flt = NAN;
-      break;
-    case MEAS_PSF_CHISQ: /* OK */
-      value.Flt = measure[0].psfChisq;
-      break;
-    case MEAS_PSF_NDOF: /* OK */
-      value.Int = measure[0].psfNdof;
-      break;
-    case MEAS_PSF_NPIX: /* OK */
-      value.Int = measure[0].psfNpix;
-      break;
-    case MEAS_CR_NSIGMA: /* OK */
-      value.Flt = measure[0].crNsigma;
-      break;
-    case MEAS_EXT_NSIGMA: /* OK */
-      value.Flt = measure[0].extNsigma;
-      break;
-    case MEAS_EXTERN_ID: /* OK */
-      {
-	Image *image;
-	image = MatchImage (measure[0].t, measure[0].photcode, measure[0].imageID);
-	if (image == NULL) break;
-	value.Int = image->externID;
-      }
-      break;
-
-      // add the star/galaxy sep -- 
-  }
-  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: unk/Ohana/src/opihi/dvo/dbFields.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/dbFields.c	(revision 31634)
+++ 	(revision )
@@ -1,450 +1,0 @@
-# include "dvoshell.h"
-
-void dbFreeFields (dbField *fields, int Nfields) {
-
-  int i;
-
-  if (fields == NULL) return;
-
-  for (i = 0; i < Nfields; i++) {
-    if (fields[i].name != NULL) free (fields[i].name);
-    if (fields[i].photcode != NULL) {
-      if (fields[i].photcode[0].type == PHOT_MAG) {
-        free (fields[i].photcode);
-      }
-    }
-  }
-  free (fields);
-}
-
-void dbInitField (dbField *field) {
-  field->name = NULL;
-  field->extract = FALSE;
-  field->table = 0;
-  field->ID = 0;
-  field->type = OPIHI_FLT;
-  field->magMode = 0;
-  field->photcode = NULL;
-}
-
-int GetMagMode (char *string) {
-
-  if (!strcasecmp (string, "inst"))      return (MAG_INST);
-  if (!strcasecmp (string, "cat"))       return (MAG_CAT);
-  if (!strcasecmp (string, "sys"))       return (MAG_SYS);
-  if (!strcasecmp (string, "rel"))       return (MAG_REL);
-  if (!strcasecmp (string, "cal"))       return (MAG_CAL);
-  if (!strcasecmp (string, "ave"))       return (MAG_AVE);
-  if (!strcasecmp (string, "ref"))       return (MAG_REF);
-  if (!strcasecmp (string, "ap"))        return (MAG_APER);
-  if (!strcasecmp (string, "aper"))      return (MAG_APER);
-  if (!strcasecmp (string, "err"))       return (MAG_ERR);
-  if (!strcasecmp (string, "aveerr"))    return (MAG_AVE_ERR);
-  if (!strcasecmp (string, "photflags")) return (MAG_PHOT_FLAGS);
-  if (!strcasecmp (string, "chisq"))     return (MAG_CHISQ);
-  if (!strcasecmp (string, "ncode"))     return (MAG_NCODE);
-  if (!strcasecmp (string, "nphot"))     return (MAG_NPHOT);
-  return (MAG_NONE);
-}
-
-PhotCode *ParsePhotcodeField (char *field, int *mode, int defMode) {
-
-  int useDefault;
-  char *tmpstring, *p;
-  PhotCode *code;
-
-  *mode = defMode;
-  useDefault = TRUE;
-
-  p = strchr (field, ':');
-  if (p != NULL) {
-    *mode = GetMagMode (p + 1);
-    useDefault = FALSE;
-    if (*mode == MAG_NONE) return (NULL);
-    tmpstring = strncreate (field, p - field);
-  } else {
-    tmpstring = strcreate (field);
-  }
-  if (!strcasecmp (tmpstring, "MAG")) {
-    ALLOCATE (code, PhotCode, 1);
-    code[0].code = 0;
-    strcpy (code[0].name, "MAG");
-    code[0].type = PHOT_MAG;
-    free (tmpstring);
-    return (code);
-  }
-  code = GetPhotcodebyName (tmpstring);
-  if (!code) {
-      return NULL;
-  }
-
-  // enforce compatibility
-  if (useDefault) {
-    if (code[0].type == PHOT_REF) {
-      *mode = MAG_CAT;
-    }
-    if (code[0].type == PHOT_DEP) {
-      *mode = MAG_REL;
-    }
-  } 
-  free (tmpstring);
-  return (code);
-}
-
-# define ESCAPE(F,M,T) { \
-  field->ID = (F); \
-  field->magMode = (M); \
-  field->type = (T); \
-  field->photcode = NULL; \
-  return (TRUE); }
-
-int ParseMeasureField (dbField *field, char *fieldName) {
-
-  int mode;
-  PhotCode *code;
-
-  field->table = DVO_TABLE_MEASURE;
-  field->name  = strcreate (fieldName);
-
-  if (!strcasecmp (fieldName, "GLON"))       {
-    dbExtractMeasuresInitTransform (COORD_GALACTIC);
-    ESCAPE (MEAS_GLON, MAG_NONE, OPIHI_FLT);
-  }
-  if (!strcasecmp (fieldName, "GLAT")) {
-    dbExtractMeasuresInitTransform (COORD_GALACTIC);
-    ESCAPE (MEAS_GLAT, MAG_NONE, OPIHI_FLT);
-  }
-  if (!strcasecmp (fieldName, "GLON:AVE")) {
-    dbExtractMeasuresInitTransform (COORD_GALACTIC);
-    ESCAPE (MEAS_GLON_AVE, MAG_NONE, OPIHI_FLT);
-  }
-  if (!strcasecmp (fieldName, "GLAT:AVE")) {
-    dbExtractMeasuresInitTransform (COORD_GALACTIC);
-    ESCAPE (MEAS_GLAT_AVE, MAG_NONE, OPIHI_FLT);
-  }
-
-  if (!strcasecmp (fieldName, "ELON"))       {
-    dbExtractMeasuresInitTransform (COORD_ECLIPTIC);
-    ESCAPE (MEAS_ELON, MAG_NONE, OPIHI_FLT);
-  }
-  if (!strcasecmp (fieldName, "ELAT")) {
-    dbExtractMeasuresInitTransform (COORD_ECLIPTIC);
-    ESCAPE (MEAS_ELAT, MAG_NONE, OPIHI_FLT);
-  }
-  if (!strcasecmp (fieldName, "ELON:AVE")) {
-    dbExtractMeasuresInitTransform (COORD_ECLIPTIC);
-    ESCAPE (MEAS_ELON_AVE, MAG_NONE, OPIHI_FLT);
-  }
-  if (!strcasecmp (fieldName, "ELAT:AVE")) {
-    dbExtractMeasuresInitTransform (COORD_ECLIPTIC);
-    ESCAPE (MEAS_ELAT_AVE, MAG_NONE, OPIHI_FLT);
-  }
-
-  if (!strcasecmp (fieldName, "RA"))         	 ESCAPE (MEAS_RA,             MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "DEC"))        	 ESCAPE (MEAS_DEC,            MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "RA:AVE"))     	 ESCAPE (MEAS_RA_AVE,         MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "DEC:AVE"))    	 ESCAPE (MEAS_DEC_AVE,        MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "RA:ERR"))     	 ESCAPE (MEAS_RA_AVE_ERR,     MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "DEC:ERR"))    	 ESCAPE (MEAS_DEC_AVE_ERR,    MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "uRA"))        	 ESCAPE (MEAS_U_RA,           MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "uDEC"))       	 ESCAPE (MEAS_U_DEC,          MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "duRA"))       	 ESCAPE (MEAS_U_RA_ERR,       MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "duDEC"))      	 ESCAPE (MEAS_U_DEC_ERR,      MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "PAR"))        	 ESCAPE (MEAS_PAR,            MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "dPAR"))       	 ESCAPE (MEAS_PAR_ERR,        MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "dR"))         	 ESCAPE (MEAS_RA_OFFSET,      MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "dD"))         	 ESCAPE (MEAS_DEC_OFFSET,     MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "dR:FIT"))     	 ESCAPE (MEAS_RA_FIT_OFFSET,  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "dD:FIT"))     	 ESCAPE (MEAS_DEC_FIT_OFFSET, MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "dR:ERR"))     	 ESCAPE (MEAS_RA_OFFSET_ERR,  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "dD:ERR"))     	 ESCAPE (MEAS_DEC_OFFSET_ERR, MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "ChiSqPos"))       ESCAPE (MEAS_CHISQ_POS,      MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "ChiSqPM"))        ESCAPE (MEAS_CHISQ_PM,       MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "ChiSqPar"))       ESCAPE (MEAS_CHISQ_PAR,      MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "Tmean"))          ESCAPE (MEAS_TMEAN,          MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "Trange"))         ESCAPE (MEAS_TRANGE,         MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "nmeas"))      	 ESCAPE (MEAS_NMEAS,          MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "nmiss"))      	 ESCAPE (MEAS_NMISS,          MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "npos"))      	 ESCAPE (MEAS_NPOS,           MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "OBJFLAGS"))   	 ESCAPE (MEAS_OBJ_FLAGS,      MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "OBJ_FLAGS"))   	 ESCAPE (MEAS_OBJ_FLAGS,      MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "DB_FLAGS"))   	 ESCAPE (MEAS_DB_FLAGS,       MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "PHOT_FLAGS")) 	 ESCAPE (MEAS_PHOT_FLAGS,     MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "DBFLAGS"))   	 ESCAPE (MEAS_DB_FLAGS,       MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "PHOTFLAGS")) 	 ESCAPE (MEAS_PHOT_FLAGS,     MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "AIRMASS"))    	 ESCAPE (MEAS_AIRMASS,        MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "ALT"))        	 ESCAPE (MEAS_ALT,            MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "AZ"))         	 ESCAPE (MEAS_AZ,             MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "EXPTIME"))    	 ESCAPE (MEAS_EXPTIME,        MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "PHOTCODE"))   	 ESCAPE (MEAS_PHOTCODE,       MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "PHOTCODE:EQUIV")) ESCAPE (MEAS_PHOTCODE_EQUIV, MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "TIME"))       	 ESCAPE (MEAS_TIME,           MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "FWHM"))       	 ESCAPE (MEAS_FWHM,           MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "FWHM_MAJ"))   	 ESCAPE (MEAS_FWHM_MAJ,       MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "FWHM_MIN"))   	 ESCAPE (MEAS_FWHM_MIN,       MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "THETA"))      	 ESCAPE (MEAS_THETA,          MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "POSANGLE"))     	 ESCAPE (MEAS_POSANGLE,       MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "PLATESCALE"))   	 ESCAPE (MEAS_PLATESCALE,     MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "MXX"))       	 ESCAPE (MEAS_MXX,            MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "MYY"))       	 ESCAPE (MEAS_MYY,            MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "MXY"))       	 ESCAPE (MEAS_MXY,            MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "DOPHOT"))     	 ESCAPE (MEAS_DOPHOT,         MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "XCCD"))       	 ESCAPE (MEAS_XCCD,           MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "YCCD"))       	 ESCAPE (MEAS_YCCD,           MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "XCCD:ERR"))   	 ESCAPE (MEAS_XCCD_ERR,       MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "YCCD:ERR"))   	 ESCAPE (MEAS_YCCD_ERR,       MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "POS_SYS_ERR"))    ESCAPE (MEAS_POS_SYS_ERR,    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);
-  if (!strcasecmp (fieldName, "XCHIP"))      	 ESCAPE (MEAS_XCCD,           MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "YCHIP"))      	 ESCAPE (MEAS_YCCD,           MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "XFPA"))       	 ESCAPE (MEAS_XMOSAIC,        MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "YFPA"))       	 ESCAPE (MEAS_YMOSAIC,        MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "DETID"))      	 ESCAPE (MEAS_DET_ID,         MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "OBJID"))      	 ESCAPE (MEAS_OBJ_ID,         MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "CATID"))      	 ESCAPE (MEAS_CAT_ID,         MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "IMAGEID"))    	 ESCAPE (MEAS_IMAGE_ID,       MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "PSF_QF"))     	 ESCAPE (MEAS_PSF_QF,         MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "PSF_QF_PERFECT")) ESCAPE (MEAS_PSF_QF_PERFECT, MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "PSF_CHISQ"))  	 ESCAPE (MEAS_PSF_CHISQ,      MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "PSF_NDOF"))  	 ESCAPE (MEAS_PSF_NDOF,       MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "PSF_NPIX"))  	 ESCAPE (MEAS_PSF_NPIX,       MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "CR_NSIGMA"))  	 ESCAPE (MEAS_CR_NSIGMA,      MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "EXT_NSIGMA")) 	 ESCAPE (MEAS_EXT_NSIGMA,     MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "SKY"))        	 ESCAPE (MEAS_SKY,            MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "SKY_ERR"))    	 ESCAPE (MEAS_dSKY,           MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "externID"))    	 ESCAPE (MEAS_EXTERN_ID,      MAG_NONE, OPIHI_INT);
-
-  // for words that don't parse, try a photcode
-
-  // check for code:mode in photcode name 
-  code = ParsePhotcodeField (fieldName, &mode, MAG_REL);
-  if (code == NULL) {
-    gprint (GP_ERR, "unknown field '%s' for measurement table in DVO database\n", fieldName);
-    return (FALSE);
-  }
-
-  field->ID = MEAS_MAG;
-  field->magMode = mode;
-  switch (mode) {
-    case MAG_NCODE:
-    case MAG_NPHOT:
-    case MAG_PHOT_FLAGS:
-      field->type = OPIHI_INT;
-      break;
-    default:
-      field->type = OPIHI_FLT;
-      break;
-  }
-  field->photcode = code;
-  return (TRUE);
-}
-  
-int ParseAverageField (dbField *field, char *fieldName) {
-
-  int mode;
-  PhotCode *code;
-
-  field->table = DVO_TABLE_AVERAGE;
-  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"))  { 
-    dbExtractAveragesInitTransform (COORD_GALACTIC);
-    ESCAPE (AVE_GLON, MAG_NONE, OPIHI_FLT);
-  }
-  if (!strcasecmp (fieldName, "GLAT"))  {
-    dbExtractAveragesInitTransform (COORD_GALACTIC);
-    ESCAPE (AVE_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"))  { 
-    dbExtractAveragesInitTransform (COORD_ECLIPTIC);
-    ESCAPE (AVE_ELON, MAG_NONE, OPIHI_FLT);
-  }
-  if (!strcasecmp (fieldName, "ELAT"))  {
-    dbExtractAveragesInitTransform (COORD_ECLIPTIC);
-    ESCAPE (AVE_ELAT, MAG_NONE, OPIHI_FLT);
-  }
-
-  if (!strcasecmp (fieldName, "RA"))        ESCAPE (AVE_RA,        MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "DEC"))       ESCAPE (AVE_DEC,       MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "GLON"))      ESCAPE (AVE_GLON,      MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "GLAT"))      ESCAPE (AVE_GLAT,      MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "ELON"))      ESCAPE (AVE_ELON,      MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "ELAT"))      ESCAPE (AVE_ELAT,      MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "dRA"))       ESCAPE (AVE_RA_ERR,    MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "dDEC"))      ESCAPE (AVE_DEC_ERR,   MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "uRA"))       ESCAPE (AVE_U_RA,      MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "uDEC"))      ESCAPE (AVE_U_DEC,     MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "duRA"))      ESCAPE (AVE_U_RA_ERR,  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "duDEC"))     ESCAPE (AVE_U_DEC_ERR, MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "PAR"))       ESCAPE (AVE_PAR,       MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "dPAR"))      ESCAPE (AVE_PAR_ERR,   MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "ChiSqPos"))  ESCAPE (AVE_CHISQ_POS, MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "ChiSqPM"))   ESCAPE (AVE_CHISQ_PM, MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "ChiSqPar"))  ESCAPE (AVE_CHISQ_PAR, MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "Tmean"))     ESCAPE (AVE_TMEAN,     MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "Trange"))    ESCAPE (AVE_TRANGE,    MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "NMEAS"))     ESCAPE (AVE_NMEAS,     MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "NMISS"))     ESCAPE (AVE_NMISS,     MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "NPOS"))      ESCAPE (AVE_NPOS,      MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "NASTROM"))   ESCAPE (AVE_NPOS,      MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "FLAGS"))     ESCAPE (AVE_OBJ_FLAGS, MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "OBJ_FLAGS")) ESCAPE (AVE_OBJ_FLAGS, MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "OBJFLAGS"))  ESCAPE (AVE_OBJ_FLAGS, MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "OBJID"))     ESCAPE (AVE_OBJID,     MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "CATID"))     ESCAPE (AVE_CATID,     MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "EXTID_HI"))  ESCAPE (AVE_EXTID_HI,  MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "EXTID_LO"))  ESCAPE (AVE_EXTID_LO,  MAG_NONE, OPIHI_INT);
-
-  // if (!strcasecmp (fieldName, "Xp"))      ESCAPE (AVE_Xp,        MAG_NONE, OPIHI_FLT);
-  // if (!strcasecmp (fieldName, "TYPE"))    ESCAPE (AVE_TYPE,      MAG_NONE, OPIHI_INT);
-  // for words that don't parse, try a photcode
-
-  // check for code:mode in photcode name 
-  code = ParsePhotcodeField (fieldName, &mode, MAG_AVE);
-  if (code == NULL) {
-    gprint (GP_ERR, "unknown field '%s' for average table in DVO database\n", fieldName);
-    return (FALSE);
-  }
-
-  if (code[0].type == PHOT_MAG) {
-    gprint (GP_ERR, "'mag' is ambiguous for avextract\n");
-    free (code);
-    return (FALSE);
-  }
-
-  field->ID = AVE_MAG;
-  field->magMode = mode;
-  switch (mode) {
-    case MAG_NCODE:
-    case MAG_NPHOT:
-    case MAG_PHOT_FLAGS:
-      field->type = OPIHI_INT;
-      break;
-    default:
-      field->type = OPIHI_FLT;
-      break;
-  }
-  field->photcode = code;
-  return (TRUE);
-}
-
-int ParseImageField (dbField *field, char *fieldName) {
-
-  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, "GLON"     )) ESCAPE (IMAGE_GLON,      MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "GLAT"     )) ESCAPE (IMAGE_GLAT,      MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "ELON"     )) ESCAPE (IMAGE_ELON,      MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "ELAT"     )) ESCAPE (IMAGE_ELAT,      MAG_NONE, OPIHI_FLT);
-
-  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, "time"     )) ESCAPE (IMAGE_TIME,      MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "nstar"    )) ESCAPE (IMAGE_NSTAR,     MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "airmass"  )) ESCAPE (IMAGE_AIRMASS,   MAG_NONE, OPIHI_FLT);
-  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, "apresid"  )) ESCAPE (IMAGE_APRESID,   MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "dapresid" )) ESCAPE (IMAGE_DAPRESID,  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, "Xm"       )) ESCAPE (IMAGE_XM,        MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "photcode" )) ESCAPE (IMAGE_PHOTCODE,  MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "exptime"  )) ESCAPE (IMAGE_EXPTIME,   MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "sidtime"  )) ESCAPE (IMAGE_SIDTIME,   MAG_NONE, OPIHI_FLT);
-
-  if (!strcasecmp (fieldName, "latitude" )) ESCAPE (IMAGE_LATITUDE,  MAG_NONE, OPIHI_FLT);
-
-  if (!strcasecmp (fieldName, "detlimit" )) ESCAPE (IMAGE_DET_LIMIT, MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "satlimit" )) ESCAPE (IMAGE_SAT_LIMIT, MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "cerror"   )) ESCAPE (IMAGE_CERROR,    MAG_NONE, OPIHI_FLT);
-
-  if (!strcasecmp (fieldName, "FWHM"       )) ESCAPE (IMAGE_FWHM,      MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "FWHM_MAJ"   )) ESCAPE (IMAGE_FWHM_MAJ,  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "FWHM_MIN"   )) ESCAPE (IMAGE_FWHM_MIN,  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "FWHM_MAJOR" )) ESCAPE (IMAGE_FWHM_MAJ,  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "FWHM_MINOR" )) ESCAPE (IMAGE_FWHM_MIN,  MAG_NONE, OPIHI_FLT);
-
-  if (!strcasecmp (fieldName, "FWHM_MEDIAN"    ))   ESCAPE (IMAGE_FWHM_MEDIAN,      MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "FWHM_MAJ_MEDIAN"))   ESCAPE (IMAGE_FWHM_MAJ_MEDIAN,  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "FWHM_MIN_MEDIAN"))   ESCAPE (IMAGE_FWHM_MIN_MEDIAN,  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "FWHM_MAJOR_MEDIAN")) ESCAPE (IMAGE_FWHM_MAJ_MEDIAN,  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "FWHM_MINOR_MEDIAN")) ESCAPE (IMAGE_FWHM_MIN_MEDIAN,  MAG_NONE, OPIHI_FLT);
-
-  if (!strcasecmp (fieldName, "trate"    )) ESCAPE (IMAGE_TRATE,     MAG_NONE, OPIHI_FLT);
-
-  if (!strcasecmp (fieldName, "ncal"     )) ESCAPE (IMAGE_NCAL,      MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "sky"      )) ESCAPE (IMAGE_SKY,       MAG_NONE, OPIHI_FLT); // deprecated for now
-
-  if (!strcasecmp (fieldName, "imflags"  )) ESCAPE (IMAGE_FLAGS,     MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "flags"    )) ESCAPE (IMAGE_FLAGS,     MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "ccdnum"   )) ESCAPE (IMAGE_CCDNUM,    MAG_NONE, OPIHI_INT);
-
-  if (!strcasecmp (fieldName, "imageID"  )) ESCAPE (IMAGE_IMAGE_ID,  MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "externID" )) ESCAPE (IMAGE_EXTERN_ID, MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "sourceID" )) ESCAPE (IMAGE_SOURCE_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);
-
-  if (!strcasecmp (fieldName, "dX_SYS"  )) ESCAPE (IMAGE_X_ERR_SYS,  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "dY_SYS"  )) ESCAPE (IMAGE_Y_ERR_SYS,  MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "dM_SYS"  )) ESCAPE (IMAGE_MAG_ERR_SYS,MAG_NONE, OPIHI_FLT);
-  if (!strcasecmp (fieldName, "NFIT_PHOTOM")) ESCAPE (IMAGE_NFIT_PHOTOM,MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "NFIT_ASTROM")) ESCAPE (IMAGE_NFIT_ASTROM,MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "NLINK_PHOTOM")) ESCAPE (IMAGE_NLINK_PHOTOM,MAG_NONE, OPIHI_INT);
-  if (!strcasecmp (fieldName, "NLINK_ASTROM")) ESCAPE (IMAGE_NLINK_ASTROM,MAG_NONE, OPIHI_INT);
-
-  // for words that don't parse, try a photcode
-  gprint (GP_ERR, "unknown field '%s' for image table in DVO database\n", fieldName);
-  return (FALSE);
-}
Index: unk/Ohana/src/opihi/dvo/dbRPN.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/dbRPN.c	(revision 31634)
+++ 	(revision )
@@ -1,206 +1,0 @@
-# include "dvoshell.h"
-# define DUMPSTACK 0
-
-dbStack *dbRPN (int argc, char **argv, int *nstack) {
-  
-  int type, Nx, Ny;
-  int i, j, Nstack, Nop_stack, NSTACK;
-  dbStack *stack, *op_stack;
-
-  /* max total stack size is argc, though should be less, this is safe */
-  NSTACK = argc + 5;
-  ALLOCATE (stack, dbStack, NSTACK);
-  ALLOCATE (op_stack, dbStack, NSTACK);
-  for (i = 0; i < NSTACK; i++) {
-    dbInitStack (&stack[i]);
-    dbInitStack (&op_stack[i]);
-  }
-  
-  Nx = Ny = Nstack = Nop_stack = 0;
-  for (i = 0; i < argc; i++) {
-    
-    /* decide on priority of object */
-    type = DB_STACK_NONE;
-    /* unary operations */
-    if (!strcmp (argv[i], "abs"))    { type = DB_STACK_UNARY; goto gotit; }
-    if (!strcmp (argv[i], "int"))    { type = DB_STACK_UNARY; goto gotit; }
-    if (!strcmp (argv[i], "exp"))    { type = DB_STACK_UNARY; goto gotit; }
-    if (!strcmp (argv[i], "ten"))    { type = DB_STACK_UNARY; goto gotit; }
-    if (!strcmp (argv[i], "log"))    { type = DB_STACK_UNARY; goto gotit; }
-    if (!strcmp (argv[i], "ln"))     { type = DB_STACK_UNARY; goto gotit; }
-    if (!strcmp (argv[i], "sqrt"))   { type = DB_STACK_UNARY; goto gotit; }
-    if (!strcmp (argv[i], "erf"))    { type = DB_STACK_UNARY; goto gotit; }
-    if (!strcmp (argv[i], "sinh"))   { type = DB_STACK_UNARY; goto gotit; }
-    if (!strcmp (argv[i], "cosh"))   { type = DB_STACK_UNARY; goto gotit; }
-    if (!strcmp (argv[i], "asinh"))  { type = DB_STACK_UNARY; goto gotit; }
-    if (!strcmp (argv[i], "acosh"))  { type = DB_STACK_UNARY; goto gotit; }
-    if (!strcmp (argv[i], "sin"))    { type = DB_STACK_UNARY; goto gotit; }
-    if (!strcmp (argv[i], "cos"))    { type = DB_STACK_UNARY; goto gotit; }
-    if (!strcmp (argv[i], "tan"))    { type = DB_STACK_UNARY; goto gotit; }
-    if (!strcmp (argv[i], "dsin"))   { type = DB_STACK_UNARY; goto gotit; }
-    if (!strcmp (argv[i], "dcos"))   { type = DB_STACK_UNARY; goto gotit; }
-    if (!strcmp (argv[i], "dtan"))   { type = DB_STACK_UNARY; goto gotit; }
-    if (!strcmp (argv[i], "asin"))   { type = DB_STACK_UNARY; goto gotit; }
-    if (!strcmp (argv[i], "acos"))   { type = DB_STACK_UNARY; goto gotit; }
-    if (!strcmp (argv[i], "atan"))   { type = DB_STACK_UNARY; goto gotit; }
-    if (!strcmp (argv[i], "dasin"))  { type = DB_STACK_UNARY; goto gotit; }
-    if (!strcmp (argv[i], "dacos"))  { type = DB_STACK_UNARY; goto gotit; }
-    if (!strcmp (argv[i], "datan"))  { type = DB_STACK_UNARY; goto gotit; }
-    if (!strcmp (argv[i], "lgamma")) { type = DB_STACK_UNARY; goto gotit; }
-    if (!strcmp (argv[i], "rnd"))    { type = DB_STACK_UNARY; goto gotit; }
-    if (!strcmp (argv[i], "xramp"))  { type = DB_STACK_UNARY; goto gotit; }
-    if (!strcmp (argv[i], "yramp"))  { type = DB_STACK_UNARY; goto gotit; }
-    if (!strcmp (argv[i], "ramp"))   { type = DB_STACK_UNARY; goto gotit; }
-    if (!strcmp (argv[i], "zero"))   { type = DB_STACK_UNARY; goto gotit; }
-    if (!strcmp (argv[i], "--"))     { type = DB_STACK_UNARY; goto gotit; }
-    if (!strcmp (argv[i], "not"))    { type = DB_STACK_UNARY; goto gotit; }
-    if (!strcmp (argv[i], "isinf"))  { type = DB_STACK_UNARY; goto gotit; }
-    if (!strcmp (argv[i], "isnan"))  { type = DB_STACK_UNARY; goto gotit; }
-
-    /* binary operations */
-    if (!strcmp (argv[i], "^"))      { type = DB_STACK_POWER; goto gotit; }
-
-    if (!strcmp (argv[i], "@"))      { type = DB_STACK_MULTIPLY; goto gotit; }
-    if (!strcmp (argv[i], "/"))      { type = DB_STACK_MULTIPLY; goto gotit; }
-    if (!strcmp (argv[i], "*"))      { type = DB_STACK_MULTIPLY; goto gotit; }
-    if (!strcmp (argv[i], "%"))      { type = DB_STACK_MULTIPLY; goto gotit; }
-
-    if (!strcmp (argv[i], "+"))      { type = DB_STACK_SUM; goto gotit; }
-    if (!strcmp (argv[i], "-"))      { type = DB_STACK_SUM; goto gotit; }
-	
-    if (!strcmp (argv[i], "&"))      { type = DB_STACK_BITWISE; goto gotit; }
-    if (!strcmp (argv[i], "|"))      { type = DB_STACK_BITWISE; goto gotit; }
-
-    if (!strcmp (argv[i], "<"))      { type = DB_STACK_COMPARE; goto gotit; }
-    if (!strcmp (argv[i], ">"))      { type = DB_STACK_COMPARE; goto gotit; }
-    if (!strcmp (argv[i], "=="))     { type = DB_STACK_COMPARE; strcpy (argv[i], "E"); goto gotit; }
-    if (!strcmp (argv[i], "!="))     { type = DB_STACK_COMPARE; strcpy (argv[i], "N"); goto gotit; }
-    if (!strcmp (argv[i], "<="))     { type = DB_STACK_COMPARE; strcpy (argv[i], "L"); goto gotit; }
-    if (!strcmp (argv[i], ">="))     { type = DB_STACK_COMPARE; strcpy (argv[i], "G"); goto gotit; }
-    if (!strcmp (argv[i], ">>"))     { type = DB_STACK_COMPARE; strcpy (argv[i], "U"); goto gotit; }
-    if (!strcmp (argv[i], "<<"))     { type = DB_STACK_COMPARE; strcpy (argv[i], "D"); goto gotit; }
-
-    if (!strcmp (argv[i], "&&"))     { type = DB_STACK_LOGIC; strcpy (argv[i], "A"); goto gotit; }
-    if (!strcmp (argv[i], "||"))     { type = DB_STACK_LOGIC; strcpy (argv[i], "O"); goto gotit; }
-
-    if (!strcmp (argv[i], "("))      { type = DB_STACK_OPEN_PAR; goto gotit; }
-    if (!strcmp (argv[i], ")"))      { type = DB_STACK_CLOSE_PAR; goto gotit; }
-
-  gotit:
-    /* choose how to deal with object */
-    switch (type) {
-      case DB_STACK_POWER:  /* exponentiation: 2^2^3 = 64 != 256 (precedence is right-to-left, not left-to-right!) */
-	/* pop previous, higher operators from OP stack to stack */
-	for (j = Nop_stack - 1; (j >= 0) && (op_stack[j].type > type); j--) {
-	  stack[Nstack] = op_stack[j];
-	  op_stack[j].name = NULL;
-	  Nstack ++;
-	  Nop_stack --;
-	}
-	/* push operator on OP stack */
-	op_stack[Nop_stack].name = strcreate (argv[i]);
-	op_stack[Nop_stack].type = type;
-	Nop_stack ++;
-	break;
-      case DB_STACK_UNARY: /* unary OPs */
-      case DB_STACK_MULTIPLY: /* binary OPs */
-      case DB_STACK_SUM:
-      case DB_STACK_BITWISE: 
-      case DB_STACK_COMPARE: 
-      case DB_STACK_LOGIC: 
-	/* pop previous, higher or equal operators from OP stack to stack */
-	for (j = Nop_stack - 1; (j >= 0) && (op_stack[j].type >= type); j--) {
-	  stack[Nstack] = op_stack[j];
-	  op_stack[j].name = NULL;
-	  Nstack ++;
-	  Nop_stack --;
-	}
-	/* push operator on OP stack */
-	op_stack[Nop_stack].name = strcreate (argv[i]);
-	op_stack[Nop_stack].type = type;
-	Nop_stack ++;
-	break;
-      case DB_STACK_OPEN_PAR:  
-	/* push operator on OP stack */
-	op_stack[Nop_stack].name = strcreate (argv[i]);
-	op_stack[Nop_stack].type = type;
-	Nop_stack ++;
-	break;
-      case DB_STACK_CLOSE_PAR: 
-	/* pop rest of operators from OP stack to stack, looking for '(' */
-	for (j = Nop_stack - 1; (j >= 0) && (op_stack[j].type != DB_STACK_OPEN_PAR); j--) {
-	  stack[Nstack] = op_stack[j];
-	  op_stack[j].name = NULL;
-	  Nstack ++;
-	  Nop_stack --;
-	}
-	if ((j == -1) || (op_stack[j].type != DB_STACK_OPEN_PAR)) {
-	  push_error ("syntax error: mismatched parenthesis");
-	  Nstack = 0;
-	  goto cleanup;
-	}
-	Nop_stack --;
-	break;
-      case 0:
-	/* place the value (number or vector/matrix name) on stack */
-	/* value of 'X' is used as sentinel until we sort out values */
-	stack[Nstack].name = strcreate (argv[i]);
-	stack[Nstack].type = DB_STACK_VALUE;
-	Nstack ++;
-	break;
-    }
-  }
-
-  /* dump remaining operators on stack, checking for '(' */
-  for (j = Nop_stack - 1; j >= 0; j--) {
-    if (op_stack[j].type == DB_STACK_OPEN_PAR) {
-      push_error ("syntax error: mismatched parenthesis");
-      Nstack = 0;
-      goto cleanup;
-    }
-    stack[Nstack] = op_stack[j];
-    op_stack[j].name = NULL;
-    Nstack ++;
-  }
-
-cleanup: 
-  /*** free up unused stack space ***/
-  dbFreeStack (op_stack, NSTACK);
-  free (op_stack);
-  dbFreeStack (&stack[Nstack], NSTACK - Nstack);
-  REALLOCATE (stack, dbStack, MAX (Nstack, 1));
-  *nstack = Nstack;
-
-  for (i = 0; i < argc; i++) {
-    free (argv[i]);
-  }
-  free (argv);
-
-# if (DUMPSTACK)
-  for (i = 0; i < Nstack; i++) {
-    gprint (GP_ERR, "%s ", stack[i].name);
-  }
-  if (Nstack > 0) gprint (GP_ERR, "\n");
-  for (i = 0; i < Nstack; i++) {
-    gprint (GP_ERR, "%d ", stack[i].type);
-  }
-  if (Nstack > 0) gprint (GP_ERR, "\n");
-# endif
-
-  return (stack);
-
-}
-
-/* here are the rules for parsing a math AOL expression to RPN:
-
-1) if object is a number, push on stack
-2) if object is a third order operand (exp, sin, cos), push on op stack
-3) if object is an open paren, push on op stack,
-4) if object is a second order operand, push on stack
-5) if object is a first order operand, pop all second order operands from stack 
-until paren, push on stack
-6) if object is an end paren, pop all objects from stack until paren, 
-pop next stack, if third order op
-7) if end of line, pop all remaining objects, second order first, etc.
-   
-*/
Index: unk/Ohana/src/opihi/dvo/dbStackMath.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/dbStackMath.c	(revision 31634)
+++ 	(revision )
@@ -1,151 +1,0 @@
-# include "dvoshell.h"
-
-static int NallocBinary = 0;
-static int NallocUnary = 0;
-
-dbStack *dbBinary (dbStack *V1, dbStack *V2, char *op, dbValue *fields) {
-
-  dbStack *OUT;
-  
-# define SS_FUNC(OP) {							\
-    if (!(V1->type & DB_STACK_INT) && !(V2->type & DB_STACK_INT)) {	\
-      opihi_flt M1 = (V1->type & DB_STACK_FIELD) ? fields[V1->field].Flt : V1->FltValue; \
-      opihi_flt M2 = (V2->type & DB_STACK_FIELD) ? fields[V2->field].Flt : V2->FltValue; \
-      OUT[0].type = DB_STACK_VALUE | DB_STACK_TEMP;			\
-      OUT[0].FltValue = OP;						\
-      break;								\
-    }									\
-    if ((V1->type & DB_STACK_INT) && !(V2->type & DB_STACK_INT)) {	\
-      opihi_int M1 = (V1->type & DB_STACK_FIELD) ? fields[V1->field].Int : V1->IntValue; \
-      opihi_flt M2 = (V2->type & DB_STACK_FIELD) ? fields[V2->field].Flt : V2->FltValue; \
-      OUT[0].type = DB_STACK_VALUE | DB_STACK_TEMP;			\
-      OUT[0].FltValue = OP;						\
-      break;								\
-    }									\
-    if (!(V1->type & DB_STACK_INT) && (V2->type & DB_STACK_INT)) {	\
-      opihi_flt M1 = (V1->type & DB_STACK_FIELD) ? fields[V1->field].Flt : V1->FltValue; \
-      opihi_int M2 = (V2->type & DB_STACK_FIELD) ? fields[V2->field].Int : V2->IntValue; \
-      OUT[0].type = DB_STACK_VALUE | DB_STACK_TEMP;			\
-      OUT[0].FltValue = OP;						\
-      break;								\
-    }									\
-    if ((V1->type & DB_STACK_INT) && (V2->type & DB_STACK_INT)) {	\
-      opihi_int M1 = (V1->type & DB_STACK_FIELD) ? fields[V1->field].Int : V1->IntValue; \
-      opihi_int M2 = (V2->type & DB_STACK_FIELD) ? fields[V2->field].Int : V2->IntValue; \
-      OUT[0].type = DB_STACK_VALUE | DB_STACK_TEMP | DB_STACK_INT;	\
-      OUT[0].IntValue = OP;						\
-      break;								\
-    }									\
-  }
-
-  NallocBinary ++;
-  ALLOCATE (OUT, dbStack, 1);
-  OUT->name = NULL;
-
-  // XXX use an enum for the op...
-  switch (op[0]) { 
-    case '+': SS_FUNC(M1 + M2);
-    case '-': SS_FUNC(M1 - M2);
-    case '*': SS_FUNC(M1 * M2);
-    case '/': SS_FUNC(M1 / M2);
-    case '%': SS_FUNC((int) M1 % (int) M2);
-    case '^': SS_FUNC(pow (M1, M2));
-    case 'D': SS_FUNC(MIN (M1, M2));
-    case 'U': SS_FUNC(MAX (M1, M2));
-    case '<': SS_FUNC((M1 < M2) ? 1 : 0);
-    case '>': SS_FUNC((M1 > M2) ? 1 : 0);
-    case '&': SS_FUNC(((int)M1 & (int)M2));
-    case '|': SS_FUNC(((int)M1 | (int)M2));
-    case 'E': SS_FUNC((M1 == M2) ? 1 : 0);
-    case 'N': SS_FUNC((M1 != M2) ? 1 : 0);
-    case 'L': SS_FUNC((M1 <= M2) ? 1 : 0);
-    case 'G': SS_FUNC((M1 >= M2) ? 1 : 0);
-    case 'A': SS_FUNC((M1 && M2) ? 1 : 0);
-    case 'O': SS_FUNC((M1 || M2) ? 1 : 0);
-  default:
-    return (NULL);
-  }
-# undef SS_FUNC
-  
-  return (OUT);
-}
-
-dbStack *dbUnary (dbStack *V1, char *op, dbValue *fields) {
-
-  dbStack *OUT;
-  
-# define S_FUNC(OP,FTYPE) {						\
-    if (!(V1->type & DB_STACK_INT)) {					\
-      opihi_flt M1 = (V1->type & DB_STACK_FIELD) ? fields[V1->field].Flt : V1->FltValue; \
-      OUT[0].type = DB_STACK_VALUE | DB_STACK_TEMP;			\
-      OUT[0].FltValue = OP;						\
-      return (OUT);							\
-    }									\
-    if ((FTYPE != DB_STACK_INT) && (V1->type & DB_STACK_INT)) {		\
-      opihi_int M1 = (V1->type & DB_STACK_FIELD) ? fields[V1->field].Int : V1->IntValue; \
-      OUT[0].type = DB_STACK_VALUE | DB_STACK_TEMP;			\
-      OUT[0].FltValue = OP;						\
-      return (OUT);							\
-    }									\
-    if ((FTYPE == DB_STACK_INT) && (V1->type & DB_STACK_INT)) {		\
-      opihi_int M1 = (V1->type & DB_STACK_FIELD) ? fields[V1->field].Int : V1->IntValue; \
-      OUT[0].type = DB_STACK_VALUE | DB_STACK_TEMP | DB_STACK_INT;	\
-      OUT[0].IntValue = OP;						\
-      return (OUT);							\
-    }									\
-  }
-
-  NallocUnary ++;
-  ALLOCATE (OUT, dbStack, 1);
-  OUT->name = NULL;
-
-  if (!strcmp (op, "="))      S_FUNC(M1,0);
-  if (!strcmp (op, "abs"))    S_FUNC(fabs(M1),0);
-  if (!strcmp (op, "int"))    S_FUNC((int)(M1),DB_STACK_INT);
-  if (!strcmp (op, "exp"))    S_FUNC(exp (M1),0);
-  if (!strcmp (op, "ten"))    S_FUNC(pow (10.0,M1),0);
-  if (!strcmp (op, "log"))    S_FUNC(log10 (M1),0);
-  if (!strcmp (op, "ln"))     S_FUNC(log (M1),0);
-  if (!strcmp (op, "sqrt"))   S_FUNC(sqrt (M1),0);
-  if (!strcmp (op, "erf"))    S_FUNC(erf (M1),0);
-
-  if (!strcmp (op, "sinh"))   S_FUNC(sinh (M1),0);
-  if (!strcmp (op, "cosh"))   S_FUNC(cosh (M1),0);
-  if (!strcmp (op, "asinh"))  S_FUNC(asinh (M1),0);
-  if (!strcmp (op, "acosh"))  S_FUNC(acosh (M1),0);
-  if (!strcmp (op, "lgamma")) S_FUNC(lgamma (M1),0);
-
-  if (!strcmp (op, "sin"))    S_FUNC(sin (M1),0);
-  if (!strcmp (op, "cos"))    S_FUNC(cos (M1),0);
-  if (!strcmp (op, "tan"))    S_FUNC(tan (M1),0);
-  if (!strcmp (op, "dsin"))   S_FUNC(sin (M1*RAD_DEG),0);
-  if (!strcmp (op, "dcos"))   S_FUNC(cos (M1*RAD_DEG),0);
-  if (!strcmp (op, "dtan"))   S_FUNC(tan (M1*RAD_DEG),0);
-  if (!strcmp (op, "asin"))   S_FUNC(asin (M1),0);
-  if (!strcmp (op, "acos"))   S_FUNC(acos (M1),0);
-  if (!strcmp (op, "atan"))   S_FUNC(atan (M1),0);
-  if (!strcmp (op, "dasin"))  S_FUNC(asin (M1)*DEG_RAD,0);
-  if (!strcmp (op, "dacos"))  S_FUNC(acos (M1)*DEG_RAD,0);
-  if (!strcmp (op, "datan"))  S_FUNC(atan (M1)*DEG_RAD,0);
-  if (!strcmp (op, "rnd"))    S_FUNC(M1*0.0 + drand48(),0);
-  if (!strcmp (op, "not"))    S_FUNC(!(M1),DB_STACK_INT);
-  if (!strcmp (op, "--"))     S_FUNC(- (M1),DB_STACK_INT);
-  if (!strcmp (op, "isinf"))  S_FUNC(!finite(M1),DB_STACK_INT);
-  if (!strcmp (op, "isnan"))  S_FUNC(isnan(M1),DB_STACK_INT);
-
-  return (OUT);
-}
-
-int dbStackAllocPrint () {
-
-  fprintf (stderr, "dbAllocBinary: %d\n", NallocBinary);
-  fprintf (stderr, "dbAllocUnary:  %d\n", NallocUnary);
-  return (TRUE);
-}
-
-int dbStackAllocReset () {
-
-  NallocBinary = 0;
-  NallocUnary = 0;
-  return (TRUE);
-}
Index: unk/Ohana/src/opihi/dvo/dbStackOps.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/dbStackOps.c	(revision 31634)
+++ 	(revision )
@@ -1,54 +1,0 @@
-# include "dvoshell.h"
-
-void dbInitStack (dbStack *stack) {
-  stack[0].type   = DB_STACK_NONE;
-  stack[0].name   = NULL;
-  stack[0].field  = 0;
-  stack[0].FltValue = 0.0;
-  stack[0].IntValue = 0;
-}
-
-// free data for stack entries (free stack explicitly)
-void dbFreeStack (dbStack *stack, int Nstack) {
-
-  int i;
-
-  if (stack == NULL) return;
-
-  for (i = 0; i < Nstack; i++) {
-    if (stack[i].name != NULL) {
-      free (stack[i].name);
-      stack[i].name = NULL;
-    }
-  }
-}
-
-static int NfreeStack = 0;
-
-/* delete name and data */
-void dbFreeEntry (dbStack *stack) {
-
-  if (stack[0].name != NULL)  free (stack[0].name);
-  free (stack);
-  NfreeStack ++;
-}
-
-/* delete name and data */
-void dbFreeTempEntry (dbStack *stack) {
-
-  if (!(stack->type & DB_STACK_TEMP)) return;
-
-  if (stack[0].name != NULL)  free (stack[0].name);
-  free (stack);
-  NfreeStack ++;
-}
-
-void dbStackFreePrint () {
-
-  fprintf (stderr, "dbFreeStack: %d\n", NfreeStack);
-}
-
-void dbStackFreeReset () {
-
-  NfreeStack = 0;
-}
Index: /trunk/Ohana/src/opihi/dvo/dmt.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/dmt.c	(revision 31634)
+++ /trunk/Ohana/src/opihi/dvo/dmt.c	(revision 31635)
@@ -45,5 +45,5 @@
   }
 
-  if (!GetGraphData (&graphsky, &kapa, NULL)) return (FALSE);
+  if (!GetGraphdata (&graphsky, &kapa, NULL)) return (FALSE);
   if (!GetGraph (&graphmode, NULL, NULL)) return (FALSE);
 
Index: /trunk/Ohana/src/opihi/dvo/extract.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/extract.c	(revision 31634)
+++ /trunk/Ohana/src/opihi/dvo/extract.c	(revision 31635)
@@ -31,5 +31,5 @@
   RegionFile *regions;
 
-  if (!GetGraphData (&graphmode, NULL, NULL)) return (FALSE);
+  if (!GetGraphdata (&graphmode, NULL, NULL)) return (FALSE);
   if (!InitPhotcodes ()) return (FALSE);
 
Index: /trunk/Ohana/src/opihi/dvo/gimages.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/gimages.c	(revision 31634)
+++ /trunk/Ohana/src/opihi/dvo/gimages.c	(revision 31635)
@@ -83,5 +83,5 @@
   if (!ohana_str_to_radec (&Ra, &Dec, argv[1], argv[2])) return (FALSE);
 
-  if ((image = LoadImages (&Nimage)) == NULL) return (FALSE);
+  if ((image = LoadImagesDVO (&Nimage)) == NULL) return (FALSE);
   image_subset (image, Nimage, &subset, &Nsubset, selection, tzero, trange, TimeSelect);
   BuildChipMatch (image, Nimage);
@@ -245,5 +245,5 @@
   set_int_variable ("IMAGEphotcode:n", Nfound);
 
-  FreeImages (image);
+  FreeImagesDVO (image);
   free (subset);
 
Index: /trunk/Ohana/src/opihi/dvo/images.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/images.c	(revision 31634)
+++ /trunk/Ohana/src/opihi/dvo/images.c	(revision 31635)
@@ -130,5 +130,5 @@
   
   /* it is not an error for the database not to have any images */
-  if ((image = LoadImages (&Nimage)) == NULL) return (TRUE);
+  if ((image = LoadImagesDVO (&Nimage)) == NULL) return (TRUE);
   BuildChipMatch (image, Nimage);
 
@@ -355,5 +355,5 @@
   free (Xvec.elements.Flt);
   free (Yvec.elements.Flt);
-  FreeImages (image);
+  FreeImagesDVO (image);
   FREE (foundMosaic);
   return (TRUE);
Index: /trunk/Ohana/src/opihi/dvo/imdata.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/imdata.c	(revision 31634)
+++ /trunk/Ohana/src/opihi/dvo/imdata.c	(revision 31635)
@@ -86,5 +86,5 @@
   if ((vec = SelectVector (argv[1], ANYVECTOR, TRUE)) == NULL) return (FALSE);
 
-  if ((image = LoadImages (&Nimage)) == NULL) return (FALSE);
+  if ((image = LoadImagesDVO (&Nimage)) == NULL) return (FALSE);
   image_subset (image, Nimage, &subset, &Nsubset, selection, tzero, trange, TimeSelect);
   BuildChipMatch (image, Nimage);
@@ -222,5 +222,5 @@
   vec[0].Nelements = N;
   REALLOCATE (vec[0].elements.Flt, opihi_flt, MAX(1,N));
-  FreeImages(image);
+  FreeImagesDVO(image);
   return (TRUE);
 }
Index: /trunk/Ohana/src/opihi/dvo/imdense.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/imdense.c	(revision 31634)
+++ /trunk/Ohana/src/opihi/dvo/imdense.c	(revision 31635)
@@ -21,5 +21,5 @@
   }
 
-  if ((image = LoadImages (&Nimage)) == NULL) return (FALSE);
+  if ((image = LoadImagesDVO (&Nimage)) == NULL) return (FALSE);
   BuildChipMatch (image, Nimage);
 
@@ -70,5 +70,5 @@
   free (Xvec.elements.Flt);
   free (Yvec.elements.Flt);
-  FreeImages (image);
+  FreeImagesDVO (image);
   return (TRUE);
 
Index: /trunk/Ohana/src/opihi/dvo/imextract.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/imextract.c	(revision 31634)
+++ /trunk/Ohana/src/opihi/dvo/imextract.c	(revision 31635)
@@ -90,5 +90,5 @@
   }
 
-  if ((image = LoadImages (&Nimage)) == NULL) goto escape;
+  if ((image = LoadImagesDVO (&Nimage)) == NULL) goto escape;
   BuildChipMatch (image, Nimage);
   dbExtractImagesInit (); 
@@ -141,5 +141,5 @@
 
   // free (subset);
-  FreeImages (image);
+  FreeImagesDVO (image);
 
   if (vec) free (vec);
Index: /trunk/Ohana/src/opihi/dvo/imlist.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/imlist.c	(revision 31634)
+++ /trunk/Ohana/src/opihi/dvo/imlist.c	(revision 31635)
@@ -81,5 +81,5 @@
   }
   
-  if ((image = LoadImages (&Nimage)) == NULL) return (FALSE);
+  if ((image = LoadImagesDVO (&Nimage)) == NULL) return (FALSE);
   image_subset (image, Nimage, &subset, &Nsubset, selection, tzero, trange, TimeSelect);
   BuildChipMatch (image, Nimage);
@@ -108,5 +108,5 @@
   }
 
-  FreeImages(image);
+  FreeImagesDVO(image);
   free (subset);
   return (TRUE);
Index: /trunk/Ohana/src/opihi/dvo/imphot.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/imphot.c	(revision 31634)
+++ /trunk/Ohana/src/opihi/dvo/imphot.c	(revision 31635)
@@ -50,5 +50,5 @@
   gprint (GP_ERR, "searching in range %ds - %ds (%f seconds)\n", (int)tzero, (int)(tzero + trange), trange);
   
-  if ((image = LoadImages (&Nimage)) == NULL) return (FALSE);
+  if ((image = LoadImagesDVO (&Nimage)) == NULL) return (FALSE);
   image_subset (image, Nimage, &subset, &Nsubset, selection, tzero, trange, TRUE);
 
@@ -98,5 +98,5 @@
   }
 
-  FreeImages(image);
+  FreeImagesDVO(image);
   free (subset);
   return (TRUE);
Index: /trunk/Ohana/src/opihi/dvo/imstats.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/imstats.c	(revision 31634)
+++ /trunk/Ohana/src/opihi/dvo/imstats.c	(revision 31635)
@@ -30,5 +30,5 @@
   }
 
-  if ((image = LoadImages (&Nimage)) == NULL) return (FALSE);
+  if ((image = LoadImagesDVO (&Nimage)) == NULL) return (FALSE);
   BuildChipMatch (image, Nimage);
 
@@ -58,5 +58,5 @@
   free (Xvec.elements.Flt);
   free (Yvec.elements.Flt);
-  FreeImages (image);
+  FreeImagesDVO (image);
   return (TRUE);
 }
Index: /trunk/Ohana/src/opihi/dvo/lcat.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/lcat.c	(revision 31634)
+++ /trunk/Ohana/src/opihi/dvo/lcat.c	(revision 31635)
@@ -11,5 +11,5 @@
   SkyList *skylist;
 
-  if (!GetGraphData (&graphmode, NULL, NULL)) return (FALSE);
+  if (!GetGraphdata (&graphmode, NULL, NULL)) return (FALSE);
 
   ShowAll = FALSE;
Index: unk/Ohana/src/opihi/dvo/match_image.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/match_image.c	(revision 31634)
+++ 	(revision )
@@ -1,73 +1,0 @@
-# include "dvoshell.h"
-
-off_t match_image (Image *image, off_t Nimage, unsigned int T, short int S) {
-
-  off_t N, Nlo, Nhi, N1, N2;
-
-  /* bracket first value of interest */
-  Nlo = 0; Nhi = Nimage;
-  while (Nhi - Nlo > 10) {
-    N = 0.5*(Nlo + Nhi);
-    if (image[N].tzero < T) {
-      Nlo = N;
-    } else {
-      Nhi = N + 1;
-    }
-  }
-  N1 = Nlo;
-
-  /* bracket last value of interest */
-  Nlo = 0; Nhi = Nimage;
-  while (Nhi - Nlo > 10) {
-    N = 0.5*(Nlo + Nhi);
-    if (image[N].tzero > T) {
-      Nhi = N;
-    } else {
-      Nlo = N - 1;
-    }
-  }
-  N2 = Nhi;
-
-  for (N = N1; N < N2; N++) {
-    if ((image[N].tzero == T) && (image[N].photcode == S)) {
-      return (N);
-    }
-  }
-  return (-1);
-}
-
-off_t match_image_subset (Image *image, off_t *subset, off_t Nsubset, unsigned int T, short int S) {
-
-  off_t N, Nlo, Nhi, N1, N2;
-
-  /* bracket first value of interest */
-  Nlo = 0; Nhi = Nsubset;
-  while (Nhi - Nlo > 10) {
-    N = 0.5*(Nlo + Nhi);
-    if (image[subset[N]].tzero < T) {
-      Nlo = N;
-    } else {
-      Nhi = N + 1;
-    }
-  }
-  N1 = Nlo;
-
-  /* bracket last value of interest */
-  Nlo = 0; Nhi = Nsubset;
-  while (Nhi - Nlo > 10) {
-    N = 0.5*(Nlo + Nhi);
-    if (image[subset[N]].tzero > T) {
-      Nhi = N;
-    } else {
-      Nlo = N - 1;
-    }
-  }
-  N2 = Nhi;
-
-  for (N = N1; N < N2; N++) {
-    if ((image[subset[N]].tzero == T) && (image[subset[N]].photcode == S)) {
-      return (subset[N]);
-    }
-  }
-  return (-1);
-}
Index: /trunk/Ohana/src/opihi/dvo/photometry.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/photometry.c	(revision 31634)
+++ /trunk/Ohana/src/opihi/dvo/photometry.c	(revision 31635)
@@ -1178,5 +1178,5 @@
       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, measure[0].imageID);
+      image = MatchImageDVO (measure[0].t, measure[0].photcode, measure[0].imageID);
       if (image == NULL) break;
       RD_to_XY (&x, &y, ra, dec, &image[0].coords);
@@ -1191,5 +1191,5 @@
       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, measure[0].imageID);
+      image = MatchImageDVO (measure[0].t, measure[0].photcode, measure[0].imageID);
       if (image == NULL) break;
       RD_to_XY (&x, &y, ra, dec, &image[0].coords);
Index: /trunk/Ohana/src/opihi/dvo/region_list.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/region_list.c	(revision 31634)
+++ /trunk/Ohana/src/opihi/dvo/region_list.c	(revision 31635)
@@ -5,9 +5,9 @@
    information carried back up */
 
-static char *CATDIR  = NULL;
 static SkyTable *sky = NULL;
 
 int SetCATDIR (char *path, int verbose) {
 
+  char *CATDIR  = NULL;
   char *newpath;
   char catdir_config[256];
@@ -24,6 +24,7 @@
   }
 
-  if (CATDIR != NULL) free (CATDIR);
-  CATDIR = strcreate (newpath);
+  CATDIR = newpath;
+  // save the new value in libdvo
+  dvo_set_catdir(CATDIR);
 
   if (VarConfig ("GSCFILE",  "%s", gscfile) == NULL) gscfile[0] = 0;
@@ -51,6 +52,10 @@
 
 char *GetCATDIR () {
+  char *CATDIR = dvo_get_catdir();
+
   if (CATDIR == NULL) {
-    SetCATDIR (NULL, FALSE);
+    if (SetCATDIR (NULL, FALSE)) {
+        CATDIR = dvo_get_catdir();
+    }
   }
   return (CATDIR);
@@ -136,4 +141,5 @@
   if (selection->name != NULL) {
     char filename[256];
+    char *CATDIR = dvo_get_catdir();
 
     ALLOCATE (skylist, SkyList, 1);
@@ -158,5 +164,5 @@
     Graphdata graphsky;
 
-    if (!GetGraphData (&graphsky, NULL, NULL)) {
+    if (!GetGraphdata (&graphsky, NULL, NULL)) {
       gprint (GP_ERR, "region display not available\n");
       return (NULL);
@@ -201,4 +207,6 @@
   ALLOCATE (skylist[0].filename, char *, NREGIONS);
   skylist[0].ownElements = TRUE; // free these elements when freeing the list
+
+  char *CATDIR = dvo_get_catdir();
 
   while (fscanf (f, "%s", filename) != EOF) {
Index: /trunk/Ohana/src/opihi/dvo/skycoverage.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/skycoverage.c	(revision 31634)
+++ /trunk/Ohana/src/opihi/dvo/skycoverage.c	(revision 31635)
@@ -186,5 +186,5 @@
   PutCoords (&coords, &buf[0].header);
 
-  image = LoadImages(&Nimage);
+  image = LoadImagesDVO(&Nimage);
   if (image == NULL) {
       return (FALSE);
@@ -266,5 +266,5 @@
     }
   }
-  FreeImages(image);
+  FreeImagesDVO(image);
   return (TRUE);
 }
Index: /trunk/Ohana/src/opihi/dvo/skyregion.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/skyregion.c	(revision 31634)
+++ /trunk/Ohana/src/opihi/dvo/skyregion.c	(revision 31635)
@@ -1,8 +1,10 @@
 # include "dvoshell.h"
 
+#ifdef NO_MOVED_TO_DVO
 static double RAs = 0.0;
 static double RAe = 0.0;
 static double DECs = 0.0;
 static double DECe = 0.0;
+#endif
 
 // define the sky region for which extractions are limited
@@ -10,4 +12,7 @@
   
   if (argc == 1) {
+    double RAs, RAe, DECs, DECe;
+    get_skyregion(&RAs, &RAe, &DECs, &DECe);
+
     gprint (GP_ERR, "current skyregion: %f - %f : %f - %f\n", RAs, RAe, DECs, DECe);
     gprint (GP_ERR, "USAGE:  skyregion (min RA) (max RA) (min DEC) (max DEC)\n");
@@ -24,5 +29,5 @@
   return (TRUE);
 }
-
+#ifdef NOT_MOVED_TO_LIBDVO
 int get_skyregion (double *Rs, double *Re, double *Ds, double *De) {
 
@@ -44,4 +49,5 @@
   return TRUE;
 }
+#endif
 
 /* find region which overlaps c at given depth (-1 : populated ) */
Index: /trunk/Ohana/src/opihi/dvo/subpix.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/subpix.c	(revision 31634)
+++ /trunk/Ohana/src/opihi/dvo/subpix.c	(revision 31635)
@@ -114,5 +114,5 @@
 
   /* load all images, extract those touching Ra, Dec */
-  if ((image = LoadImages (&Nimage)) == NULL) return (FALSE);
+  if ((image = LoadImagesDVO (&Nimage)) == NULL) return (FALSE);
   BuildChipMatch (image, Nimage);
 
@@ -150,5 +150,5 @@
   SkyListFree (skylist);
 
-  FreeImages(image);
+  FreeImagesDVO(image);
   return (TRUE);
 }
Index: /trunk/Ohana/src/opihi/include/astro.h
===================================================================
--- /trunk/Ohana/src/opihi/include/astro.h	(revision 31634)
+++ /trunk/Ohana/src/opihi/include/astro.h	(revision 31635)
@@ -27,5 +27,7 @@
 } CoordTransform;
 
+#ifndef MOVED_TO_LIBDVO
 typedef enum {COORD_NONE, COORD_CELESTIAL, COORD_GALACTIC, COORD_ECLIPTIC} CoordTransformSystem;
+#endif
 
 CoordTransform *InitTransform (CoordTransformSystem input, CoordTransformSystem output);
Index: unk/Ohana/src/opihi/include/convert.h
===================================================================
--- /trunk/Ohana/src/opihi/include/convert.h	(revision 31634)
+++ 	(revision )
@@ -1,25 +1,0 @@
-# include "external.h"
-
-# ifndef CONVERT_H
-# define CONVERT_H
-
-/*** time/coord conversion functions not supplied by libohana ***/
-time_t        TimeRef               PROTO((double time, time_t TimeReference, int TimeFormat));
-double        TimeValue             PROTO((time_t time, time_t TimeReference, int TimeFormat));
-
-int           hh_hms                PROTO((double hh, int *hr, int *mn, double *sc));
-int           dd_dms                PROTO((double dd, int *dg, int *mn, double *sc));
-int           hms_format            PROTO((char *line, double value));
-int           dms_format            PROTO((char *line, double value));
-int           hh_hm                 PROTO((double hh, int *hr, double *mn));
-int           day_to_sec            PROTO((char *string, time_t *second));
-int           hms_to_sec            PROTO((char *string, time_t *second));
-char         *ohana_sec_to_hms      PROTO((time_t second));
-char         *ohana_sec_to_day      PROTO((time_t second));
-
-char         *meade_deg_to_str      PROTO((double deg));
-char         *meade_ra_to_str       PROTO((double deg));
-char         *meade_dec_to_str      PROTO((double deg));
-char         *strptime              PROTO((const char *s, const char *format, struct tm *tm));
-
-# endif
Index: /trunk/Ohana/src/opihi/include/dvomath.h
===================================================================
--- /trunk/Ohana/src/opihi/include/dvomath.h	(revision 31634)
+++ /trunk/Ohana/src/opihi/include/dvomath.h	(revision 31635)
@@ -7,6 +7,6 @@
 
 # define NCHARS 256
-# define opihi_flt double
-# define opihi_int int
+// # define opihi_flt double
+// # define opihi_int int
 // NOTE: if opihi_int is changed to unsigned, all subtraction and negation operations
 // need to result in a float value (or 3 - 5 will yield the unexpected value 2^32 - 2)
@@ -26,5 +26,7 @@
 enum {ANYVECTOR, NEWVECTOR, OLDVECTOR};
 enum {ANYBUFFER, NEWBUFFER, OLDBUFFER};
+#ifdef NOT_MOVED_TO_LIBDVO
 enum {OPIHI_FLT, OPIHI_INT};
+#endif
 
 typedef struct {			/* representation of a variable (0-D) */
@@ -64,5 +66,6 @@
 /* math functions */
 char         *dvomath               PROTO((int argc, char **argv, int *size, int maxsize));
-char        **isolate_elements      PROTO((int argc, char **argv, int *nstack));
+// MOVED to libohana
+// char        **isolate_elements      PROTO((int argc, char **argv, int *nstack));
 StackVar     *convert_to_RPN        PROTO((int argc, char **argv, int *nstack));
 int           check_stack           PROTO((StackVar *stack, int Nstack, int validsize));
@@ -144,5 +147,7 @@
 /* why are these in here? */
 int           gfits_copy_matrix_info (Matrix *matrix1, Matrix *matrix2);
+#ifndef MOVED_TO_LIBDVO
 int           GetTimeFormat         PROTO((time_t *TimeReference, int *TimeFormat));
+#endif
 
 # endif
Index: /trunk/Ohana/src/opihi/include/dvoshell.h
===================================================================
--- /trunk/Ohana/src/opihi/include/dvoshell.h	(revision 31634)
+++ /trunk/Ohana/src/opihi/include/dvoshell.h	(revision 31635)
@@ -2,8 +2,10 @@
 # include "basic.h"
 # include "astro.h"
+# include "dvo.h"
 
 # ifndef DVOSHELL_H
 # define DVOSHELL_H
 
+#ifdef NOT_MOVED_TO_LIBDVO
 typedef enum {
   DB_STACK_NONE  = 0,
@@ -232,5 +234,4 @@
 };
 
-
 enum {DVO_TABLE_AVERAGE, DVO_TABLE_MEASURE, DVO_TABLE_IMAGE};
 enum {DVO_DB_CMDLINE_ERROR, DVO_DB_CMDLINE_IS_END, DVO_DB_CMDLINE_IS_WHERE, DVO_DB_CMDLINE_IS_MATCH}; 
@@ -268,4 +269,6 @@
   opihi_int Int;
 } dbValue;
+
+#endif // notdef MOVED_TO_LIBDVO
 
 typedef struct {
@@ -313,7 +316,9 @@
 void          FreeDVO               PROTO((void));
 int           InitPhotcodes         PROTO((void));
+#ifdef NOT_MOVED_TO_DVO
 Image        *LoadImages            PROTO((off_t *Nimage));
 void          FreeImages            PROTO((Image *images));
 Image        *MatchImage            PROTO((unsigned int time, short int source, unsigned int imageID));
+#endif
 Coords       *MatchMosaic           PROTO((unsigned int time, short int source));
 int           Quality               PROTO((Measure *measure, int IsDophot));
@@ -347,5 +352,7 @@
 CMPstars     *cmpReadText           PROTO((FILE *f, off_t *nstars));
 int           RD_to_XYpic           PROTO((double *x, double *y, double r, double d, Coords *coords, double Rmin, double Rmax, double Rmid, int *leftside));
-
+int wordhash (char *word);
+
+#ifdef NOT_MOVED_TO_LIBDVO
 // dvo DB field functions
 dbField     *dbCmdlineFields        PROTO((int argc, char **argv, int table, int *last, int *nfields));
@@ -361,4 +368,5 @@
 dbStack     *dbBinary               PROTO((dbStack *V1, dbStack *V2, char *op, dbValue *fields));
 dbStack     *dbUnary                PROTO((dbStack *V1, char *op, dbValue *fields));
+#endif
 
 int          GetMagMode             PROTO((char *string));
@@ -368,19 +376,20 @@
 int          ParseImageField        PROTO((dbField *field, char *fieldName));
 
-dbValue      dbExtractAverages      PROTO((Average *average, SecFilt *secfilt, Measure *measure, dbField *field));
 dbValue      dbExtractMeasures      PROTO((Average *average, SecFilt *secfilt, Measure *measure, dbField *field));
 dbValue      dbExtractImages        PROTO((Image *image, off_t Nimage, off_t N, dbField *field));
+#ifdef NOT_MOVED_TO_LIBDVO
+dbValue      dbExtractAverages      PROTO((Average *average, SecFilt *secfilt, Measure *measure, dbField *field));
 
 void 	     dbInitField            PROTO((dbField *field));
 void 	     dbFreeFields           PROTO((dbField *fields, int Nfields));
 int          dbAstroRegionLimits    PROTO((dbStack **stack, int *nstack, SkyRegionSelection *selection, int table));
-char        *strfloat               PROTO((float value));
-
 int get_skyregion (double *Rs, double *Re, double *Ds, double *De);
 int set_skyregion (double Rs, double Re, double Ds, double De);
 void FreeImageSelection (void);
+char        *strfloat               PROTO((float value));
+
 
 void FreeSkyRegionSelection (SkyRegionSelection *selection);
-int wordhash (char *word);
+
 
 int dbExtractMeasuresInitTransform (CoordTransformSystem target);
@@ -395,4 +404,5 @@
 int dbExtractImagesInit (void);
 int dbExtractImagesReset (void);
+#endif // NOT_MOVED_TO_LIBDVO
 
 # endif
Index: /trunk/Ohana/src/opihi/include/shell.h
===================================================================
--- /trunk/Ohana/src/opihi/include/shell.h	(revision 31634)
+++ /trunk/Ohana/src/opihi/include/shell.h	(revision 31635)
@@ -12,7 +12,9 @@
 # define MACRO_NAME(s) MACRO_STRING(s)
 
+typedef enum {GP_FILE, GP_BUFF} gpMode;
+#ifdef NOT_MOVED_TO_LIBOHANA
 /* enums used by gprint functions */
-typedef enum {GP_FILE, GP_BUFF} gpMode;
 typedef enum {GP_LOG, GP_ERR} gpDest;
+#endif
 typedef enum {OPIHI_VERBOSE_OFF, OPIHI_VERBOSE_ON, OPIHI_VERBOSE_ERROR} OpihiVerboseMode;
 
@@ -122,7 +124,10 @@
 char         *VarConfigEntry           	PROTO((char *keyword, char *mode, int entry, void *ptr));
 
+#ifndef NOT_MOVED_TO_DVO
 int           init_error                PROTO((void));
 int           push_error                PROTO((char *line));
 int           print_error               PROTO((void));
+#endif
+
 void          handle_interrupt      	PROTO((int));
 char        **command_completer     	PROTO((const char *, int, int));
@@ -168,5 +173,7 @@
 FILE         *gprintGetFile   		PROTO((gpDest dest));
 char         *gprintGetName   		PROTO((gpDest dest));
+#ifdef NOT_MOVED_TO_LIBOHANA
 int           gprint          		PROTO((gpDest dest, char *format, ...)) OHANA_FORMAT(printf, 2, 3);
+#endif
 int           gwrite          		PROTO((char *buffer, int size, int N, gpDest dest));
 int           gprint_syserror           PROTO((gpDest dest, int myError, char *format, ...)) OHANA_FORMAT(printf, 3, 4);
Index: /trunk/Ohana/src/opihi/lib.data/Makefile
===================================================================
--- /trunk/Ohana/src/opihi/lib.data/Makefile	(revision 31634)
+++ /trunk/Ohana/src/opihi/lib.data/Makefile	(revision 31635)
@@ -21,5 +21,4 @@
 $(SDIR)/svdcmp.$(ARCH).o		\
 $(SDIR)/svdcmp_bond_new.$(ARCH).o		\
-$(SDIR)/convert.$(ARCH).o		\
 $(SDIR)/bracket.$(ARCH).o		\
 $(SDIR)/spline.$(ARCH).o		\
@@ -48,5 +47,4 @@
 $(INC)/shell.h \
 $(INC)/dvomath.h \
-$(INC)/convert.h \
 $(INC)/display.h 
 
Index: unk/Ohana/src/opihi/lib.data/convert.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.data/convert.c	(revision 31634)
+++ 	(revision )
@@ -1,305 +1,0 @@
-# include "convert.h"
-# define _XOPEN_SOURCE /* glibc2 (strptime) needs this */
-# include <time.h>
-
-/** additional time / coordinate conversions not supplied by libohana **/
-
-int hh_hms (double hh, int *hr, int *mn, double *sc) {
-
-  int N, flag;
-
-  flag = SIGN(hh);
-  hh = fabs(hh);
-
-  // rationalize hh to range -24.0 < hh < 24.0
-  if (hh >= 24.0) {
-    N = (int)(hh/24.0);
-    hh -= 24.0*N;
-  }
-
-  *hr = (int) hh;
-  *mn = (int) 60*(hh - *hr);
-  *sc = 3600.0*(hh - *hr - *mn / 60.0);
-  if (*sc > 59.99) {
-    *sc = 0.0;
-    *mn += 1.0;
-  }
-  *hr *= flag;
-  return (TRUE);
-}
- 
-int dd_dms (double dd, int *dg, int *mn, double *sc) {
-
-  int flag;
-
-  flag = SIGN(dd);
-  dd = fabs (dd);
-  *dg = (int) dd;
-  *mn = (int) 60*(dd - *dg);
-  *sc = 3600.0*(dd - *dg - *mn/60.0);
-  if (*sc > 59.99) {
-    *sc = 0;
-    *mn += 1.0;
-  }
-  *dg *= flag;
-  return (TRUE);
-}
- 
-int hms_format (char *line, double value) {
-
-  int hr, mn;
-  double sc;
-
-  hh_hms (value, &hr, &mn, &sc);
-  hr = (int) value;
-  if (isnan (value))
-    sprintf (line, "xx:xx:xx.xx");
-  else {
-    if (value < 0) {
-      sprintf (line, "-%02d:%02d:%05.2f", abs(hr), mn, sc);
-    } else {
-      sprintf (line, "+%02d:%02d:%05.2f", hr, mn, sc);
-    }
-  }      
-  return (TRUE);
-}
-
-int dms_format (char *line, double value) {
-
-  int dg, mn;
-  double sc;
-
-  dd_dms (value, &dg, &mn, &sc);
-  if (value < 0) {
-    sprintf (line, "-%02d:%02d:%05.2f", abs(dg), mn, sc);
-  } else {
-    sprintf (line, "+%02d:%02d:%05.2f", dg, mn, sc);
-  }
-  return (TRUE);
-}
-
-/***** convert 00:00:00 or 00:00 to 0 - 86400 ****/
-int hms_to_sec (char *string, time_t *second) {
-  
-  char *p;
-  struct tm time;
-
-  p = strptime (string, "%H:%M:%S", &time);
-  if (p != NULL) goto valid;
-
-  p = strptime (string, "%H:%M", &time);
-  if (p != NULL) goto valid;
-
-  return (FALSE);
-    
-valid:
-  if (*p) return (FALSE);
-  *second = time.tm_hour*3600 + time.tm_min*60 + time.tm_sec;
-  return (TRUE);
-}
-
-/***** convert Mon[@00:00:00] or 00:00 to 0 - 86400*7 ****/
-int day_to_sec (char *string, time_t *second) {
-  
-  char *p;
-  struct tm time;
-
-  bzero (&time, sizeof(time));
-  p = strptime (string, "%A@%H:%M:%S", &time);
-  if (p != NULL) goto valid;
-
-  p = strptime (string, "%A@%H:%M", &time);
-  if (p != NULL) goto valid;
-
-  p = strptime (string, "%A@%H", &time);
-  if (p != NULL) goto valid;
-
-  p = strptime (string, "%A", &time);
-  if (p != NULL) goto valid;
-
-  return (FALSE);
-
-valid:
-  if (*p) return (FALSE);
-  *second = time.tm_wday*86400 + time.tm_hour*3600 + time.tm_min*60 + time.tm_sec;
-  return (TRUE);
-}
-
-/***** convert seconds to HH:MM:SS ****/
-char *ohana_sec_to_hms (time_t second) {
-  
-  struct tm *gmt;
-  char *line;
-
-  ALLOCATE (line, char, 64);
-  gmt   = gmtime (&second);
-  sprintf (line, "%02d:%02d:%02d", gmt[0].tm_hour, gmt[0].tm_min, gmt[0].tm_sec); 
-  return (line);
-}
-
-/***** convert seconds to Day@HH:MM:SS ****/
-char *ohana_sec_to_day (time_t second) {
-  
-  struct tm *gmt;
-  char *line;
-
-  ALLOCATE (line, char, 64);
-  gmt   = gmtime (&second);
-  switch (gmt[0].tm_wday) {
-    case 0:
-      sprintf (line, "Sun@%02d:%02d:%02d", gmt[0].tm_hour, gmt[0].tm_min, gmt[0].tm_sec); 
-      break;
-    case 1:
-      sprintf (line, "Mon@%02d:%02d:%02d", gmt[0].tm_hour, gmt[0].tm_min, gmt[0].tm_sec); 
-      break;
-    case 2:
-      sprintf (line, "Tue@%02d:%02d:%02d", gmt[0].tm_hour, gmt[0].tm_min, gmt[0].tm_sec); 
-      break;
-    case 3:
-      sprintf (line, "Wed@%02d:%02d:%02d", gmt[0].tm_hour, gmt[0].tm_min, gmt[0].tm_sec); 
-      break;
-    case 4:
-      sprintf (line, "Thu@%02d:%02d:%02d", gmt[0].tm_hour, gmt[0].tm_min, gmt[0].tm_sec); 
-      break;
-    case 5:
-      sprintf (line, "Fri@%02d:%02d:%02d", gmt[0].tm_hour, gmt[0].tm_min, gmt[0].tm_sec); 
-      break;
-    case 6:
-      sprintf (line, "Sat@%02d:%02d:%02d", gmt[0].tm_hour, gmt[0].tm_min, gmt[0].tm_sec); 
-      break;
-  }
-  return (line);
-}
-
-int hh_hm (double hh, int *hr, double *mn) {
-
-  int flag;
-
-  flag = SIGN(hh);
-  hh = fabs (hh);
-
-  *mn = 60.0*(hh - (int)hh);
-  *hr = (int) hh;
-  *hr *= flag;
-  return (TRUE);
-}
-
-char *meade_deg_to_str (double deg) {
-
-  int hr;
-  double mn;
-  char *line;
-
-  ALLOCATE (line, char, 16);
-
-  hh_hm (deg, &hr, &mn);
-
-  sprintf (line, "%03d:%04.1f", abs(hr), mn);
-  return (line);
-}
-
-char *meade_ra_to_str (double deg) {
-
-  int hr;
-  double mn;
-  char *line;
-
-  ALLOCATE (line, char, 16);
-
-  hh_hm (deg/15.0, &hr, &mn);
-
-  sprintf (line, "%02d:%04.1f", abs(hr), mn);
-  return (line);
-}
-
-char *meade_dec_to_str (double deg) {
-
-  int hr;
-  double mn;
-  char *line;
-
-  ALLOCATE (line, char, 16);
-
-  hh_hm (deg, &hr, &mn);
-
-  if (deg < 0) {
-    sprintf (line, "-%02d:%04.1f", abs(hr), mn);
-  } else {
-    sprintf (line, "+%02d:%04.1f", hr, mn);
-  }      
-  return (line);
-}
-
-/* convert UNIX time to a value referenced to the TimeReference in the given unit */
-double TimeValue (time_t time, time_t TimeReference, int TimeFormat) {
-
-  double value, dt;
-
-  dt = (time > TimeReference) ? (time - TimeReference) : -1 * (double)(TimeReference - time);
-  switch (TimeFormat) {
-  case TIME_JD:
-    value = time / 86400.0 + 2440587.5;
-    break;
-  case TIME_MJD:
-    value = time / 86400.0 + 40587.0;
-    break;
-  case TIME_DAYS:
-    value = dt / 86400.0;
-    break;
-  case TIME_HOURS:
-    value = dt / 3600.0;
-    break;
-  case TIME_MINUTES:
-    value = dt / 60.0;
-    break;
-  case TIME_SECONDS:
-  default:
-    value = dt;
-    break;
-  }
-  return (value);
-}
-  
-/* convert time value referenced to the TimeReference in the given unit to UNIX time */
-time_t TimeRef (double value, time_t TimeReference, int TimeFormat) {
-
-  int dt;
-  time_t time;
-
-  switch (TimeFormat) {
-  case TIME_JD:
-    time = (value -  2440587.5) * 86400.0;
-    return (time);
-    break;
-  case TIME_MJD:
-    time = (value -  40587.0) * 86400.0;
-    return (time);
-    break;
-  case TIME_DAYS:
-    dt = value * 86400.0;
-    break;
-  case TIME_HOURS:
-    dt = value * 3600.0;
-    break;
-  case TIME_MINUTES:
-    dt = value * 60.0;
-    break;
-  case TIME_SECONDS:
-  default:
-    dt = value;
-    break;
-  }
-
-  time = TimeReference + dt;
-  return (time);
-}
-
-/* times may be in forms as:
- * 20040200450s (N seconds since 1970.0)
- * 2440900.232j (julian date)
- * 99/02/23,03:22:18 (date string)
- * (separators may be anything except space, +, -)
- * 99:02:15:12:23:30
- * 99:02:15:12h23m30s
- */
-
Index: /trunk/Ohana/src/opihi/lib.data/open_kapa.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.data/open_kapa.c	(revision 31634)
+++ /trunk/Ohana/src/opihi/lib.data/open_kapa.c	(revision 31635)
@@ -162,5 +162,5 @@
 
 /* return pointers for given kapa, don't set or open */
-int GetGraphData (Graphdata *data, int *fd, char *name) {
+int GetGraphdata (Graphdata *data, int *fd, char *name) {
 
   int entry;
Index: /trunk/Ohana/src/opihi/lib.shell/Makefile
===================================================================
--- /trunk/Ohana/src/opihi/lib.shell/Makefile	(revision 31634)
+++ /trunk/Ohana/src/opihi/lib.shell/Makefile	(revision 31635)
@@ -28,5 +28,4 @@
 $(SDIR)/convert_to_RPN.$(ARCH).o	\
 $(SDIR)/dvomath.$(ARCH).o               \
-$(SDIR)/errors.$(ARCH).o		\
 $(SDIR)/evaluate_stack.$(ARCH).o  	\
 $(SDIR)/exec_loop.$(ARCH).o             \
@@ -35,5 +34,4 @@
 $(SDIR)/gprint.$(ARCH).o		\
 $(SDIR)/interrupt.$(ARCH).o	        \
-$(SDIR)/isolate_elements.$(ARCH).o 	\
 $(SDIR)/macro_create.$(ARCH).o          \
 $(SDIR)/macro_delete.$(ARCH).o          \
@@ -61,5 +59,4 @@
 $(INC)/shell.h \
 $(INC)/dvomath.h \
-$(INC)/convert.h \
 $(INC)/display.h 
 
Index: /trunk/Ohana/src/opihi/lib.shell/dvomath.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.shell/dvomath.c	(revision 31634)
+++ /trunk/Ohana/src/opihi/lib.shell/dvomath.c	(revision 31635)
@@ -1,3 +1,4 @@
 # include "opihi.h"
+# include "dvo.h"
 
 /* return value on success is temp vector/buffer name or scalar value return value on error is NULL, all
Index: unk/Ohana/src/opihi/lib.shell/errors.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.shell/errors.c	(revision 31634)
+++ 	(revision )
@@ -1,22 +1,0 @@
-# include "opihi.h"
-
-static char errorline[1024];
-
-int init_error () {
-
-  bzero (errorline, 1024);
-  return (TRUE);
-}
-
-int push_error (char *line) {
-
-  bzero (errorline, 1024);
-  strncpy (errorline, line, 1023);
-  return (TRUE);
-}
-
-int print_error () {
-
-  gprint (GP_ERR, "%s\n", errorline);
-  return (TRUE);
-}
Index: unk/Ohana/src/opihi/lib.shell/isolate_elements.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.shell/isolate_elements.c	(revision 31634)
+++ 	(revision )
@@ -1,210 +1,0 @@
-# include "opihi.h"
-
-/* local private functions */
-char **InsertValue (char **myOutput, int *Nout, int *Nchar, int *NCHAR, char c);
-char **EndOfString (char **myOutput, int *Nout, int *Nchar, int *NOUT, int *NCHAR);
-int IsAnOp (char *c);
-int IsTwoOp (char *c);
-
-char **isolate_elements (int Nin, char **in, int *nout) {
-  
-  /* local private static variables */
-  int NCHAR, Nchar, Nout, NOUT;
-  char **myOutput;
-
-  int i, j, minus, negate, plus, posate, OpStat, SciNotation;
-
-  NOUT = Nin;
-  Nchar = Nout = 0;
-  NCHAR = 256;
-  ALLOCATE (myOutput, char *, NOUT);
-  ALLOCATE (myOutput[Nout], char, NCHAR);
-
-  for (i = 0; i < Nin; i++) {
-    for (j = 0; j < strlen(in[i]); j++) {
-      SciNotation = FALSE;
-      /* identify 'negate' or 'minus' ops */
-      negate = minus = FALSE;
-      if (in[i][j] == '-') { 
-	minus = TRUE;  
-	/* if - is first thing on line, must be a negator */
-	if ((Nout == 0) && (Nchar == 0)) {  
-	  minus = FALSE;
-	  negate = TRUE;
-	  goto skip1;
-	}
-	/* check previous entry on line */
-	if (Nchar) {
-	  OpStat = IsAnOp (myOutput[Nout]);
-	  if (myOutput[Nout][0] == ')') OpStat = FALSE;
-	} else {
-	  OpStat = IsAnOp (myOutput[Nout-1]);
-	  if (myOutput[Nout-1][0] == ')') OpStat = FALSE;
-	}
-	/* if - follows an operator, must be negator */
-	if (OpStat) {
-	  minus = FALSE;
-	  negate = TRUE;
-	  goto skip1;
-	}
-	/* if - follows 'e' is part of 1e-5 */
-	if (j == 0) goto skip1;
-	if ((in[i][j-1] == 'e') || (in[i][j-1] == 'E')) {
-	  SciNotation = TRUE;
-	  negate = minus = FALSE;
-	}
-      }
-    skip1:
-      /* idenfity 'posate' or 'plus' ops */
-      posate = plus = FALSE;
-      if (in[i][j] == '+') { 
-	plus = TRUE;  
-	/* if + is first thing on line, must be a posator */
-	if ((Nout == 0) && (Nchar == 0)) {  
-	  plus = FALSE;
-	  posate = TRUE;
-	  goto skip2;
-	}
-	/* check previous entry on line */
-	if (Nchar) {
-	  OpStat = IsAnOp (myOutput[Nout]);
-	  if (myOutput[Nout][0] == ')') OpStat = FALSE;
-	} else {
-	  OpStat = IsAnOp (myOutput[Nout-1]);
-	  if (myOutput[Nout-1][0] == ')') OpStat = FALSE;
-	}
-	/* if + follows an operator, must be posator */
-	if (OpStat) {
-	  plus = FALSE;
-	  posate = TRUE;
-	  goto skip2;
-	}
-	/* if + follows 'e' is part of 1e+5 */
-	if (j == 0) goto skip2;
-	if ((in[i][j-1] == 'e') || (in[i][j-1] == 'E')) {
-	  SciNotation = TRUE;
-	  posate = plus = FALSE;
-	}
-      }
-    skip2:
-      /* operators */
-      if (negate || minus || posate || plus || (IsAnOp (&in[i][j]) && !SciNotation)) {
-	if (posate) continue;
-	myOutput = EndOfString (myOutput, &Nout, &Nchar, &NOUT, &NCHAR);
-	/* copy operator to myOutput[Nout] */
-	myOutput = InsertValue (myOutput, &Nout, &Nchar, &NCHAR, in[i][j]);
-	if (negate) {
-	  myOutput = InsertValue (myOutput, &Nout, &Nchar, &NCHAR, '-');
-	}
-
-	if (IsTwoOp (&in[i][j])) {
-	  myOutput = InsertValue (myOutput, &Nout, &Nchar, &NCHAR, in[i][j+1]);
-	  j++;
-	} 
-	myOutput = EndOfString (myOutput, &Nout, &Nchar, &NOUT, &NCHAR);
-	continue;
-      }
-      /* quoted string */
-      if (in[i][j] == '"') {
-	myOutput = InsertValue (myOutput, &Nout, &Nchar, &NCHAR, in[i][j]);
-	j++;
-	while ((j < strlen(in[i])) && (in[i][j] != '"')) {
-	  myOutput = InsertValue (myOutput, &Nout, &Nchar, &NCHAR, in[i][j]);
-	  j++;
-	}
-	if (in[i][j] != '"') continue;
-	/* 
-	  gprint (GP_ERR, "mismatched quotes\n");
-	  return (FALSE);
-	}
-	*/
-	myOutput = InsertValue (myOutput, &Nout, &Nchar, &NCHAR, in[i][j]);
-	myOutput = EndOfString (myOutput, &Nout, &Nchar, &NOUT, &NCHAR);
-	continue;
-      }
-      /* not an operator, not a quoted string */
-      if (!OHANA_WHITESPACE (in[i][j])) {
-	myOutput = InsertValue (myOutput, &Nout, &Nchar, &NCHAR, in[i][j]);
-      } else {
-	myOutput = EndOfString (myOutput, &Nout, &Nchar, &NOUT, &NCHAR);
-      }
-    }
-	myOutput = EndOfString (myOutput, &Nout, &Nchar, &NOUT, &NCHAR);
-  }
-
-  /* one extra entry is allocated, free here */
-  free (myOutput[Nout]);
-  *nout = Nout;
-  return (myOutput);
-
-}
-
-char **InsertValue (char **myOutput, int *Nout, int *Nchar, int *NCHAR, char c) {
-  myOutput[*Nout][*Nchar] = c;
-  (*Nchar) ++;
-  if ((*Nchar) >= (*NCHAR) - 2) {
-    (*NCHAR) += 256;
-    REALLOCATE (myOutput[*Nout], char, *NCHAR);
-  }
-  myOutput[*Nout][*Nchar] = 0;
-  return (myOutput);
-}
-
-char **EndOfString (char **myOutput, int *Nout, int *Nchar, int *NOUT, int *NCHAR) {
-  if ((*Nchar) > 0) {
-    myOutput[*Nout][*Nchar] = 0;
-    (*Nout) ++;
-    (*Nchar) = 0;
-    
-    if ((*Nout) >= (*NOUT) - 1) {
-      (*NOUT) += 10; 
-      REALLOCATE (myOutput, char *, (*NOUT)); 
-    } 
-    (*NCHAR) = 256;
-    ALLOCATE (myOutput[*Nout], char, (*NCHAR)); 
-  }
-  return (myOutput);
-}
-
-int IsAnOp (char *c) {
-
-  if (!strncmp (c, "*",  1)) return (TRUE);
-  if (!strncmp (c, "/",  1)) return (TRUE);
-  if (!strncmp (c, "+",  1)) return (TRUE);
-  if (!strncmp (c, "-",  1)) return (TRUE);
-  if (!strncmp (c, "^",  1)) return (TRUE);
-  if (!strncmp (c, "@",  1)) return (TRUE);
-  if (!strncmp (c, "(",  1)) return (TRUE);
-  if (!strncmp (c, ")",  1)) return (TRUE);
-  if (!strncmp (c, "&",  1)) return (TRUE);
-  if (!strncmp (c, "|",  1)) return (TRUE);
-  if (!strncmp (c, ">",  1)) return (TRUE);
-  if (!strncmp (c, "<",  1)) return (TRUE);
-  if (!strncmp (c, "<",  1)) return (TRUE);
-  if (!strncmp (c, "<<", 2)) return (TRUE);
-  if (!strncmp (c, ">>", 2)) return (TRUE);
-  if (!strncmp (c, "&&", 2)) return (TRUE);
-  if (!strncmp (c, "||", 2)) return (TRUE);
-  if (!strncmp (c, "==", 2)) return (TRUE);
-  if (!strncmp (c, "!=", 2)) return (TRUE);
-  if (!strncmp (c, "<=", 2)) return (TRUE);
-  if (!strncmp (c, ">=", 2)) return (TRUE);
-
-  return (FALSE);
-
-}
-
-int IsTwoOp (char *c) {
-
-  if (!strncmp (c, "<<", 2)) return (TRUE);
-  if (!strncmp (c, ">>", 2)) return (TRUE);
-  if (!strncmp (c, "&&", 2)) return (TRUE);
-  if (!strncmp (c, "||", 2)) return (TRUE);
-  if (!strncmp (c, "==", 2)) return (TRUE);
-  if (!strncmp (c, "!=", 2)) return (TRUE);
-  if (!strncmp (c, "<=", 2)) return (TRUE);
-  if (!strncmp (c, ">=", 2)) return (TRUE);
-
-  return (FALSE);
-
-}
Index: /trunk/Ohana/src/photdbc/include/photdbc.h
===================================================================
--- /trunk/Ohana/src/photdbc/include/photdbc.h	(revision 31634)
+++ /trunk/Ohana/src/photdbc/include/photdbc.h	(revision 31635)
@@ -111,5 +111,5 @@
 void          unique_measures (Catalog *catalog);
 void          wcatalog (Catalog *catalog);
-int           make_subcatalog (Catalog *subcatalog, Catalog *catalog);
+int           make_subcatalog (Catalog *subcatalog, Catalog *catalog, SkyRegion *region);
 void          check_directory (char *basefile);
 
Index: /trunk/Ohana/src/photdbc/src/make_subcatalog.c
===================================================================
--- /trunk/Ohana/src/photdbc/src/make_subcatalog.c	(revision 31634)
+++ /trunk/Ohana/src/photdbc/src/make_subcatalog.c	(revision 31635)
@@ -3,5 +3,5 @@
 // copy a catalog to a new subcatalog, applying some filters
 // the supplied subcatalog must already be locked, opened, and created
-int make_subcatalog (Catalog *subcatalog, Catalog *catalog) {
+int make_subcatalog (Catalog *subcatalog, Catalog *catalog, SkyRegion *region) {
   
   int found;
@@ -36,4 +36,15 @@
   for (i = 0; i < catalog[0].Naverage; i++) {
     // perform exclusions based on average properties
+
+    // XXX: temporary check make sure that this object belongs in this region
+    // used to fix the pole area in the reference catalog
+    {
+        double R = catalog[0].average[i].R;
+        double D = catalog[0].average[i].D;
+        if (R <= region->Rmin) continue;
+        if (R >  region->Rmax) continue;
+        if (D <= region->Dmin) continue;
+        if (D >  region->Dmax) continue;
+    }
 
     // exclude stars with too few measurements
Index: /trunk/Ohana/src/photdbc/src/photdbc.c
===================================================================
--- /trunk/Ohana/src/photdbc/src/photdbc.c	(revision 31634)
+++ /trunk/Ohana/src/photdbc/src/photdbc.c	(revision 31635)
@@ -65,5 +65,5 @@
 
     /* limit number of measures based on selections */
-    make_subcatalog (&outcatalog, &incatalog);
+    make_subcatalog (&outcatalog, &incatalog, skylist[0].regions[i]);
 	
     // XXX add other filters here:
Index: /trunk/Ohana/src/relastro/Makefile
===================================================================
--- /trunk/Ohana/src/relastro/Makefile	(revision 31634)
+++ /trunk/Ohana/src/relastro/Makefile	(revision 31635)
@@ -61,4 +61,5 @@
 $(SRC)/high_speed_catalogs.$(ARCH).o  \
 $(SRC)/high_speed_objects.$(ARCH).o  \
+$(SRC)/high_speed_utils.$(ARCH).o  \
 $(SRC)/relastroVisual.$(ARCH).o
 
Index: /trunk/Ohana/src/relastro/include/relastro.h
===================================================================
--- /trunk/Ohana/src/relastro/include/relastro.h	(revision 31634)
+++ /trunk/Ohana/src/relastro/include/relastro.h	(revision 31635)
@@ -131,4 +131,6 @@
 int           NphotcodesGroupA,  NphotcodesGroupB;
 PhotCode     **photcodesGroupA, **photcodesGroupB;
+char          WHERE_A[10000],          WHERE_B[10000];
+SkyRegionSelection SELECTION;
 
 int AreaSelect;
@@ -361,2 +363,8 @@
 
 int GetScatterRawRef(float *dLsig, float *dMsig, float *dRsig, int *nKeep, StarData *raw, StarData *ref, int Nstars, float SigmaLimit);
+
+int initializeConstraints();
+int applyConstraintsA();
+int applyConstraintsB();
+void setupAreaSelection(SkyRegion *region);
+
Index: /trunk/Ohana/src/relastro/src/ConfigInit.c
===================================================================
--- /trunk/Ohana/src/relastro/src/ConfigInit.c	(revision 31634)
+++ /trunk/Ohana/src/relastro/src/ConfigInit.c	(revision 31635)
@@ -48,4 +48,8 @@
   ScanConfig(config, "PHOTCODE_FILE",          "%s",  0, MasterPhotcodeFile);
 
+  // Defaults for WHERE_A are established in db_utils.c: intializeConstraints
+  ScanConfig(config, "WHERE_A",                "%s",  0, WHERE_A);
+  ScanConfig(config, "WHERE_B",                "%s",  0, WHERE_B);
+
   sprintf (ImageCat, "%s/Images.dat", CATDIR);
 
Index: /trunk/Ohana/src/relastro/src/args.c
===================================================================
--- /trunk/Ohana/src/relastro/src/args.c	(revision 31634)
+++ /trunk/Ohana/src/relastro/src/args.c	(revision 31635)
@@ -307,5 +307,5 @@
   fprintf (stderr, "  -update-chips\n");
   fprintf (stderr, "  -update-mosaics\n");
-  fprintf (stderr, "  -high-speed (code[,code,code]) (code[,code,code]) (radius)\n\n");
+  fprintf (stderr, "  -high-speed (code[,code,code]) (code[,code,code]) (radius) (whereA) (whereB) (output catdir)\n\n");
   fprintf (stderr, "  additional options: \n");
   fprintf (stderr, "  -time (start)(stop)\n");
Index: /trunk/Ohana/src/relastro/src/high_speed_catalogs.c
===================================================================
--- /trunk/Ohana/src/relastro/src/high_speed_catalogs.c	(revision 31634)
+++ /trunk/Ohana/src/relastro/src/high_speed_catalogs.c	(revision 31635)
@@ -9,4 +9,7 @@
   Catalog catalog;
 
+  // tell libdvo the CATDIR
+  dvo_set_catdir(CATDIR);
+
   // load the current sky table (layout of all SkyRegions) 
   sky = SkyTableLoadOptimal (CATDIR, SKY_TABLE, GSCFILE, FALSE, SKY_DEPTH, VERBOSE);
@@ -16,7 +19,11 @@
   if (UserCatalog) {
     skylist = SkyRegionByPoint (sky, -1, UserCatalogRA, UserCatalogDEC);
+    setupAreaSelection(skylist->regions[0]);
   } else {
     skylist = SkyListByPatch (sky, -1, &UserPatch);
+    setupAreaSelection(&UserPatch);
   }
+
+  initializeConstraints();
 
   // load data from each region file, only use bright stars
Index: /trunk/Ohana/src/relastro/src/high_speed_objects.c
===================================================================
--- /trunk/Ohana/src/relastro/src/high_speed_objects.c	(revision 31634)
+++ /trunk/Ohana/src/relastro/src/high_speed_objects.c	(revision 31635)
@@ -4,9 +4,4 @@
 # define NEXT_J { j++; continue; }
 
-// XXX these were used to spot-check specific objects
-# define REF_RA1 192.455781 
-# define REF_DEC1 2.563102 
-# define REF_RA2 192.444302113 
-# define REF_DEC2 2.5786559112 
 int high_speed_objects (SkyRegion *region, Catalog *catalog) {
 
@@ -14,5 +9,6 @@
 
   off_t i, j, m, J, ni, nj, *N1, Nslow, Ninvalid, NgroupA, NgroupB, NgroupAbad, NgroupBbad,l,i1,Noff,Nmeasure,Naverage, NAVERAGE, NMEASURE;
-  int *slowMoving, *groupA, *groupB, status, foundA, foundB, Nmatch, valid,Nmatchmeas,Nepoch,nv[2],Nmatchmeasobj;
+  int *slowMoving, *groupA, *groupB, status, Nmatch, Nmatchmeas,Nepoch,nv[2],Nmatchmeasobj;
+  int foundA, foundB;
   double *X1, *Y1;
   double dX, dY, dR, RADIUS2;
@@ -20,9 +16,9 @@
   Catalog catalog1;
 
-  int zcode, zNsec, ycode, yNsec, jcode, jNsec, hcode, hNsec, kcode, kNsec, USNO_R, USNO_N, Nsecfilt;
+  int Nsecfilt;
   char filename[1024];
   Noff = strlen(CATDIR);
-  sprintf (filename, "%s/%s", HIGH_SPEED_DIR, &catalog[0].filename[Noff]);
-  printf("%s\n",filename);
+  sprintf (filename, "%s%s", HIGH_SPEED_DIR, &catalog[0].filename[Noff]);
+  fprintf(stderr, "%s\n",filename);
   dvo_catalog_init(&catalog1, TRUE); /*initialise new catalogue*/
   catalog1.filename = strcreate(filename);
@@ -33,7 +29,4 @@
   Naverage=catalog[0].Naverage;
   Nmeasure=catalog[0].Nmeasure;
-  // ALLOCATE (catalog1.average, Average,Naverage);
-  // ALLOCATE (catalog1.measure, Measure,Nmeasure);
-  // ALLOCATE(catalog1.secfilt, SecFilt,catalog[0].Naverage*Nsecfilt);
   catalog1.filename = filename; // based on the input name, need to keep everything below the catdir portion
   catalog1.Nsecfilt  = Nsecfilt;
@@ -56,22 +49,4 @@
   REALLOCATE(catalog1.secfilt, SecFilt, NAVERAGE*Nsecfilt);
 
-  ycode = GetPhotcodeCodebyName("y");
-  yNsec = GetPhotcodeNsec(ycode);
-  
-  zcode = GetPhotcodeCodebyName("z");
-  zNsec = GetPhotcodeNsec(zcode);
-  
-  jcode = GetPhotcodeCodebyName("J");
-  jNsec = GetPhotcodeNsec(jcode);
-  
-  hcode = GetPhotcodeCodebyName("H");
-  hNsec = GetPhotcodeNsec(hcode);
-  
-  kcode = GetPhotcodeCodebyName("K");
-  kNsec = GetPhotcodeNsec(kcode);
-  
-  USNO_R = GetPhotcodeCodebyName("USNO_RED");
-  USNO_N = GetPhotcodeCodebyName("USNO_N");
-
   // high-speed between different surveys (easier case):
   // we have two sets of photcodes (A) and (B) and are looking for objects
@@ -94,5 +69,5 @@
   memset (groupB, 0, catalog[0].Naverage*sizeof(int));
 
-  fprintf (stderr, "checking "OFF_T_FMT" objects\n",  catalog[0].Naverage);
+  if (VERBOSE) fprintf (stderr, "checking "OFF_T_FMT" objects\n",  catalog[0].Naverage);
   Nslow = 0;
   Ninvalid = 0;
@@ -100,21 +75,6 @@
   NgroupBbad = 0;
 
-  fprintf (stdout, "#      RA_A  DEC_A              RA_B  DEC_B      :     pmx     pmy      dR  dt:    z      dz       y      dy       J      dJ       H      dH       K      dK\n");
-  //................270.2346670  20.2471540  270.2170434  20.2717396 :  -59.11   88.78   106.66 :   0.000  0.000   19.582  0.112   16.041  0.110   15.388  0.098   14.858  0.001
-
   // mark (exclude) objects with both sets of target photcodes
   for (i = 0; i < catalog[0].Naverage; i++) {
-
-    // if (i % 100 == 0) fprintf (stderr, ".");
-
-    // radius = hypot((REF_DEC1 - catalog[0].average[i].D), (REF_RA1 - catalog[0].average[i].R));
-    // if (radius < 0.0001) {
-    //   fprintf (stderr, "found it\n");
-    // }
-    // radius = hypot((REF_DEC2 - catalog[0].average[i].D), (REF_RA2 - catalog[0].average[i].R));
-    // if (radius < 0.0001) {
-    //   fprintf (stderr, "found it\n");
-    // }
-
     // do any of the measures for this object match group A?
     m = catalog[0].average[i].measureOffset;
@@ -132,5 +92,4 @@
     for (j = 0; !foundB && (j < catalog[0].average[i].Nmeasure); j++, m++) {
           
-
       if (MeasMatchesPhotcode(&catalog[0].measure[m], photcodesGroupB, NphotcodesGroupB)) {
 	foundB = TRUE;
@@ -138,4 +97,5 @@
     }
 
+    // object found in both - mark as slow moving
     if (foundA && foundB) {
       slowMoving[i] = TRUE;
@@ -144,102 +104,30 @@
     }
 
-    // additional constraints:
-    // * group A : require 
-
-    // 2MASS detections:
+    // Apply additional constraints:
     if (foundA && !foundB) {
-      // average-based tests:
-         
-
-      valid = TRUE;
-      valid &= ((catalog[0].average[i].flags & 0x02000000) == 0);
-      valid &= ((catalog[0].average[i].flags & 0x08000000)  > 0);
-      valid &= ((catalog[0].secfilt[i*Nsecfilt + yNsec].M < 1.0)||(isnan(catalog[0].secfilt[i*Nsecfilt + yNsec].M)));
-      valid &= (((catalog[0].secfilt[i*Nsecfilt + zNsec].M < 1.0))||(isnan(catalog[0].secfilt[i*Nsecfilt + zNsec].M)));
-      // XXX color restrictions are applied in the pair-wise matching below
-      
-      // measure-based tests:
-      /*      m = catalog[0].average[i].measureOffset;
-      for (j = 0; valid && (j < catalog[0].average[i].Nmeasure); j++, m++) {
-	if (catalog[0].measure[m].photcode == USNO_R) {
-	  valid &= ((catalog[0].measure[m].M > 20.0) || isnan(catalog[0].measure[m].M));
-	}
-	if (catalog[0].measure[m].photcode == USNO_N) {
-	  valid &= ((catalog[0].measure[m].M > 18.0) || isnan(catalog[0].measure[m].M));
-	}
-	}*/
-
-      // ((objflags & 524288) == 524288) && 
-      // ((objflags & 262144) == 0) && 
-      // (z<1.0) && 
-      // (y<1.0) && 
-      // ((yp[$i]-J)>1.25) && ((yp[$i]-J)<5.0) && 
-      // ((USNO_RED<1.0)||(USNO_RED>20.0)) && 
-      // ((USNO_N>18.0)||(USNO_N<1.0))
-
-      if (valid) {
-	groupA[i] = TRUE;
-	NgroupA ++;
-	continue;
-      } else {
-	NgroupAbad ++;
-	// fprintf (stderr, "skip "OFF_T_FMT" (group A)\n",  i);
-      }
-    }
-
-    // PS1 detections:
-    if (foundB && !foundA) {
-
-      // average-based tests:
-      valid = TRUE;
-      valid &= ((catalog[0].average[i].flags & 0x01000000) == 0);
-
-      valid &= ((catalog[0].average[i].flags & 0x04000000)  > 0);
-
-      valid &= ((catalog[0].secfilt[i*Nsecfilt + jNsec].M < 1.0)||(isnan(catalog[0].secfilt[i*Nsecfilt + jNsec].M)));
-      valid &= ((catalog[0].secfilt[i*Nsecfilt + yNsec].Nused > 1)||(catalog[0].secfilt[i*Nsecfilt + zNsec].Nused > 1));
-      valid &= ((catalog[0].secfilt[i*Nsecfilt + yNsec].dM < 0.2)||(catalog[0].secfilt[i*Nsecfilt + zNsec].dM < 0.2));
-
-      /*if ((catalog[0].secfilt[i*Nsecfilt + zNsec].M < 1.0) || (catalog[0].secfilt[i*Nsecfilt + zNsec].Nused == 1)) {
-	valid &= TRUE;
-      } else {
-	valid &= ((catalog[0].secfilt[i*Nsecfilt + zNsec].M - catalog[0].secfilt[i*Nsecfilt + yNsec].M) > 0.2);
-	}*/
-
-      // measure-based tests:
-      /*m = catalog[0].average[i].measureOffset;
-      for (j = 0; valid && (j < catalog[0].average[i].Nmeasure); j++, m++) {
-	if (catalog[0].measure[m].photcode == USNO_R) {
-	  valid &= ((catalog[0].measure[m].M > 20.0) || isnan(catalog[0].measure[m].M));
-	}
-	if (catalog[0].measure[m].photcode == USNO_N) {
-	  valid &= ((catalog[0].measure[m].M > 18.5) || isnan(catalog[0].measure[m].M));
-	}
-	}*/
-
-      // (abs(glat)>15.0) && 
-      // ((objflags & 65536) == 0) && 
-      // ((objflags & 131072) == 131072) &&
-      // (J<1.0) && 
-      // (y:nphot>1) && 
-      // (y:err<0.2) && 
-      // ((USNO_RED>20.0)||(USNO_RED<1.0)) && 
-      // ((USNO_N>18.5)||(USNO_N<1.0)) && 
-      // ((z<1.0)||(z:nphot == 1)||((z:nphot>1)&&((z-y)>0.2)))
-
-      if (valid) {
-	groupB[i] = TRUE;
-	NgroupB ++;
-	continue;
-      } else {
-	NgroupBbad ++;
-	// fprintf (stderr, "skip "OFF_T_FMT" (group B)\n",  i);
-      }
-    }
-
-    // this object does not have a detection from either groupA or groupB -- skip as if slow
+        if (applyConstraintsA(catalog, i)) {
+            groupA[i] = TRUE;
+            NgroupA++;
+            continue;
+        } else {
+            NgroupAbad ++;
+            // fprintf (stderr, "skip "OFF_T_FMT" (group A)\n",  i);
+        }
+
+    } else if (foundB && !foundA) {
+
+        if (applyConstraintsB(catalog, i)) {
+            groupB[i] = TRUE;
+            NgroupB++;
+            continue;
+        } else {
+            NgroupBbad++;
+        }
+    }
+    // this object does not have a detection matching the contraints from either gorupA or groupB -- skip as if slow
     slowMoving[i] = TRUE;
     Ninvalid ++;
   }
+
   fprintf (stderr, OFF_T_FMT" slow, "OFF_T_FMT" invalid, ("OFF_T_FMT" group A, "OFF_T_FMT" group B), "OFF_T_FMT" total objects; "OFF_T_FMT" in group A, "OFF_T_FMT" in group B\n",  Nslow,  Ninvalid, NgroupAbad, NgroupBbad, catalog[0].Naverage,  NgroupA,  NgroupB);
     
@@ -284,10 +172,4 @@
     ni = N1[i];
     nj = N1[j];
-    // if (ni == 131030) {
-    //   fprintf (stderr, "got 2mass\n");
-    // }
-    // if (nj == 53581) {
-    //   fprintf (stderr, "got ps1\n");
-    // }
 
     if (slowMoving[ni]) NEXT_I;
@@ -319,10 +201,4 @@
       dR = dX*dX + dY*dY;
       if (dR > RADIUS2) continue;
-
-      // y_groupA - J_groupB 
-
-      /*      yJ = catalog[0].secfilt[nj*Nsecfilt + yNsec].M - catalog[0].secfilt[ni*Nsecfilt + jNsec].M;
-      if (yJ < 1.25) continue;
-      if (yJ > 5.0) continue;*/
 
       /*** a match is found (just print it for the moment) ***/
@@ -330,5 +206,4 @@
       Nepoch=2;
       FIT_MODE = FIT_PM_ONLY;
-/*nv=(int *)malloc(Nepoch*sizeof(int));*/
       nv[0]=ni; /*THESE SHOULD BE CHANGED FOR MULTIPLE EPOCHS AS SHOULD nv*/
       nv[1]=nj;
@@ -363,21 +238,4 @@
 	REALLOCATE(catalog1.secfilt, SecFilt, NAVERAGE*Nsecfilt);
       }
-      // for the moment, just write the matches to stdout:
-      //float pmx = -dX; // proper-motion displacement in ra  direction (B - A) [arcsec]
-      //float pmy = -dY; // proper-motion displacement in dec direction (B - A) [arcsec]
-      /*           fprintf (stdout, "%11.7f %11.7f  %11.7f %11.7f : %7.2f %7.2f  %7.2f: %7.3f %6.3f  %7.3f %6.3f  %7.3f %6.3f  %7.3f %6.3f  %7.3f %6.3f\n", 
-	       catalog[0].average[ni].R, catalog[0].average[ni].D,
-	       catalog[0].average[nj].R, catalog[0].average[nj].D,
-	       dX, dY, sqrt(dR),
-	       catalog[0].secfilt[nj*Nsecfilt + zNsec].M,
-	       catalog[0].secfilt[nj*Nsecfilt + zNsec].dM,
-	       catalog[0].secfilt[nj*Nsecfilt + yNsec].M, 
-	       catalog[0].secfilt[nj*Nsecfilt + yNsec].dM,
-	       catalog[0].secfilt[ni*Nsecfilt + jNsec].M,
-	       catalog[0].secfilt[ni*Nsecfilt + jNsec].dM,
-	       catalog[0].secfilt[ni*Nsecfilt + hNsec].M,
-	       catalog[0].secfilt[ni*Nsecfilt + hNsec].dM,
-	       catalog[0].secfilt[ni*Nsecfilt + kNsec].M,
-	       catalog[0].secfilt[ni*Nsecfilt + kNsec].dM);*/
     }
     i++;
Index: /trunk/Ohana/src/relastro/src/high_speed_utils.c
===================================================================
--- /trunk/Ohana/src/relastro/src/high_speed_utils.c	(revision 31635)
+++ /trunk/Ohana/src/relastro/src/high_speed_utils.c	(revision 31635)
@@ -0,0 +1,139 @@
+# include "relastro.h"
+# include "kapa.h"
+
+                          //   !ID_OBJ_EXT_ALT          ID_OBJ_GOOD_ALT         
+#define DEFAULT_WHERE_A "((flags & 0x02000000 == 0) && (flags & 0x08000000))"
+
+                          //    !ID_OBJ_EXT             ID_OBJ_GOOD
+#define DEFAULT_WHERE_B  "((flags & 0x01000000) == 0) && ((flags & 0x04000000) && ((y:nphot > 1) || (z:nphot > 1)) &&((y:err < 0.2) || (z:err < 0.2)))"
+
+
+extern char **isolate_elements(int, char **, int *);
+
+int print_error();
+
+static dbField *fieldsA = NULL;
+static int NfieldsA = 0;
+static dbStack *stackA = NULL;
+static int NstackA = 0;
+static dbField *fieldsB = NULL;
+static int NfieldsB = 0;
+static dbStack *stackB = NULL;
+static int NstackB = 0;
+static dbValue *valuesA;
+// static int NvaluesA;
+static dbValue *valuesB;
+// static int NvaluesB;
+
+void setupAreaSelection(SkyRegion *region) {
+    SELECTION.name = NULL;
+    SELECTION.list = NULL;
+    SELECTION.useDisplay = FALSE;
+    SELECTION.useSkyregion = TRUE;
+    set_skyregion(region->Rmin, region->Rmax, region->Dmin, region->Dmax);
+}
+
+
+// split string into an array of words using space as delimiter by a space.
+static char ** splitToWords(char *string, int *n) {
+    char **words;
+    int NwordsAllocated = 20;
+    ALLOCATE(words, char *, NwordsAllocated);
+
+    char *copy_of_str = strdup(string);
+
+    char *saveptr = NULL;
+    char *p = strtok_r(copy_of_str, " ", &saveptr);
+    *n = 0;
+    while (p) {
+        if (*n == NwordsAllocated) {
+            NwordsAllocated += 20;
+            REALLOCATE (words, char *, NwordsAllocated);
+        }
+        words[(*n)++] = p;
+        p = strtok_r(NULL, " ", &saveptr);
+    }
+
+    return words;
+}
+
+// Create the data strucutres required to apply avextract like cuts
+int setupConstraints(char *whereString, dbField **pFields, int *pNfields, dbStack **pStack, int *pNstack) {
+
+    // split the string into words
+    int nWords;
+    char **words = splitToWords(whereString, &nWords);
+    if (!nWords) {
+        fprintf(stderr, "unable to parse constraint\n");
+        return FALSE;
+    }
+
+    // parse it into elements of the where condition
+    char **cstack = NULL;
+    int Ncstack;
+    cstack = isolate_elements(nWords, words, &Ncstack);
+    free(words);
+
+    *pStack = dbRPN(Ncstack, cstack, pNstack);
+    if (Ncstack && !*pNstack) {
+        print_error();
+        return FALSE;
+    }
+    dbAstroRegionLimits(pStack, pNstack, &SELECTION, DVO_TABLE_AVERAGE);
+
+    *pFields = NULL;
+    *pNfields = 0;
+
+    return dbCheckStack(*pStack, *pNstack, DVO_TABLE_AVERAGE, pFields, pNfields);
+}
+
+int initializeConstraints() {
+  // if constaints haven't been set by the user use 2mass
+    if (!WHERE_A[0]) {
+        strcpy(WHERE_A, DEFAULT_WHERE_A);
+    }
+    if (!WHERE_B[0]) {
+        strcpy(WHERE_B, DEFAULT_WHERE_B);
+    }
+
+    if (! setupConstraints(WHERE_A, &fieldsA, &NfieldsA, &stackA, &NstackA)) {
+        print_error();
+        fprintf(stderr, "failed to set up constratints for group A: %s\n", WHERE_A);
+        exit(1);
+    }
+    ALLOCATE(valuesA, dbValue, NfieldsA);
+    if (! setupConstraints(WHERE_B, &fieldsB, &NfieldsB, &stackB, &NstackB)) {
+        print_error();
+        fprintf(stderr, "failed to set up constratints for group A: %s\n", WHERE_A);
+        exit(1);
+    }
+    ALLOCATE(valuesB, dbValue, NfieldsB);
+    return TRUE;
+}
+
+// XXX: TODO: We should be able to combine fieldsA and fieldsB and do a single extract
+
+int applyConstraintsA(Catalog *catalog, off_t i) {
+    off_t m = catalog[0].average[i].measureOffset;
+    off_t n;
+    int Nsecfilt = GetPhotcodeNsecfilt();
+    
+    dbExtractAveragesInit();
+    for (n = 0; n < NfieldsA; n++) {
+        valuesA[n] = dbExtractAverages (&catalog[0].average[i], &catalog[0].secfilt[i*Nsecfilt], &catalog[0].measure[m], &fieldsA[n]);
+    }
+    return dbBooleanCond(stackA, NstackA, valuesA);
+}
+
+int applyConstraintsB(Catalog *catalog, off_t i) {
+    off_t m = catalog[0].average[i].measureOffset;
+    int Nsecfilt = GetPhotcodeNsecfilt();
+    
+    dbExtractAveragesInit();
+
+    off_t n;
+    for (n = 0; n < NfieldsB; n++) {
+        valuesB[n] = dbExtractAverages (&catalog[0].average[i], &catalog[0].secfilt[i*Nsecfilt], &catalog[0].measure[m], &fieldsB[n]);
+    }
+    return dbBooleanCond(stackB, NstackB, valuesB);
+}
Index: /trunk/Ohana/src/relastro/src/initialize.c
===================================================================
--- /trunk/Ohana/src/relastro/src/initialize.c	(revision 31634)
+++ /trunk/Ohana/src/relastro/src/initialize.c	(revision 31635)
@@ -63,8 +63,8 @@
 
     /* parse the comma-separated list of photcodesGroupA */
+    fprintf (stderr, "PHOTCODE_A_LIST: %s\n", PHOTCODE_A_LIST);
     list = PHOTCODE_A_LIST;
     while ((codename = strtok_r (list, ",", &ptr)) != NULL) {
       list = NULL; // pass NULL on successive strtok_r calls
-      fprintf (stderr, "PHOTCODE_A_LIST: %s\n", PHOTCODE_A_LIST);
       fprintf (stderr, "codename: %s\n", codename);
       if ((photcodesGroupA[NphotcodesGroupA] = GetPhotcodebyName (codename)) == NULL) {
@@ -83,9 +83,9 @@
     ALLOCATE (photcodesGroupB, PhotCode *, NPHOTCODES);
 
+    fprintf (stderr, "PHOTCODE_B_LIST: %s\n", PHOTCODE_B_LIST);
     /* parse the comma-separated list of photcodesGroupB */
     list = PHOTCODE_B_LIST;
     while ((codename = strtok_r (list, ",", &ptr)) != NULL) {
       list = NULL; // pass NULL on successive strtok_r calls
-      fprintf (stderr, "PHOTCODE_B_LIST: %s\n", PHOTCODE_B_LIST);
       fprintf (stderr, "codename: %s\n", codename);
       if ((photcodesGroupB[NphotcodesGroupB] = GetPhotcodebyName (codename)) == NULL) {
Index: /trunk/Ohana/src/relastro/src/relastroVisual.c
===================================================================
--- /trunk/Ohana/src/relastro/src/relastroVisual.c	(revision 31634)
+++ /trunk/Ohana/src/relastro/src/relastroVisual.c	(revision 31635)
@@ -3,5 +3,4 @@
  */
 
-#include "kapa.h"
 #include "relastro.h"
 
Index: /trunk/Ohana/src/uniphot/include/uniphot.h
===================================================================
--- /trunk/Ohana/src/uniphot/include/uniphot.h	(revision 31634)
+++ /trunk/Ohana/src/uniphot/include/uniphot.h	(revision 31635)
@@ -83,14 +83,14 @@
   int style, ptype, ltype, etype, color;
   double lweight, size;
-} Graphdata;
+} UPGraphdata;
 
 /***** prototypes ****/
 void          ConfigInit          PROTO((int *argc, char **argv));
-void          DonePlotting        PROTO((Graphdata *graphmode, int N));
-void          JpegPlot            PROTO((Graphdata *graphmode, int N, char *filename));
-void          PSPlot              PROTO((Graphdata *graphmode, int N, char *filename));
+void          DonePlotting        PROTO((UPGraphdata *graphmode, int N));
+void          JpegPlot            PROTO((UPGraphdata *graphmode, int N, char *filename));
+void          PSPlot              PROTO((UPGraphdata *graphmode, int N, char *filename));
 void          PlotLabel           PROTO((char *string, int N));
 void          PlotVector          PROTO((int Npts, double *vect, int mode, int N));
-void          PrepPlotting        PROTO((int Npts, Graphdata *graphmode, int N));
+void          PrepPlotting        PROTO((int Npts, UPGraphdata *graphmode, int N));
 void          XDead               PROTO((void));
 int           args_uniphot        PROTO((int argc, char **argv));
Index: /trunk/Ohana/src/uniphot/src/plotstuff.c
===================================================================
--- /trunk/Ohana/src/uniphot/src/plotstuff.c	(revision 31634)
+++ /trunk/Ohana/src/uniphot/src/plotstuff.c	(revision 31635)
@@ -27,5 +27,5 @@
 }
 
-void DonePlotting (Graphdata *graphmode, int N) {
+void DonePlotting (UPGraphdata *graphmode, int N) {
 
   if (Xgraph[N] == 0) return;
@@ -34,5 +34,5 @@
 }
 
-void PrepPlotting (int Npts, Graphdata *graphmode, int N) {
+void PrepPlotting (int Npts, UPGraphdata *graphmode, int N) {
 
   active = N;
@@ -75,5 +75,5 @@
 }
 
-void JpegPlot (Graphdata *graphmode, int N, char *filename) {
+void JpegPlot (UPGraphdata *graphmode, int N, char *filename) {
 
   if (Xgraph[N] == 0) return;
@@ -83,5 +83,5 @@
 }
 
-void PSPlot (Graphdata *graphmode, int N, char *filename) {
+void PSPlot (UPGraphdata *graphmode, int N, char *filename) {
 
   if (Xgraph[N] == 0) return;
@@ -97,6 +97,6 @@
    int style, ptype, ltype, etype, color;
    double lweight, size;
-   } Graphdata;
-   Graphdata graphdata;
+   } UPGraphdata;
+   UPGraphdata graphdata;
    
    graphdata.xmin = -200;
