Index: /trunk/Ohana/src/addstar/Makefile
===================================================================
--- /trunk/Ohana/src/addstar/Makefile	(revision 20935)
+++ /trunk/Ohana/src/addstar/Makefile	(revision 20936)
@@ -25,4 +25,5 @@
 load2mass   : $(BIN)/load2mass.$(ARCH)
 gztest      : $(BIN)/gztest.$(ARCH)
+mkcmf       : $(BIN)/mkcmf.$(ARCH)
 
 all: addstar addstarc addstard addstart sedstar load2mass skycells
@@ -222,4 +223,7 @@
 $(SRC)/SetSignals.$(ARCH).o
 
+MKCMF = \
+$(SRC)/mkcmf.$(ARCH).o
+
 SKYCELLS = \
 $(SRC)/skycells.$(ARCH).o \
@@ -230,21 +234,23 @@
 $(SRC)/sky_tessalation.$(ARCH).o
 
-$(ADDSTARC) : $(INC)/addstar.h
-$(ADDSTARD) : $(INC)/addstar.h
-$(ADDSTART) : $(INC)/addstar.h
-$(ADDSTAR)  : $(INC)/addstar.h
-$(SKYCELLS) : $(INC)/addstar.h
+$(ADDSTARC)   : $(INC)/addstar.h
+$(ADDSTARD)   : $(INC)/addstar.h
+$(ADDSTART)   : $(INC)/addstar.h
+$(ADDSTAR)    : $(INC)/addstar.h
+$(SKYCELLS)   : $(INC)/addstar.h
 $(LOAD-2MASS) : $(INC)/addstar.h $(INC)/2mass.h
-
-$(BIN)/addstar.$(ARCH) : $(ADDSTAR)
-$(BIN)/addstard.$(ARCH) : $(ADDSTARD)
-$(BIN)/addstart.$(ARCH) : $(ADDSTART)
-$(BIN)/addstarc.$(ARCH) : $(ADDSTARC)
+$(MKCMF)      : $(INC)/mkcmf.h
+
+$(BIN)/addstar.$(ARCH) 	   : $(ADDSTAR)
+$(BIN)/addstard.$(ARCH)	   : $(ADDSTARD)
+$(BIN)/addstart.$(ARCH)	   : $(ADDSTART)
+$(BIN)/addstarc.$(ARCH)	   : $(ADDSTARC)
 $(BIN)/mkacc-2mass.$(ARCH) : $(MKACC-2MASS)
-$(BIN)/sedstar.$(ARCH)   : $(SEDSTAR)
-$(BIN)/load2mass.$(ARCH) : $(LOAD-2MASS)
-$(BIN)/skycells.$(ARCH) : $(SKYCELLS)
-
-INSTALL = addstar addstarc addstard addstart sedstar load2mass skycells
+$(BIN)/sedstar.$(ARCH)     : $(SEDSTAR)
+$(BIN)/load2mass.$(ARCH)   : $(LOAD-2MASS)
+$(BIN)/skycells.$(ARCH)    : $(SKYCELLS)
+$(BIN)/mkcmf.$(ARCH)       : $(MKCMF)
+
+INSTALL = addstar addstarc addstard addstart sedstar load2mass skycells mkcmf
 
 # dependancy rules for binary code #########################
Index: /trunk/Ohana/src/addstar/include/addstar.h
===================================================================
--- /trunk/Ohana/src/addstar/include/addstar.h	(revision 20935)
+++ /trunk/Ohana/src/addstar/include/addstar.h	(revision 20936)
@@ -87,4 +87,6 @@
 char   STKeyword[64];
 char   ExtnameKeyword[64];
+char   ImageIDKeyword[64];
+char   SourceIDKeyword[64];
 
 /* these globals modify the behavior of gstars (KEEP) */
Index: /trunk/Ohana/src/addstar/include/mkcmf.h
===================================================================
--- /trunk/Ohana/src/addstar/include/mkcmf.h	(revision 20936)
+++ /trunk/Ohana/src/addstar/include/mkcmf.h	(revision 20936)
@@ -0,0 +1,17 @@
+# include <ohana.h>
+# include <dvo.h>
+# include <signal.h>
+# include <sys/time.h>
+# include <time.h>
+# include <zlib.h>
+
+/* solaris requires both of these instead of ip.h:
+   # include <sys/socket.h>
+   # include <netinet/in.h>
+*/
+
+/* linux is happy with this, not solaris */
+# include <netinet/ip.h>
+# include <netdb.h>
+# include <arpa/inet.h>
+# include <glob.h>
Index: /trunk/Ohana/src/addstar/src/ConfigInit.c
===================================================================
--- /trunk/Ohana/src/addstar/src/ConfigInit.c	(revision 20935)
+++ /trunk/Ohana/src/addstar/src/ConfigInit.c	(revision 20936)
@@ -67,4 +67,7 @@
   ScanConfig (config, "OBSERVATORY-LONGITUDE",  "%lf", 0, &Longitude);
   ScanConfig (config, "SUBPIX_DATAFILE",        "%s",  0, SubpixDatafile);
+
+  ScanConfig (config, "IMAGE-ID-KEYWORD",       "%s",  0, ImageIDKeyword);
+  ScanConfig (config, "SOURCE-ID-KEYWORD",      "%s",  0, SourceIDKeyword);
 
   if (!ScanConfig (config, "EXTNAME-KEYWORD",        "%s",  0, ExtnameKeyword)) {
Index: /trunk/Ohana/src/addstar/src/ReadImageHeader.c
===================================================================
--- /trunk/Ohana/src/addstar/src/ReadImageHeader.c	(revision 20935)
+++ /trunk/Ohana/src/addstar/src/ReadImageHeader.c	(revision 20936)
@@ -5,5 +5,5 @@
 int ReadImageHeader (Header *header, Image *image, int photcode) {
 
-  int Nastro, ccdnum, hour, min, Nx, Ny, haveNx, haveNy;
+  int Nastro, ccdnum, hour, min, Nx, Ny, haveNx, haveNy, sourceID;
   double tmp, sec, Cerror, ZeroPt, FWHM_X, FWHM_Y;
   char *c, photname[64], line[80];
@@ -178,4 +178,17 @@
   }
 
+  if (!gfits_scan (header, ImageIDKeyword, "%d", 1, &image[0].externID)) {
+    image[0].externID = 0;
+  }
+  if (!gfits_scan (header, SourceIDKeyword, "%d", 1, &sourceID)) {
+    image[0].sourceID = 0;
+  } else {
+    if (sourceID > 0xffff) {
+      fprintf (stderr, "image source ID is surprisingly large: %d, skipping\n", sourceID); 
+      return (FALSE);
+    }
+    image[0].sourceID = sourceID;
+  }
+
   gfits_scan (header, "ZERO_PT", "%lf", 1, &ZeroPt);
   if (ZeroPt != GetZeroPoint()) {
Index: /trunk/Ohana/src/addstar/src/find_matches.c
===================================================================
--- /trunk/Ohana/src/addstar/src/find_matches.c	(revision 20935)
+++ /trunk/Ohana/src/addstar/src/find_matches.c	(revision 20936)
@@ -193,5 +193,5 @@
 
       catalog[0].measure[Nmeas].detID     = stars[N].detID;
-      catalog[0].measure[Nmeas].imageID   = options.imageID;
+      catalog[0].measure[Nmeas].imageID   = stars[N].imageID;
 
       catalog[0].measure[Nmeas].dXccd     = stars[N].dX;
Index: /trunk/Ohana/src/addstar/src/find_matches_closest.c
===================================================================
--- /trunk/Ohana/src/addstar/src/find_matches_closest.c	(revision 20935)
+++ /trunk/Ohana/src/addstar/src/find_matches_closest.c	(revision 20936)
@@ -215,5 +215,5 @@
 
     catalog[0].measure[Nmeas].detID     = stars[N].detID;
-    catalog[0].measure[Nmeas].imageID   = options.imageID;
+    catalog[0].measure[Nmeas].imageID   = stars[N].imageID;
 
     catalog[0].measure[Nmeas].dXccd     = stars[N].dX;
@@ -327,5 +327,5 @@
 
     catalog[0].measure[Nmeas].detID     = stars[N].detID;
-    catalog[0].measure[Nmeas].imageID   = options.imageID;
+    catalog[0].measure[Nmeas].imageID   = stars[N].imageID;
 
     catalog[0].measure[Nmeas].dXccd     = stars[N].dX;
Index: /trunk/Ohana/src/addstar/src/mkcmf.c
===================================================================
--- /trunk/Ohana/src/addstar/src/mkcmf.c	(revision 20936)
+++ /trunk/Ohana/src/addstar/src/mkcmf.c	(revision 20936)
@@ -0,0 +1,257 @@
+# include "mkcmf.h"
+void gauss_init (int Nbin);
+double rnd_gauss (double mean, double sigma);
+
+# define SKY 100.0
+# define DSKY 2.0
+# define PSFCHI 1.3
+# define CRN 3.0
+# define EXTN 4.0
+# define FX 1.5
+# define FY 1.0
+# define DF 10.0
+# define PSFQUAL 0.98
+# define FLAGS 0x1101
+
+int main (int argc, char **argv) {
+
+  // generate a simple, fake cmf file
+  // load a text table with X,Y,Mag (instrumental?)
+
+  int i, N, Nstars, NSTARS;
+  double *X, *Y, *M;
+  double Xmax, Ymax;
+  float flux, fSN;
+
+  FILE *f, *fits;
+  Header header, theader;
+  Matrix matrix;
+  FTable ftable;
+  Coords coords;
+
+  PS1_DEV_1 *stars;
+
+  static char *date = "2001-01-01";
+  if ((N = get_argument (argc, argv, "-date"))) {
+    remove_argument (N, &argc, argv);
+    date = strcreate (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  static char *time = "00:00:00";
+  if ((N = get_argument (argc, argv, "-time"))) {
+    remove_argument (N, &argc, argv);
+    time = strcreate (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  double RA = 10.0;
+  double DEC = 20.0;
+  if ((N = get_argument (argc, argv, "-radec"))) {
+    remove_argument (N, &argc, argv);
+    RA = atof (argv[N]);
+    remove_argument (N, &argc, argv);
+    DEC = atof (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  if (argc != 3) {
+    fprintf (stderr, "USAGE mkcmf (input) (output) [-date date] [-time time] [-radec ra dec]\n");
+    exit (2);
+  }
+
+  f = fopen (argv[1], "r");
+  if (f == NULL) {
+    fprintf (stderr, "unable to open input file %s\n", argv[1]);
+    exit (1);
+  }
+    
+  Nstars = 0;
+  NSTARS = 100;
+  ALLOCATE (X, double, NSTARS);
+  ALLOCATE (Y, double, NSTARS);
+  ALLOCATE (M, double, NSTARS);
+
+  Xmax = Ymax = 0;
+
+  while (fscanf (f, "%lf %lf %lf", &X[Nstars], &Y[Nstars], &M[Nstars]) != EOF) {
+    if (Nstars == NSTARS - 1) {
+      NSTARS += 100;
+      REALLOCATE (X, double, NSTARS);
+      REALLOCATE (Y, double, NSTARS);
+      REALLOCATE (M, double, NSTARS);
+    }
+    Nstars ++;
+  }
+
+  // XXX add gaussian-distributed noise based on counts
+  ALLOCATE (stars, PS1_DEV_1, Nstars);
+  gauss_init (2048);
+  for (i = 0; i < Nstars; i++) {
+    stars[i].detID = i;
+
+    flux = pow (10.0, -0.4*M[i]);
+    fSN = 1.0 / sqrt(flux);
+
+    stars[i].X = X[i] + FX * fSN * rnd_gauss(0.0, 1.0);
+    stars[i].Y = Y[i] + FY * fSN * rnd_gauss(0.0, 1.0);
+    stars[i].M = M[i] + fSN*rnd_gauss(0.0, 1.0);
+
+    Xmax  = MAX(Xmax, X[i]);
+    Ymax  = MAX(Ymax, Y[i]);
+
+    stars[i].dX = FX * fSN;
+    stars[i].dY = FY * fSN;
+    stars[i].dM = fSN;
+
+    stars[i].Mpeak     = M[i] + 1.0;
+    stars[i].sky       = SKY;
+    stars[i].dSky      = DSKY;
+    stars[i].psfChisq  = PSFCHI;
+    stars[i].crNsigma  = CRN;
+    stars[i].extNsigma = EXTN;
+    stars[i].fx        = FX;
+    stars[i].fy        = FY;
+    stars[i].df        = DF;
+    stars[i].psfQual   = PSFQUAL;
+    stars[i].nFrames   = 1;
+    stars[i].flags     = FLAGS;
+  }
+
+  // create primary header
+  gfits_init_header (&header);    
+  header.extend = TRUE;
+  gfits_create_header (&header);
+  gfits_create_matrix (&header, &matrix);
+  gfits_print (&header, "NEXTEND", "%d", 1, 1);
+
+  // XXX add minimum needed header fields 
+  gfits_print (&header, "IMNAXIS1", "%d", 1, (int)(Xmax + 50));
+  gfits_print (&header, "IMNAXIS2", "%d", 1, (int)(Ymax + 50));
+
+  gfits_modify (&header, "NSTARS",   "%d", 1, Nstars);
+  gfits_modify (&header, "PHOTCODE", "%s", 1, "SIMTEST.r.Chip");
+  gfits_modify (&header, "DATE-OBS", "%s", 1, date);
+  gfits_modify (&header, "UTC-OBS",  "%s", 1, time);
+  gfits_modify (&header, "ZERO_PT", "%lf", 1, 25.0);
+  gfits_modify (&header, "EXPTIME", "%lf", 1, 1.0);
+  gfits_modify (&header, "AIRMASS", "%lf", 1, 1.0);
+  gfits_modify (&header, "NASTRO",   "%d", 1, 10); 
+
+  gfits_modify (&header, "IMAGEID",  "%d", 1, (int)(1000*drand48())); 
+  gfits_modify (&header, "SOURCEID", "%d", 1, (int)(100*drand48())); 
+
+  /* bore site center guess */
+  strcpy (coords.ctype, "DEC--TAN");
+  coords.crval1 = RA;
+  coords.crval2 = DEC;
+  coords.crpix1 = 0.0;
+  coords.crpix2 = 0.0;
+  
+  coords.cdelt1 = 0.25/3600.0;
+  coords.cdelt2 = 0.25/3600.0;
+
+  coords.pc1_1  = 1;
+  coords.pc2_2  = 1;
+  coords.pc1_2  = 0;
+  coords.pc2_1  = 0;
+  coords.Npolyterms = 1;
+
+  PutCoords (&coords, &header);
+  gfits_modify (&header, "EXTNAME",   "%s", 1, "Chip.hdr");
+
+  ftable.header = &theader;
+  gfits_table_set_PS1_DEV_1 (&ftable, stars, Nstars);
+  gfits_modify (&theader, "EXTNAME",   "%s", 1, "Chip.psf");
+  gfits_modify (&theader, "EXTTYPE",   "%s", 1, "PS1_DEV_1");
+  gfits_modify (&theader, "EXTHEAD",   "%s", 1, "Chip.hdr");
+
+  fits = fopen (argv[2], "w");
+  if (fits == NULL) {
+    fprintf (stderr, "ERROR: can't open output file %s\n", argv[2]);
+    exit (1);
+  }
+
+  gfits_fwrite_header  (fits, &header);
+  gfits_fwrite_matrix  (fits, &matrix);
+  gfits_fwrite_Theader (fits, &theader);
+  gfits_fwrite_table   (fits, &ftable);
+  fclose (fits);
+
+  exit (0);
+}
+
+
+static int Ngaussint = 0;
+static double *gaussint;
+
+extern double drand48();
+
+double gaussian (double x, double mean, double sigma) {
+
+  double f;
+
+  f = exp (-0.5 * SQ(x - mean) / SQ(sigma)) / sqrt(2 * M_PI * SQ(sigma));
+
+  return (f);
+
+}
+
+/* integrate a gaussian from -5 sigma to +5 sigma */
+void gauss_init (int Nbin) {
+ 
+  int i;
+  long A, B;
+  double val, x, dx, dx1, dx2, dx3, df;
+  double mean, sigma;
+ 
+  /* no need to generate this if it already exists */
+  if (Ngaussint == Nbin) return;
+
+  A = time(NULL);
+  for (B = 0; A == time(NULL); B++);
+  srand48(B);
+ 
+  Ngaussint = Nbin;
+  ALLOCATE (gaussint, double, Ngaussint + 1);
+
+  val = 0;
+  dx = 1.0 / Ngaussint;
+  dx1 = dx / 3.0;
+  dx2 = 2.0*dx/3.0;
+  dx3 = dx;
+  mean = 0.0;
+  sigma = 1.0;
+ 
+  for (i = 0, x = -7.0; (i < Ngaussint) && (x < 7.0); x += dx)  {
+    df = (3.0*gaussian(x    , mean, sigma) + 
+          9.0*gaussian(x+dx1, mean, sigma) +
+          9.0*gaussian(x+dx2, mean, sigma) + 
+          3.0*gaussian(x+dx3, mean, sigma)) * (dx1/8.0);
+    val += df;
+    if (val > (i + 0.5) / (double) Ngaussint) {
+      gaussint[i] = x + dx / 2.0;
+      i++;
+    }
+  }
+}
+
+double rnd_gauss (double mean, double sigma) {
+ 
+  int i;
+  double y;
+ 
+  y = drand48();
+  i = Ngaussint*y;
+  y = gaussint[i]*sigma + mean;
+ 
+  return (y);
+ 
+}
+ 
+double int_gauss (int i) {
+  double y;
+  y = gaussint[i];
+  return (y);
+}
+ 
Index: /trunk/Ohana/src/addstar/test/.cvsignore
===================================================================
--- /trunk/Ohana/src/addstar/test/.cvsignore	(revision 20936)
+++ /trunk/Ohana/src/addstar/test/.cvsignore	(revision 20936)
@@ -0,0 +1,5 @@
+test.1.cmf
+test.2.cmf
+test.in.txt
+catdir.test
+.dvo
Index: /trunk/Ohana/src/addstar/test/addstar.sh
===================================================================
--- /trunk/Ohana/src/addstar/test/addstar.sh	(revision 20936)
+++ /trunk/Ohana/src/addstar/test/addstar.sh	(revision 20936)
@@ -0,0 +1,58 @@
+
+macro test.measure.basic
+  
+  $PASS = 1
+
+  catdir catdir.test
+  skyregion 9 11 19 21
+
+  mextract ra, dec, xccd, yccd, mag:inst, mag, mag:err, time, photcode
+
+  if (ra[] != 242) 
+    $PASS = 0
+    echo "found the wrong number of measurements in db"
+  end
+
+  avextract ra, dec
+
+  if (ra[] != 242) 
+    $PASS = 0
+    echo "found the wrong number of stars in db"
+  end
+
+  ### XXX write down some tests of things we know about the input data values
+  ### XXX probably need to add options to mkcmf to eliminate poisson error
+end
+
+# create a populated catdir with a couple of cmf files
+macro mkcatdir
+
+  exec rm -rf catdir.test
+
+  mkinput
+  exec mkcmf test.in.txt test.1.cmf -date 2008/1/1 -time 01:00:00 -radec 10.0 20.0
+  exec mkcmf test.in.txt test.2.cmf -date 2008/1/1 -time 02:00:00 -radec 10.0 20.0
+
+  exec addstar -D CATDIR catdir.test -D CAMERA simtest test.1.cmf
+  exec addstar -D CATDIR catdir.test -D CAMERA simtest test.2.cmf
+end
+
+# make a simple input file for mkcmf
+macro mkinput
+  exec rm -f test.in.txt
+
+  output test.in.txt
+  for i 10 1024 100
+    for j 10 1024 100
+      fprintf " %4d %4d  %6.2f" $i $j {-15.0 + 2.5*($i + $j)/1000.0}
+    end
+  end
+  output stdout
+end
+
+macro showinput
+   data test.in.txt 
+   read x 1 y 2 m 3
+   lim x y; clear; box; zplot -pt 7 x y m -10 -15
+end
+
Index: /trunk/Ohana/src/delstar/src/parse_time.c
===================================================================
--- /trunk/Ohana/src/delstar/src/parse_time.c	(revision 20935)
+++ /trunk/Ohana/src/delstar/src/parse_time.c	(revision 20936)
@@ -31,10 +31,10 @@
   gfits_scan (header, UTKeyword, "%s", 1, line);
   /* remove ':' characters */
-  for (c = strchr (line, 0x3a); c != (char *) NULL; c = strchr (line, 0x3a)) { *c = ' '; }
+  for (c = strchr (line, 0x3a); c != NULL; c = strchr (line, 0x3a)) { *c = ' '; }
   sscanf (line, "%d %d %d", &hour, &min, &sec);
 
   /* parse mode line */
   uppercase (DateMode);
-  for (Ny = 0, c = strchr (DateMode, 'Y'); c != (char ) NULL; c = strchr (c + 1, 'Y'), Ny++);
+  for (Ny = 0, c = strchr (DateMode, 'Y'); c != NULL; c = strchr (c + 1, 'Y'), Ny++);
   if ((Ny != 2) && (Ny != 4)) {
     Shutdown ("error in DATE-MODE format: %s", DateMode);
@@ -43,5 +43,5 @@
   pm = strchr (DateMode, 'M');
   pd = strchr (DateMode, 'D');
-  if ((py == (char *) NULL) || (pm == (char *) NULL) || (pd == (char *) NULL)) {
+  if ((py == NULL) || (pm == NULL) || (pd == NULL)) {
     Shutdown ("error in DATE-MODE format: %s", DateMode);
   }
@@ -65,8 +65,8 @@
   gfits_scan (header, DateKeyword, "%s",  1, line);
   /* remove possible separators: ':', '/' '.', '-' */
-  for (c = strchr (line, 0x3a); c != (char *) NULL; c = strchr (line, 0x3a)) { *c = ' '; }
-  for (c = strchr (line, 0x2f); c != (char *) NULL; c = strchr (line, 0x2f)) { *c = ' '; }
-  for (c = strchr (line, 0x2e); c != (char *) NULL; c = strchr (line, 0x2e)) { *c = ' '; }
-  for (c = strchr (line, 0x2d); c != (char *) NULL; c = strchr (line, 0x2d)) { *c = ' '; }
+  for (c = strchr (line, 0x3a); c != NULL; c = strchr (line, 0x3a)) { *c = ' '; }
+  for (c = strchr (line, 0x2f); c != NULL; c = strchr (line, 0x2f)) { *c = ' '; }
+  for (c = strchr (line, 0x2e); c != NULL; c = strchr (line, 0x2e)) { *c = ' '; }
+  for (c = strchr (line, 0x2d); c != NULL; c = strchr (line, 0x2d)) { *c = ' '; }
 
   Nf = 0;
Index: /trunk/Ohana/src/imregister/base/parse_time.c
===================================================================
--- /trunk/Ohana/src/imregister/base/parse_time.c	(revision 20935)
+++ /trunk/Ohana/src/imregister/base/parse_time.c	(revision 20936)
@@ -31,10 +31,10 @@
   warn_scan (header, UTKeyword, "%s", 1, line);
   /* remove ':' characters */
-  for (c = strchr (line, 0x3a); c != (char *) NULL; c = strchr (line, 0x3a)) { *c = ' '; }
+  for (c = strchr (line, 0x3a); c != NULL; c = strchr (line, 0x3a)) { *c = ' '; }
   sscanf (line, "%d %d %d", &hour, &min, &sec);
 
   /* parse mode line */
   uppercase (DateMode);
-  for (Ny = 0, c = strchr (DateMode, 'Y'); c != (char ) NULL; c = strchr (c + 1, 'Y'), Ny++);
+  for (Ny = 0, c = strchr (DateMode, 'Y'); c != NULL; c = strchr (c + 1, 'Y'), Ny++);
   if ((Ny != 2) && (Ny != 4)) {
     fprintf (stderr, "error in DATE-MODE format: %s\n", DateMode);
@@ -44,5 +44,5 @@
   pm = strchr (DateMode, 'M');
   pd = strchr (DateMode, 'D');
-  if ((py == (char *) NULL) || (pm == (char *) NULL) || (pd == (char *) NULL)) {
+  if ((py == NULL) || (pm == NULL) || (pd == NULL)) {
     fprintf (stderr, "error in DATE-MODE format: %s\n", DateMode);
     exit (0);
@@ -70,8 +70,8 @@
   warn_scan (header, DateKeyword, "%s",  1, line);
   /* remove possible separators: ':', '/' '.', '-' */
-  for (c = strchr (line, 0x3a); c != (char *) NULL; c = strchr (line, 0x3a)) { *c = ' '; }
-  for (c = strchr (line, 0x2f); c != (char *) NULL; c = strchr (line, 0x2f)) { *c = ' '; }
-  for (c = strchr (line, 0x2e); c != (char *) NULL; c = strchr (line, 0x2e)) { *c = ' '; }
-  for (c = strchr (line, 0x2d); c != (char *) NULL; c = strchr (line, 0x2d)) { *c = ' '; }
+  for (c = strchr (line, 0x3a); c != NULL; c = strchr (line, 0x3a)) { *c = ' '; }
+  for (c = strchr (line, 0x2f); c != NULL; c = strchr (line, 0x2f)) { *c = ' '; }
+  for (c = strchr (line, 0x2e); c != NULL; c = strchr (line, 0x2e)) { *c = ' '; }
+  for (c = strchr (line, 0x2d); c != NULL; c = strchr (line, 0x2d)) { *c = ' '; }
 
   Nf = 0;
Index: /trunk/Ohana/src/kapa2/src/LoadObject.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/LoadObject.c	(revision 20935)
+++ /trunk/Ohana/src/kapa2/src/LoadObject.c	(revision 20936)
@@ -123,5 +123,5 @@
   }
   if (Nbytes_send != Npts_send*sizeof(float)) {
-    fprintf (stderr, "Kapa Communication error: unexpected data size %d vs %d\n", Nbytes_send, Npts_send*sizeof(float));
+    fprintf (stderr, "Kapa Communication error: unexpected data size %d vs %ld\n", Nbytes_send, Npts_send*sizeof(float));
   }
 
Index: /trunk/Ohana/src/kapa2/src/PaintOverlay.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/PaintOverlay.c	(revision 20935)
+++ /trunk/Ohana/src/kapa2/src/PaintOverlay.c	(revision 20936)
@@ -5,5 +5,5 @@
   int i;
   int dX, dY, dx, dy;
-  int x, y, Xmin, Ymin, Xmax, Ymax, Xrange, Yrange;
+  int Xmin, Ymin, Xmax, Ymax, Xrange, Yrange;
   double t, expand, X, Y, pX, pY;
  
Index: /trunk/Ohana/src/libautocode/def/common.h
===================================================================
--- /trunk/Ohana/src/libautocode/def/common.h	(revision 20935)
+++ /trunk/Ohana/src/libautocode/def/common.h	(revision 20936)
@@ -38,5 +38,5 @@
 # endif
 
-# define e_time unsigned int
+# define e_time int
 # define e_void long long
 # define rawshort short
Index: /trunk/Ohana/src/libautocode/def/image.d
===================================================================
--- /trunk/Ohana/src/libautocode/def/image.d	(revision 20935)
+++ /trunk/Ohana/src/libautocode/def/image.d	(revision 20936)
@@ -50,4 +50,6 @@
 FIELD 	  ccdnum,           CCDNUM,               unsigned char,  CCD ID number
 FIELD 	  imageID,          IMAGE_ID,             unsigned int,   internal image ID
+
+# XXX do we want to use this to handle mosaics?
 # FIELD 	  parentID,         PARENT_ID,            unsigned int,   associated ref image
 FIELD 	  externID,         EXTERN_ID,            unsigned int,   external image ID
Index: /trunk/Ohana/src/libdvo/include/ps1_dev_3_defs.h
===================================================================
--- /trunk/Ohana/src/libdvo/include/ps1_dev_3_defs.h	(revision 20935)
+++ /trunk/Ohana/src/libdvo/include/ps1_dev_3_defs.h	(revision 20936)
@@ -1,2 +1,5 @@
+Image 		       	*Image_PS1_DEV_3_ToInternal (Image_PS1_DEV_3 *in, int Nvalues);
+Image_PS1_DEV_3  	*ImageInternalTo_PS1_DEV_3 (Image *in, int Nvalues);
+
 PhotCode *PhotCode_PS1_DEV_3_To_Internal (PhotCode_PS1_DEV_3 *in, int Nvalues);
 PhotCode_PS1_DEV_3 *PhotCode_Internal_To_PS1_DEV_3 (PhotCode *in, int Nvalues);
Index: /trunk/Ohana/src/libdvo/src/dvo_catalog.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/dvo_catalog.c	(revision 20935)
+++ /trunk/Ohana/src/libdvo/src/dvo_catalog.c	(revision 20936)
@@ -88,4 +88,7 @@
   catalog[0].secfilt = NULL;
   
+  catalog[0].objID = 0;
+  catalog[0].catID = 0;
+
   catalog[0].Naverage = 0;
   catalog[0].Nmeasure = 0;
Index: /trunk/Ohana/src/libdvo/src/dvo_catalog_create.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/dvo_catalog_create.c	(revision 20935)
+++ /trunk/Ohana/src/libdvo/src/dvo_catalog_create.c	(revision 20936)
@@ -94,4 +94,7 @@
     gfits_modify (&catalog[0].header, "RA1",  "%lf", 1, region[0].Rmax);
     gfits_modify (&catalog[0].header, "DEC1", "%lf", 1, region[0].Dmax);
+    
+    catalog[0].catID = region[0].index;
+    gfits_modify (&catalog[0].header, "CATID", "%d", 1, catalog[0].catID);
   }
 
Index: /trunk/Ohana/src/libdvo/src/dvo_catalog_mef.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/dvo_catalog_mef.c	(revision 20935)
+++ /trunk/Ohana/src/libdvo/src/dvo_catalog_mef.c	(revision 20936)
@@ -27,4 +27,10 @@
   if (!gfits_scan (&catalog[0].header, "NMISS",    "%d", 1, &Nmissing)) return (FALSE);
   if (!gfits_scan (&catalog[0].header, "NSECFILT", "%d", 1, &Nsecfilt)) Nsecfilt = 0;
+
+  /* the OBJID is a counter that uniquely defines an average entry and never changes.  if
+     it is not defined for a legacy database, we can generate them using the existing index values.
+     XXX if it is missing, give an error and require the user to upgrade the DB? */
+  if (!gfits_scan (&catalog[0].header, "OBJID",    "%d", 1, &catalog[0].objID)) return (FALSE);
+  if (!gfits_scan (&catalog[0].header, "CATID",    "%d", 1, &catalog[0].catID)) return (FALSE);
 
   /* save the current number so we can do partial updates */
@@ -228,4 +234,5 @@
   gfits_modify (&catalog[0].header, "NSECFILT", "%d", 1, Nsecfilt);
   gfits_modify (&catalog[0].header, "EXTEND",   "%t", 1, TRUE);
+  gfits_modify (&catalog[0].header, "OBJID",    "%d", 1, catalog[0].objID);
 
   f = catalog[0].f;
Index: /trunk/Ohana/src/libdvo/src/dvo_catalog_raw.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/dvo_catalog_raw.c	(revision 20935)
+++ /trunk/Ohana/src/libdvo/src/dvo_catalog_raw.c	(revision 20936)
@@ -25,4 +25,10 @@
   if (!gfits_scan (&catalog[0].header, "NMISS",    "%d", 1, &catalog[0].Nmissing)) return (FALSE);
   if (!gfits_scan (&catalog[0].header, "NSECFILT", "%d", 1, &catalog[0].Nsecfilt)) catalog[0].Nsecfilt = 0;
+
+  /* the OBJID is a counter that uniquely defines an average entry and never changes.  if
+     it is not defined for a legacy database, we can generate them using the existing index values.
+     XXX if it is missing, give an error and require the user to upgrade the DB? */
+  if (!gfits_scan (&catalog[0].header, "OBJID",    "%d", 1, &catalog[0].objID)) return (FALSE);
+  if (!gfits_scan (&catalog[0].header, "CATID",    "%d", 1, &catalog[0].catID)) return (FALSE);
 
   /* determine catalog format */
@@ -249,4 +255,5 @@
   gfits_modify (&catalog[0].header, "NMISS",    "%d", 1, catalog[0].Nmissing);
   gfits_modify (&catalog[0].header, "NSECFILT", "%d", 1, catalog[0].Nsecfilt);
+  gfits_modify (&catalog[0].header, "OBJID",    "%d", 1, catalog[0].objID);
 
   /* specify the appropriate data format */
Index: /trunk/Ohana/src/libdvo/src/dvo_catalog_split.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/dvo_catalog_split.c	(revision 20935)
+++ /trunk/Ohana/src/libdvo/src/dvo_catalog_split.c	(revision 20936)
@@ -174,4 +174,10 @@
   if (!gfits_scan (&catalog[0].header, "NMISS",    "%d", 1, &Nmissing)) return (FALSE);
   if (!gfits_scan (&catalog[0].header, "NSECFILT", "%d", 1, &Nsecfilt)) Nsecfilt = 0;
+
+  /* the OBJID is a counter that uniquely defines an average entry and never changes.  if
+     it is not defined for a legacy database, we can generate them using the existing index values.
+     XXX if it is missing, give an error and require the user to upgrade the DB? */
+  if (!gfits_scan (&catalog[0].header, "OBJID",    "%d", 1, &catalog[0].objID)) return (FALSE);
+  if (!gfits_scan (&catalog[0].header, "CATID",    "%d", 1, &catalog[0].catID)) return (FALSE);
 
   /* save the current number so we can do partial updates */
@@ -512,4 +518,5 @@
   gfits_modify (&catalog[0].header, "NSECFILT", "%d", 1, Nsecfilt);
   gfits_modify (&catalog[0].header, "EXTEND",   "%t", 1, TRUE);
+  gfits_modify (&catalog[0].header, "OBJID",    "%d", 1, catalog[0].objID);
 
   /* in split mode, we can save only part of the data */ 
@@ -712,4 +719,5 @@
   gfits_modify (&catalog[0].header, "NSECFILT", "%d", 1, Nsecfilt);
   gfits_modify (&catalog[0].header, "EXTEND",   "%t", 1, TRUE);
+  gfits_modify (&catalog[0].header, "OBJID",    "%d", 1, catalog[0].objID);
 
   /* in split mode, we can save only part of the data */ 
@@ -890,4 +898,5 @@
   gfits_modify (&catalog[0].header, "NSECFILT", "%d", 1, Nsecfilt);
   gfits_modify (&catalog[0].header, "EXTEND",   "%t", 1, TRUE);
+  gfits_modify (&catalog[0].header, "OBJID",    "%d", 1, catalog[0].objID);
 
   /* in split mode, we can save only part of the data */ 
Index: /trunk/Ohana/src/libdvo/src/skyregion_gsc.c
===================================================================
--- /trunk/Ohana/src/libdvo/src/skyregion_gsc.c	(revision 20935)
+++ /trunk/Ohana/src/libdvo/src/skyregion_gsc.c	(revision 20936)
@@ -153,4 +153,8 @@
   skytable[0].Nregions = 0;
 
+  // L0, L1, L2, L3, L4 all have index ranges of 0 -> Nregions and parent values pointing
+  // at the index of the parent.  SkyTableAppend updates these values based on the
+  // cumulative count
+
   SkyTableAppend (skytable, &L0, 0);
   SkyTableAppend (skytable, &L1, skytable[0].Nregions - L0.Nregions);
@@ -539,5 +543,6 @@
   for (i = 0; i < new[0].Nregions; i++) {
     old[0].regions[i + Nold] = new[0].regions[i];
-    old[0].regions[i + Nold].parent += Nprev;
+    old[0].regions[i + Nold].parent += Nold;
+    old[0].regions[i + Nold].index += Nold;
   }
   return;
@@ -560,5 +565,3 @@
     notes and questions:
     1) is the regions.index value used?
-
-
 ***/
Index: /trunk/Ohana/src/libkapa/src/KiiPicture.c
===================================================================
--- /trunk/Ohana/src/libkapa/src/KiiPicture.c	(revision 20935)
+++ /trunk/Ohana/src/libkapa/src/KiiPicture.c	(revision 20936)
@@ -108,9 +108,7 @@
 int KiiNewPicture2D (int fd, KiiImage *image, KapaImageData *data, Coords *coords) {
 
-  int i, j;
-  int Npix, Ncolors, NNcolors, size;
-  float *in, min, max;
-  char *out, *outbuffer;
-  double a1, a2;
+  int j;
+  int Npix, Ncolors, size;
+  float min, max;
 
   Npix = image[0].Nx*image[0].Ny;
Index: /trunk/Ohana/src/mosastro/src/parse_time.c
===================================================================
--- /trunk/Ohana/src/mosastro/src/parse_time.c	(revision 20935)
+++ /trunk/Ohana/src/mosastro/src/parse_time.c	(revision 20936)
@@ -32,10 +32,10 @@
   gfits_scan (header, UTKeyword, "%s", 1, line);
   /* remove ':' characters */
-  for (c = strchr (line, 0x3a); c != (char *) NULL; c = strchr (line, 0x3a)) { *c = ' '; }
+  for (c = strchr (line, 0x3a); c != NULL; c = strchr (line, 0x3a)) { *c = ' '; }
   sscanf (line, "%d %d %d", &hour, &min, &sec);
 
   /* parse mode line */
   uppercase (DateMode);
-  for (Ny = 0, c = strchr (DateMode, 'Y'); c != (char ) NULL; c = strchr (c + 1, 'Y'), Ny++);
+  for (Ny = 0, c = strchr (DateMode, 'Y'); c != NULL; c = strchr (c + 1, 'Y'), Ny++);
   if ((Ny != 2) && (Ny != 4)) {
     fprintf (stderr, "error in DATE-MODE format: %s\n", DateMode);
@@ -45,5 +45,5 @@
   pm = strchr (DateMode, 'M');
   pd = strchr (DateMode, 'D');
-  if ((py == (char *) NULL) || (pm == (char *) NULL) || (pd == (char *) NULL)) {
+  if ((py == NULL) || (pm == NULL) || (pd == NULL)) {
     fprintf (stderr, "error in DATE-MODE format: %s\n", DateMode);
     exit (1);
@@ -71,8 +71,8 @@
   gfits_scan (header, DateKeyword, "%s",  1, line);
   /* remove possible separators: ':', '/' '.', '-' */
-  for (c = strchr (line, 0x3a); c != (char *) NULL; c = strchr (line, 0x3a)) { *c = ' '; }
-  for (c = strchr (line, 0x2f); c != (char *) NULL; c = strchr (line, 0x2f)) { *c = ' '; }
-  for (c = strchr (line, 0x2e); c != (char *) NULL; c = strchr (line, 0x2e)) { *c = ' '; }
-  for (c = strchr (line, 0x2d); c != (char *) NULL; c = strchr (line, 0x2d)) { *c = ' '; }
+  for (c = strchr (line, 0x3a); c != NULL; c = strchr (line, 0x3a)) { *c = ' '; }
+  for (c = strchr (line, 0x2f); c != NULL; c = strchr (line, 0x2f)) { *c = ' '; }
+  for (c = strchr (line, 0x2e); c != NULL; c = strchr (line, 0x2e)) { *c = ' '; }
+  for (c = strchr (line, 0x2d); c != NULL; c = strchr (line, 0x2d)) { *c = ' '; }
 
   Nf = 0;
Index: /trunk/Ohana/src/opihi/cmd.astro/biassub.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.astro/biassub.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.astro/biassub.c	(revision 20936)
@@ -5,5 +5,6 @@
   int i, j, k, N, dir, nlong, nwide, start;
   int sx, sy, nx, ny, NX, NY, NoVector, Nval;
-  float *V, *DV, dV, *vect, *segment, val;
+  float *V, dV, *segment, val;
+  opihi_flt *DV, *vect;
   Vector *xvec, *yvec;
   Buffer *buf;
@@ -54,5 +55,5 @@
   }
 
-  ALLOCATE (vect, float, nlong);
+  ALLOCATE (vect, opihi_flt, nlong);
   ALLOCATE (segment, float, nwide);
 
@@ -90,10 +91,9 @@
 
   if (!NoVector) {
-    xvec[0].Nelements = yvec[0].Nelements = nlong;
-    REALLOCATE (xvec[0].elements, float, nlong);
-    REALLOCATE (yvec[0].elements, float, nlong);
+    ResetVector (xvec, OPIHI_FLT, nlong);
+    ResetVector (yvec, OPIHI_FLT, nlong);
     for (i = 0; i < nlong; i++) {
-      xvec[0].elements[i] = i + start;
-      yvec[0].elements[i] = vect[i];
+      xvec[0].elements.Flt[i] = i + start;
+      yvec[0].elements.Flt[i] = vect[i];
     }
   }
Index: /trunk/Ohana/src/opihi/cmd.astro/cgrid.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.astro/cgrid.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.astro/cgrid.c	(revision 20936)
@@ -3,6 +3,6 @@
   if (N == NELEMENTS) { \
     NELEMENTS +=200; \
-    REALLOCATE (Xvec.elements, float, NELEMENTS); \
-    REALLOCATE (Yvec.elements, float, NELEMENTS); \
+    REALLOCATE (Xvec.elements.Flt, opihi_flt, NELEMENTS); \
+    REALLOCATE (Yvec.elements.Flt, opihi_flt, NELEMENTS); \
   }
 
@@ -95,8 +95,8 @@
   
   /* prepare vectors to hold data */
+  N = 0;
   NELEMENTS = 200;
-  ALLOCATE (Xvec.elements, float, NELEMENTS);
-  ALLOCATE (Yvec.elements, float, NELEMENTS);
-  N = 0;
+  SetVector (&Xvec, OPIHI_FLT, NELEMENTS);
+  SetVector (&Yvec, OPIHI_FLT, NELEMENTS);
   
   /***  do consecutive RA lines, first increasing **/
@@ -109,23 +109,23 @@
     for (d = firstDEC; (d < 90 + dD) && (LOnPic || NorthPole || SouthPole); d += dD) {
       D = MAX (-90, MIN(90, d));
-      status = fRD_to_XY (&Xvec.elements[N], &Yvec.elements[N], r, D, &graphmode.coords);
-      /*
-      if ((fabs(Xvec.elements[N] - Xvec.elements[N-1]) > 10) && (fabs(Yvec.elements[N] - Yvec.elements[N-1]) > 10))
-	First = TRUE;
-	*/
-      if ((Xvec.elements[N] >= graphmode.xmin) && (Xvec.elements[N] <= graphmode.xmax) && 
-	  (Yvec.elements[N] >= graphmode.ymin) && (Yvec.elements[N] <= graphmode.ymax) && status) {
-	N++;
-	CHECKELEMENTS;
-	OnPic = TRUE;
-	if (!First) {
-	  Xvec.elements[N] = Xvec.elements[N-1];
-	  Yvec.elements[N] = Yvec.elements[N-1];
-	  N++;
-	  CHECKELEMENTS;
-	} else {
-	  if (N > 1) {
-	    Xvec.elements[N-2] = Xvec.elements[N-1];
-	    Yvec.elements[N-2] = Yvec.elements[N-1];
+      status = RD_to_XY (&Xvec.elements.Flt[N], &Yvec.elements.Flt[N], r, D, &graphmode.coords);
+      /*
+      if ((fabs(Xvec.elements.Flt[N] - Xvec.elements.Flt[N-1]) > 10) && (fabs(Yvec.elements.Flt[N] - Yvec.elements.Flt[N-1]) > 10))
+	First = TRUE;
+	*/
+      if ((Xvec.elements.Flt[N] >= graphmode.xmin) && (Xvec.elements.Flt[N] <= graphmode.xmax) && 
+	  (Yvec.elements.Flt[N] >= graphmode.ymin) && (Yvec.elements.Flt[N] <= graphmode.ymax) && status) {
+	N++;
+	CHECKELEMENTS;
+	OnPic = TRUE;
+	if (!First) {
+	  Xvec.elements.Flt[N] = Xvec.elements.Flt[N-1];
+	  Yvec.elements.Flt[N] = Yvec.elements.Flt[N-1];
+	  N++;
+	  CHECKELEMENTS;
+	} else {
+	  if (N > 1) {
+	    Xvec.elements.Flt[N-2] = Xvec.elements.Flt[N-1];
+	    Yvec.elements.Flt[N-2] = Yvec.elements.Flt[N-1];
 	    N--;
 	  }
@@ -142,23 +142,23 @@
     for (d = firstDEC; (d > -90 - dD) && (LOnPic || NorthPole || SouthPole); d -= dD) {
       D = MAX (-90, MIN(90, d));
-      status = fRD_to_XY (&Xvec.elements[N], &Yvec.elements[N], r, D, &graphmode.coords);
-      /*
-      if ((fabs(Xvec.elements[N] - Xvec.elements[N-1]) > 10) && (fabs(Yvec.elements[N] - Yvec.elements[N-1]) > 10))
-	First = TRUE;
-	*/
-      if ((Xvec.elements[N] >= graphmode.xmin) && (Xvec.elements[N] <= graphmode.xmax) && 
-	  (Yvec.elements[N] >= graphmode.ymin) && (Yvec.elements[N] <= graphmode.ymax) && status) {
-	N++;
-	CHECKELEMENTS;
-	OnPic = TRUE;
-	if (!First) {
-	  Xvec.elements[N] = Xvec.elements[N-1];
-	  Yvec.elements[N] = Yvec.elements[N-1];
-	  N++;
-	  CHECKELEMENTS;
-	} else {
-	  if (N > 1) {
-	    Xvec.elements[N-2] = Xvec.elements[N-1];
-	    Yvec.elements[N-2] = Yvec.elements[N-1];
+      status = RD_to_XY (&Xvec.elements.Flt[N], &Yvec.elements.Flt[N], r, D, &graphmode.coords);
+      /*
+      if ((fabs(Xvec.elements.Flt[N] - Xvec.elements.Flt[N-1]) > 10) && (fabs(Yvec.elements.Flt[N] - Yvec.elements.Flt[N-1]) > 10))
+	First = TRUE;
+	*/
+      if ((Xvec.elements.Flt[N] >= graphmode.xmin) && (Xvec.elements.Flt[N] <= graphmode.xmax) && 
+	  (Yvec.elements.Flt[N] >= graphmode.ymin) && (Yvec.elements.Flt[N] <= graphmode.ymax) && status) {
+	N++;
+	CHECKELEMENTS;
+	OnPic = TRUE;
+	if (!First) {
+	  Xvec.elements.Flt[N] = Xvec.elements.Flt[N-1];
+	  Yvec.elements.Flt[N] = Yvec.elements.Flt[N-1];
+	  N++;
+	  CHECKELEMENTS;
+	} else {
+	  if (N > 1) {
+	    Xvec.elements.Flt[N-2] = Xvec.elements.Flt[N-1];
+	    Yvec.elements.Flt[N-2] = Yvec.elements.Flt[N-1];
 	    N--;
 	  }
@@ -181,23 +181,23 @@
     for (d = firstDEC; (d < 90 + dD) && (LOnPic || NorthPole || SouthPole); d += dD) {
       D = MAX (-90, MIN(90, d));
-      status = fRD_to_XY (&Xvec.elements[N], &Yvec.elements[N], r, D, &graphmode.coords);
-      /*
-      if ((fabs(Xvec.elements[N] - Xvec.elements[N-1]) > 10) && (fabs(Yvec.elements[N] - Yvec.elements[N-1]) > 10))
-	First = TRUE;
-	*/
-      if ((Xvec.elements[N] >= graphmode.xmin) && (Xvec.elements[N] <= graphmode.xmax) && 
-	  (Yvec.elements[N] >= graphmode.ymin) && (Yvec.elements[N] <= graphmode.ymax) && status) {
-	N++;
-	CHECKELEMENTS;
-	OnPic = TRUE;
-	if (!First) {
-	  Xvec.elements[N] = Xvec.elements[N-1];
-	  Yvec.elements[N] = Yvec.elements[N-1];
-	  N++;
-	  CHECKELEMENTS;
-	} else {
-	  if (N > 1) {
-	    Xvec.elements[N-2] = Xvec.elements[N-1];
-	    Yvec.elements[N-2] = Yvec.elements[N-1];
+      status = RD_to_XY (&Xvec.elements.Flt[N], &Yvec.elements.Flt[N], r, D, &graphmode.coords);
+      /*
+      if ((fabs(Xvec.elements.Flt[N] - Xvec.elements.Flt[N-1]) > 10) && (fabs(Yvec.elements.Flt[N] - Yvec.elements.Flt[N-1]) > 10))
+	First = TRUE;
+	*/
+      if ((Xvec.elements.Flt[N] >= graphmode.xmin) && (Xvec.elements.Flt[N] <= graphmode.xmax) && 
+	  (Yvec.elements.Flt[N] >= graphmode.ymin) && (Yvec.elements.Flt[N] <= graphmode.ymax) && status) {
+	N++;
+	CHECKELEMENTS;
+	OnPic = TRUE;
+	if (!First) {
+	  Xvec.elements.Flt[N] = Xvec.elements.Flt[N-1];
+	  Yvec.elements.Flt[N] = Yvec.elements.Flt[N-1];
+	  N++;
+	  CHECKELEMENTS;
+	} else {
+	  if (N > 1) {
+	    Xvec.elements.Flt[N-2] = Xvec.elements.Flt[N-1];
+	    Yvec.elements.Flt[N-2] = Yvec.elements.Flt[N-1];
 	    N--;
 	  }
@@ -214,23 +214,23 @@
     for (d = firstDEC; (d > -90 - dD) && (LOnPic || NorthPole || SouthPole); d -= dD) {
       D = MAX (-90, MIN(90, d));
-      status = fRD_to_XY (&Xvec.elements[N], &Yvec.elements[N], r, D, &graphmode.coords);
-      /*
-      if ((fabs(Xvec.elements[N] - Xvec.elements[N-1]) > 10) && (fabs(Yvec.elements[N] - Yvec.elements[N-1]) > 10))
-	First = TRUE;
-	*/
-      if ((Xvec.elements[N] >= graphmode.xmin) && (Xvec.elements[N] <= graphmode.xmax) && 
-	  (Yvec.elements[N] >= graphmode.ymin) && (Yvec.elements[N] <= graphmode.ymax) && status) {
-	N++;
-	CHECKELEMENTS;
-	OnPic = TRUE;
-	if (!First) {
-	  Xvec.elements[N] = Xvec.elements[N-1];
-	  Yvec.elements[N] = Yvec.elements[N-1];
-	  N++;
-	  CHECKELEMENTS;
-	} else {
-	  if (N > 1) {
-	    Xvec.elements[N-2] = Xvec.elements[N-1];
-	    Yvec.elements[N-2] = Yvec.elements[N-1];
+      status = RD_to_XY (&Xvec.elements.Flt[N], &Yvec.elements.Flt[N], r, D, &graphmode.coords);
+      /*
+      if ((fabs(Xvec.elements.Flt[N] - Xvec.elements.Flt[N-1]) > 10) && (fabs(Yvec.elements.Flt[N] - Yvec.elements.Flt[N-1]) > 10))
+	First = TRUE;
+	*/
+      if ((Xvec.elements.Flt[N] >= graphmode.xmin) && (Xvec.elements.Flt[N] <= graphmode.xmax) && 
+	  (Yvec.elements.Flt[N] >= graphmode.ymin) && (Yvec.elements.Flt[N] <= graphmode.ymax) && status) {
+	N++;
+	CHECKELEMENTS;
+	OnPic = TRUE;
+	if (!First) {
+	  Xvec.elements.Flt[N] = Xvec.elements.Flt[N-1];
+	  Yvec.elements.Flt[N] = Yvec.elements.Flt[N-1];
+	  N++;
+	  CHECKELEMENTS;
+	} else {
+	  if (N > 1) {
+	    Xvec.elements.Flt[N-2] = Xvec.elements.Flt[N-1];
+	    Yvec.elements.Flt[N-2] = Yvec.elements.Flt[N-1];
 	    N--;
 	  }
@@ -253,23 +253,23 @@
     First = TRUE;
     for (r = firstRA; (r < firstRA + 180) && (LOnPic || NorthPole || SouthPole); r += dR) {
-      status = fRD_to_XY (&Xvec.elements[N], &Yvec.elements[N], r, D, &graphmode.coords);
-      /*
-      if ((fabs(Xvec.elements[N] - Xvec.elements[N-1]) > 10) && (fabs(Yvec.elements[N] - Yvec.elements[N-1]) > 10))
-	First = TRUE;
-	*/
-      if ((Xvec.elements[N] >= graphmode.xmin) && (Xvec.elements[N] <= graphmode.xmax) && 
-	  (Yvec.elements[N] >= graphmode.ymin) && (Yvec.elements[N] <= graphmode.ymax) && status) {
-	N++;
-	CHECKELEMENTS;
-	OnPic = TRUE;
-	if (!First) {
-	  Xvec.elements[N] = Xvec.elements[N-1];
-	  Yvec.elements[N] = Yvec.elements[N-1];
-	  N++;
-	  CHECKELEMENTS;
-	} else {
-	  if (N > 1) {
-	    Xvec.elements[N-2] = Xvec.elements[N-1];
-	    Yvec.elements[N-2] = Yvec.elements[N-1];
+      status = RD_to_XY (&Xvec.elements.Flt[N], &Yvec.elements.Flt[N], r, D, &graphmode.coords);
+      /*
+      if ((fabs(Xvec.elements.Flt[N] - Xvec.elements.Flt[N-1]) > 10) && (fabs(Yvec.elements.Flt[N] - Yvec.elements.Flt[N-1]) > 10))
+	First = TRUE;
+	*/
+      if ((Xvec.elements.Flt[N] >= graphmode.xmin) && (Xvec.elements.Flt[N] <= graphmode.xmax) && 
+	  (Yvec.elements.Flt[N] >= graphmode.ymin) && (Yvec.elements.Flt[N] <= graphmode.ymax) && status) {
+	N++;
+	CHECKELEMENTS;
+	OnPic = TRUE;
+	if (!First) {
+	  Xvec.elements.Flt[N] = Xvec.elements.Flt[N-1];
+	  Yvec.elements.Flt[N] = Yvec.elements.Flt[N-1];
+	  N++;
+	  CHECKELEMENTS;
+	} else {
+	  if (N > 1) {
+	    Xvec.elements.Flt[N-2] = Xvec.elements.Flt[N-1];
+	    Yvec.elements.Flt[N-2] = Yvec.elements.Flt[N-1];
 	    N--;
 	  }
@@ -285,23 +285,23 @@
     LOnPic = TRUE;
     for (r = firstRA; (r > firstRA - 180) && (LOnPic || NorthPole || SouthPole); r -= dR) {
-      status = fRD_to_XY (&Xvec.elements[N], &Yvec.elements[N], r, D, &graphmode.coords);
-      /*
-      if ((fabs(Xvec.elements[N] - Xvec.elements[N-1]) > 10) && (fabs(Yvec.elements[N] - Yvec.elements[N-1]) > 10))
-	First = TRUE;
-	*/
-      if ((Xvec.elements[N] >= graphmode.xmin) && (Xvec.elements[N] <= graphmode.xmax) && 
-	  (Yvec.elements[N] >= graphmode.ymin) && (Yvec.elements[N] <= graphmode.ymax) && status) {
-	N++;
-	CHECKELEMENTS;
-	OnPic = TRUE;
-	if (!First) {
-	  Xvec.elements[N] = Xvec.elements[N-1];
-	  Yvec.elements[N] = Yvec.elements[N-1];
-	  N++;
-	  CHECKELEMENTS;
-	} else {
-	  if (N > 1) {
-	    Xvec.elements[N-2] = Xvec.elements[N-1];
-	    Yvec.elements[N-2] = Yvec.elements[N-1];
+      status = RD_to_XY (&Xvec.elements.Flt[N], &Yvec.elements.Flt[N], r, D, &graphmode.coords);
+      /*
+      if ((fabs(Xvec.elements.Flt[N] - Xvec.elements.Flt[N-1]) > 10) && (fabs(Yvec.elements.Flt[N] - Yvec.elements.Flt[N-1]) > 10))
+	First = TRUE;
+	*/
+      if ((Xvec.elements.Flt[N] >= graphmode.xmin) && (Xvec.elements.Flt[N] <= graphmode.xmax) && 
+	  (Yvec.elements.Flt[N] >= graphmode.ymin) && (Yvec.elements.Flt[N] <= graphmode.ymax) && status) {
+	N++;
+	CHECKELEMENTS;
+	OnPic = TRUE;
+	if (!First) {
+	  Xvec.elements.Flt[N] = Xvec.elements.Flt[N-1];
+	  Yvec.elements.Flt[N] = Yvec.elements.Flt[N-1];
+	  N++;
+	  CHECKELEMENTS;
+	} else {
+	  if (N > 1) {
+	    Xvec.elements.Flt[N-2] = Xvec.elements.Flt[N-1];
+	    Yvec.elements.Flt[N-2] = Yvec.elements.Flt[N-1];
 	    N--;
 	  }
@@ -324,23 +324,23 @@
     First = TRUE;
     for (r = firstRA; (r < firstRA + 180) && (LOnPic || NorthPole || SouthPole); r += dR) {
-      status = fRD_to_XY (&Xvec.elements[N], &Yvec.elements[N], r, D, &graphmode.coords);
-      /*
-      if ((fabs(Xvec.elements[N] - Xvec.elements[N-1]) > 10) && (fabs(Yvec.elements[N] - Yvec.elements[N-1]) > 10))
-	First = TRUE;
-	*/
-      if ((Xvec.elements[N] >= graphmode.xmin) && (Xvec.elements[N] <= graphmode.xmax) && 
-	  (Yvec.elements[N] >= graphmode.ymin) && (Yvec.elements[N] <= graphmode.ymax) && status) {
-	N++;
-	CHECKELEMENTS;
-	OnPic = TRUE;
-	if (!First) {
-	  Xvec.elements[N] = Xvec.elements[N-1];
-	  Yvec.elements[N] = Yvec.elements[N-1];
-	  N++;
-	  CHECKELEMENTS;
-	} else {
-	  if (N > 1) {
-	    Xvec.elements[N-2] = Xvec.elements[N-1];
-	    Yvec.elements[N-2] = Yvec.elements[N-1];
+      status = RD_to_XY (&Xvec.elements.Flt[N], &Yvec.elements.Flt[N], r, D, &graphmode.coords);
+      /*
+      if ((fabs(Xvec.elements.Flt[N] - Xvec.elements.Flt[N-1]) > 10) && (fabs(Yvec.elements.Flt[N] - Yvec.elements.Flt[N-1]) > 10))
+	First = TRUE;
+	*/
+      if ((Xvec.elements.Flt[N] >= graphmode.xmin) && (Xvec.elements.Flt[N] <= graphmode.xmax) && 
+	  (Yvec.elements.Flt[N] >= graphmode.ymin) && (Yvec.elements.Flt[N] <= graphmode.ymax) && status) {
+	N++;
+	CHECKELEMENTS;
+	OnPic = TRUE;
+	if (!First) {
+	  Xvec.elements.Flt[N] = Xvec.elements.Flt[N-1];
+	  Yvec.elements.Flt[N] = Yvec.elements.Flt[N-1];
+	  N++;
+	  CHECKELEMENTS;
+	} else {
+	  if (N > 1) {
+	    Xvec.elements.Flt[N-2] = Xvec.elements.Flt[N-1];
+	    Yvec.elements.Flt[N-2] = Yvec.elements.Flt[N-1];
 	    N--;
 	  }
@@ -356,23 +356,23 @@
     LOnPic = TRUE;
     for (r = firstRA; (r > firstRA - 180) && (LOnPic || NorthPole || SouthPole); r -= dR) {
-      status = fRD_to_XY (&Xvec.elements[N], &Yvec.elements[N], r, D, &graphmode.coords);
-      /*
-      if ((fabs(Xvec.elements[N] - Xvec.elements[N-1]) > 10) && (fabs(Yvec.elements[N] - Yvec.elements[N-1]) > 10))
-	First = TRUE;
-	*/
-      if ((Xvec.elements[N] >= graphmode.xmin) && (Xvec.elements[N] <= graphmode.xmax) && 
-	  (Yvec.elements[N] >= graphmode.ymin) && (Yvec.elements[N] <= graphmode.ymax) && status) {
-	N++;
-	CHECKELEMENTS;
-	OnPic = TRUE;
-	if (!First) {
-	  Xvec.elements[N] = Xvec.elements[N-1];
-	  Yvec.elements[N] = Yvec.elements[N-1];
-	  N++;
-	  CHECKELEMENTS;
-	} else {
-	  if (N > 1) {
-	    Xvec.elements[N-2] = Xvec.elements[N-1];
-	    Yvec.elements[N-2] = Yvec.elements[N-1];
+      status = RD_to_XY (&Xvec.elements.Flt[N], &Yvec.elements.Flt[N], r, D, &graphmode.coords);
+      /*
+      if ((fabs(Xvec.elements.Flt[N] - Xvec.elements.Flt[N-1]) > 10) && (fabs(Yvec.elements.Flt[N] - Yvec.elements.Flt[N-1]) > 10))
+	First = TRUE;
+	*/
+      if ((Xvec.elements.Flt[N] >= graphmode.xmin) && (Xvec.elements.Flt[N] <= graphmode.xmax) && 
+	  (Yvec.elements.Flt[N] >= graphmode.ymin) && (Yvec.elements.Flt[N] <= graphmode.ymax) && status) {
+	N++;
+	CHECKELEMENTS;
+	OnPic = TRUE;
+	if (!First) {
+	  Xvec.elements.Flt[N] = Xvec.elements.Flt[N-1];
+	  Yvec.elements.Flt[N] = Yvec.elements.Flt[N-1];
+	  N++;
+	  CHECKELEMENTS;
+	} else {
+	  if (N > 1) {
+	    Xvec.elements.Flt[N-2] = Xvec.elements.Flt[N-1];
+	    Yvec.elements.Flt[N-2] = Yvec.elements.Flt[N-1];
 	    N--;
 	  }
@@ -391,8 +391,8 @@
   graphmode.ptype = 100; /* connect a pair */
   graphmode.etype = 0;
-  PlotVectorPair (kapa, N, Xvec.elements, Yvec.elements, &graphmode);
-
-  free (Xvec.elements);
-  free (Yvec.elements);
+  PlotVectorPair (kapa, &Xvec, &Yvec, &graphmode);
+
+  free (Xvec.elements.Ptr);
+  free (Yvec.elements.Ptr);
   return (TRUE);
 
Index: /trunk/Ohana/src/opihi/cmd.astro/coords.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.astro/coords.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.astro/coords.c	(revision 20936)
@@ -56,4 +56,6 @@
       return (FALSE);
     }
+    REQUIRE_VECTOR_FLT (xvec, FALSE); 
+    REQUIRE_VECTOR_FLT (yvec, FALSE); 
     form = VECTOR;
   }      
@@ -89,5 +91,5 @@
   if (mode == SKY) {
     for (i = 0; i < xvec[0].Nelements; i++) {
-      fXY_to_RD (&xvec[0].elements[i], &yvec[0].elements[i], xvec[0].elements[i], yvec[0].elements[i], &coords);
+      XY_to_RD (&xvec[0].elements.Flt[i], &yvec[0].elements.Flt[i], xvec[0].elements.Flt[i], yvec[0].elements.Flt[i], &coords);
     }
     return (TRUE);
@@ -95,5 +97,5 @@
   if (mode == PIXEL) {
     for (i = 0; i < xvec[0].Nelements; i++) {
-      fRD_to_XY (&xvec[0].elements[i], &yvec[0].elements[i], xvec[0].elements[i], yvec[0].elements[i], &coords);
+      RD_to_XY (&xvec[0].elements.Flt[i], &yvec[0].elements.Flt[i], xvec[0].elements.Flt[i], yvec[0].elements.Flt[i], &coords);
     }
     return (TRUE);
Index: /trunk/Ohana/src/opihi/cmd.astro/cplot.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.astro/cplot.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.astro/cplot.c	(revision 20936)
@@ -4,5 +4,5 @@
   
   int i, kapa, Npts, status, leftside;
-  float *x, *y, *r, *d, Rmin, Rmax, Rmid;
+  opihi_flt *x, *y, *r, *d, Rmin, Rmax, Rmid;
   Vector Xvec, Yvec, *xvec, *yvec;
   Graphdata graphmode;
@@ -23,4 +23,7 @@
   if ((yvec = SelectVector (argv[2], OLDVECTOR, TRUE)) == NULL) return (FALSE);
 
+  REQUIRE_VECTOR_FLT (xvec, FALSE); 
+  REQUIRE_VECTOR_FLT (yvec, FALSE); 
+
   if (xvec[0].Nelements != yvec[0].Nelements) {
     gprint (GP_ERR, "vectors are not the same length\n");
@@ -28,18 +31,15 @@
   }
 
-  ALLOCATE (Xvec.elements, float, xvec[0].Nelements);
-  ALLOCATE (Yvec.elements, float, xvec[0].Nelements);
-    
-  Xvec.Nelements = xvec[0].Nelements;
-  Yvec.Nelements = xvec[0].Nelements;
+  SetVector (&Xvec, OPIHI_FLT, xvec[0].Nelements);
+  SetVector (&Yvec, OPIHI_FLT, xvec[0].Nelements);
   
-  r = xvec[0].elements;
-  d = yvec[0].elements;
-  x = Xvec.elements;
-  y = Yvec.elements;
+  r = xvec[0].elements.Flt;
+  d = yvec[0].elements.Flt;
+  x = Xvec.elements.Flt;
+  y = Yvec.elements.Flt;
   
   Npts = 0;
   for (i = 0; i < Xvec.Nelements; i++, r++, d++) {
-      *r = ohana_normalize_angle (*r);
+    *r = ohana_normalize_angle (*r);
     while (*r < Rmin) *r += 360.0;
     while (*r > Rmax) *r -= 360.0;
@@ -51,5 +51,5 @@
       if (!leftside && (r[0] < Rmid - 90)) { r[0] += 360.0; }
     }
-    status = fRD_to_XY (x, y, *r, *d, &graphmode.coords);
+    status = RD_to_XY (x, y, *r, *d, &graphmode.coords);
 
     // if we fail on one of the points, drop the corresponding pair
@@ -77,8 +77,8 @@
 
   graphmode.etype = 0;
-  PlotVectorPair (kapa, Npts, Xvec.elements, Yvec.elements, &graphmode);
+  PlotVectorPair (kapa, &Xvec, &Yvec, &graphmode);
   
-  free (Xvec.elements);
-  free (Yvec.elements);
+  free (Xvec.elements.Ptr);
+  free (Yvec.elements.Ptr);
     
   return (TRUE);
Index: /trunk/Ohana/src/opihi/cmd.astro/csystem.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.astro/csystem.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.astro/csystem.c	(revision 20936)
@@ -6,5 +6,5 @@
   int i;
   double X, Y, x, y;
-  float *xptr, *yptr;
+  opihi_flt *xptr, *yptr;
   Vector *xvec, *yvec;
   CoordTransformSystem input, output;
@@ -54,12 +54,12 @@
   }
   
-  xptr = xvec[0].elements;
-  yptr = yvec[0].elements;
+  CastVector (xvec, OPIHI_FLT);
+  CastVector (yvec, OPIHI_FLT);
+
+  xptr = xvec[0].elements.Flt;
+  yptr = yvec[0].elements.Flt;
 
   for (i = 0; i < xvec[0].Nelements; i++, xptr++, yptr++) {
-    // ApplyTransform takes (double *), but xptr, yptr are (float *)
-    ApplyTransform (&x, &y, *xptr, *yptr, transform);
-    *xptr = x;
-    *yptr = y;
+    ApplyTransform (xptr, yptr, *xptr, *yptr, transform);
   }
 
Index: /trunk/Ohana/src/opihi/cmd.astro/czplot.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.astro/czplot.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.astro/czplot.c	(revision 20936)
@@ -3,7 +3,7 @@
 int czplot (int argc, char **argv) {
   
-  int i, kapa, Npts;
+  int i, kapa;
   double min, range, Rmin, Rmax;
-  float *in, *out, *r, *d, *x, *y;
+  opihi_flt *out, *r, *d, *x, *y;
   Vector Xvec, Yvec, Zvec, *xvec, *yvec, *zvec;
   Graphdata graphmode;
@@ -26,4 +26,8 @@
   if ((zvec = SelectVector (argv[3], OLDVECTOR, TRUE)) == NULL) return (FALSE);
 
+  REQUIRE_VECTOR_FLT (xvec, FALSE); 
+  REQUIRE_VECTOR_FLT (yvec, FALSE); 
+  REQUIRE_VECTOR_FLT (zvec, FALSE); 
+
   if (xvec[0].Nelements != yvec[0].Nelements) {
     gprint (GP_ERR, "vectors %s and %s not the same length\n", argv[1], argv[2]);
@@ -34,21 +38,28 @@
     return (FALSE);
   }
-  Xvec.Nelements = xvec[0].Nelements;
-  Yvec.Nelements = xvec[0].Nelements;
-  Zvec.Nelements = zvec[0].Nelements;
-  ALLOCATE (Xvec.elements, float, Xvec.Nelements);
-  ALLOCATE (Yvec.elements, float, Yvec.Nelements);
-  ALLOCATE (Zvec.elements, float, Zvec.Nelements);
+  SetVector (&Xvec, OPIHI_FLT, xvec[0].Nelements);
+  SetVector (&Yvec, OPIHI_FLT, xvec[0].Nelements);
+  SetVector (&Zvec, OPIHI_FLT, xvec[0].Nelements);
   
-  r   = xvec[0].elements;
-  d   = yvec[0].elements;
-  in  = zvec[0].elements;
-  x   = Xvec.elements;
-  y   = Yvec.elements;
-  out = Zvec.elements;
-  for (i = 0; i < Zvec.Nelements; i++, in++, out++, r++, d++, x++, y++) {
-    *out = MIN (1.0, MAX (0.01, (*in - min) / range));
+  r   = xvec[0].elements.Flt;
+  d   = yvec[0].elements.Flt;
+  x   = Xvec.elements.Flt;
+  y   = Yvec.elements.Flt;
+  for (i = 0; i < Zvec.Nelements; i++, r++, d++, x++, y++) {
     *r = ohana_normalize_angle (*r);
-    fRD_to_XY (x, y, *r, *d, &graphmode.coords);
+    RD_to_XY (x, y, *r, *d, &graphmode.coords);
+  }
+
+  out = Zvec.elements.Flt;
+  if (zvec->type == OPIHI_FLT) {
+    opihi_flt *in  = zvec[0].elements.Flt;
+    for (i = 0; i < Zvec.Nelements; i++, in++, out++) {
+      *out = MIN (1.0, MAX (0.01, (*in - min) / range));
+    }
+  } else {
+    opihi_int *in  = zvec[0].elements.Int;
+    for (i = 0; i < Zvec.Nelements; i++, in++, out++) {
+      *out = MIN (1.0, MAX (0.01, (*in - min) / range));
+    }
   }
 
@@ -56,10 +67,9 @@
   graphmode.size = -1; /* point size determined by Zvec */
   graphmode.etype = 0;
-  Npts = Xvec.Nelements;
-  PlotVectorTriplet (kapa, Npts, Xvec.elements, Yvec.elements, Zvec.elements, &graphmode);
+  PlotVectorTriplet (kapa, &Xvec, &Yvec, &Zvec, &graphmode);
 
-  free (Xvec.elements);
-  free (Yvec.elements);
-  free (Zvec.elements);
+  free (Xvec.elements.Flt);
+  free (Yvec.elements.Flt);
+  free (Zvec.elements.Flt);
 
   return (TRUE);
Index: /trunk/Ohana/src/opihi/cmd.astro/imfit-fgauss.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.astro/imfit-fgauss.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.astro/imfit-fgauss.c	(revision 20936)
@@ -1,5 +1,5 @@
 # include "imfit.h"
 
-float fgaussTD (float, float, float *, int, float *);
+opihi_flt fgaussTD (opihi_flt, opihi_flt, opihi_flt *, int, opihi_flt *);
 void  fgaussCL ();
 
@@ -14,8 +14,8 @@
 
   /* allocate free and fixed parameters */
-  ALLOCATE (par, float, MAX (Npar, 1));
-  bzero (par, Npar*sizeof(float));
-  ALLOCATE (fpar, float, MAX (Nfpar, 1));
-  bzero (fpar, Nfpar*sizeof(float));
+  ALLOCATE (par, opihi_flt, MAX (Npar, 1));
+  bzero (par, Npar*sizeof(opihi_flt));
+  ALLOCATE (fpar, opihi_flt, MAX (Nfpar, 1));
+  bzero (fpar, Nfpar*sizeof(opihi_flt));
 
   par[0] = get_variable_default ("Xg", 0);
@@ -40,8 +40,8 @@
 
 /* real 2D gaussian -- x, y, sx, sy, sxy, I, sky */
-float fgaussTD (float x, float y, float *par, int Npar, float *dpar) {
+opihi_flt fgaussTD (opihi_flt x, opihi_flt y, opihi_flt *par, int Npar, opihi_flt *dpar) {
 
-  float X, Y, px, py;
-  float z, r, q, f;
+  opihi_flt X, Y, px, py;
+  opihi_flt z, r, q, f;
 
   X = x - par[0];
Index: /trunk/Ohana/src/opihi/cmd.astro/imfit-pgauss-psf.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.astro/imfit-pgauss-psf.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.astro/imfit-pgauss-psf.c	(revision 20936)
@@ -1,5 +1,5 @@
 # include "imfit.h"
 
-float pgauss_psfTD (float, float, float *, int, float *);
+opihi_flt pgauss_psfTD (opihi_flt, opihi_flt, opihi_flt *, int, opihi_flt *);
 void  pgauss_psfCL ();
 
@@ -14,8 +14,8 @@
 
   /* allocate free and fixed parameters */
-  ALLOCATE (par, float, MAX (Npar, 1));
-  bzero (par, Npar*sizeof(float));
-  ALLOCATE (fpar, float, MAX (Nfpar, 1));
-  bzero (fpar, Nfpar*sizeof(float));
+  ALLOCATE (par, opihi_flt, MAX (Npar, 1));
+  bzero (par, Npar*sizeof(opihi_flt));
+  ALLOCATE (fpar, opihi_flt, MAX (Nfpar, 1));
+  bzero (fpar, Nfpar*sizeof(opihi_flt));
 
   par[0] = get_variable_default ("Xg", 0);
@@ -38,8 +38,8 @@
 
 /* pseudo 2D gaussian -- x, y, (sx), (sy), (sxy), I, sky */
-float pgauss_psfTD (float x, float y, float *par, int Npar, float *dpar) {
+opihi_flt pgauss_psfTD (opihi_flt x, opihi_flt y, opihi_flt *par, int Npar, opihi_flt *dpar) {
 
-  float X, Y, px, py;
-  float z, r, q, f;
+  opihi_flt X, Y, px, py;
+  opihi_flt z, r, q, f;
 
   /* par -> fpar: (2,0), (3,1), (4,2) */
Index: /trunk/Ohana/src/opihi/cmd.astro/imfit-pgauss.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.astro/imfit-pgauss.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.astro/imfit-pgauss.c	(revision 20936)
@@ -1,5 +1,5 @@
 # include "imfit.h"
 
-float pgaussTD (float, float, float *, int, float *);
+opihi_flt pgaussTD (opihi_flt, opihi_flt, opihi_flt *, int, opihi_flt *);
 void  pgaussCL ();
 
@@ -14,8 +14,8 @@
 
   /* allocate free and fixed parameters */
-  ALLOCATE (par, float, MAX (Npar, 1));
-  bzero (par, Npar*sizeof(float));
-  ALLOCATE (fpar, float, MAX (Nfpar, 1));
-  bzero (fpar, Nfpar*sizeof(float));
+  ALLOCATE (par, opihi_flt, MAX (Npar, 1));
+  bzero (par, Npar*sizeof(opihi_flt));
+  ALLOCATE (fpar, opihi_flt, MAX (Nfpar, 1));
+  bzero (fpar, Nfpar*sizeof(opihi_flt));
 
   par[0] = get_variable_default ("Xg", 0.0);
@@ -40,8 +40,8 @@
 
 /* pseudo 2D gaussian -- x, y, sx, sy, sxy, I, sky */
-float pgaussTD (float x, float y, float *par, int Npar, float *dpar) {
+opihi_flt pgaussTD (opihi_flt x, opihi_flt y, opihi_flt *par, int Npar, opihi_flt *dpar) {
 
-  float X, Y, px, py;
-  float z, r, q, f;
+  opihi_flt X, Y, px, py;
+  opihi_flt z, r, q, f;
 
   X = x - par[0];
Index: /trunk/Ohana/src/opihi/cmd.astro/imfit-qfgauss.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.astro/imfit-qfgauss.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.astro/imfit-qfgauss.c	(revision 20936)
@@ -1,5 +1,5 @@
 # include "imfit.h"
 
-float qfgaussTD (float, float, float *, int, float *);
+opihi_flt qfgaussTD (opihi_flt, opihi_flt, opihi_flt *, int, opihi_flt *);
 void  qfgaussCL ();
 
@@ -14,8 +14,8 @@
 
   /* allocate free and fixed parameters */
-  ALLOCATE (par, float, MAX (Npar, 1));
-  bzero (par, Npar*sizeof(float));
-  ALLOCATE (fpar, float, MAX (Nfpar, 1));
-  bzero (fpar, Nfpar*sizeof(float));
+  ALLOCATE (par, opihi_flt, MAX (Npar, 1));
+  bzero (par, Npar*sizeof(opihi_flt));
+  ALLOCATE (fpar, opihi_flt, MAX (Nfpar, 1));
+  bzero (fpar, Nfpar*sizeof(opihi_flt));
 
   par[0]  = get_variable_default ("Xg", 0);
@@ -44,8 +44,8 @@
 
 /* one component, two slopes: (1 + z^M + z^N)^(-1) -- x, y, sx, sy, sxy, I, sky */
-float qfgaussTD (float x, float y, float *par, int Npar, float *dpar) {
+opihi_flt qfgaussTD (opihi_flt x, opihi_flt y, opihi_flt *par, int Npar, opihi_flt *dpar) {
 
-  float X, Y, px, py;
-  float z, r, q, f;
+  opihi_flt X, Y, px, py;
+  opihi_flt z, r, q, f;
 
   X = x - par[0];
Index: /trunk/Ohana/src/opihi/cmd.astro/imfit-qgauss-psf.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.astro/imfit-qgauss-psf.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.astro/imfit-qgauss-psf.c	(revision 20936)
@@ -1,5 +1,5 @@
 # include "imfit.h"
 
-float qgauss_psfTD (float, float, float *, int, float *);
+opihi_flt qgauss_psfTD (opihi_flt, opihi_flt, opihi_flt *, int, opihi_flt *);
 void  qgauss_psfCL ();
 
@@ -14,8 +14,8 @@
 
   /* allocate free and fixed parameters */
-  ALLOCATE (par, float, MAX (Npar, 1));
-  bzero (par, Npar*sizeof(float));
-  ALLOCATE (fpar, float, MAX (Nfpar, 1));
-  bzero (fpar, Nfpar*sizeof(float));
+  ALLOCATE (par, opihi_flt, MAX (Npar, 1));
+  bzero (par, Npar*sizeof(opihi_flt));
+  ALLOCATE (fpar, opihi_flt, MAX (Nfpar, 1));
+  bzero (fpar, Nfpar*sizeof(opihi_flt));
 
   par[0]  = get_variable_default ("Xg", 0);
@@ -41,8 +41,8 @@
 
 /* one component, two slopes: (1 + z^M + z^N)^(-1) -- x, y, sx, sy, sxy, I, sky, sr */
-float qgauss_psfTD (float x, float y, float *par, int Npar, float *dpar) {
+opihi_flt qgauss_psfTD (opihi_flt x, opihi_flt y, opihi_flt *par, int Npar, opihi_flt *dpar) {
 
-  float X, Y, px, py;
-  float z, r, q, f;
+  opihi_flt X, Y, px, py;
+  opihi_flt z, r, q, f;
 
   X = x - par[0];
Index: /trunk/Ohana/src/opihi/cmd.astro/imfit-qgauss.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.astro/imfit-qgauss.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.astro/imfit-qgauss.c	(revision 20936)
@@ -1,5 +1,5 @@
 # include "imfit.h"
 
-float qgaussTD (float, float, float *, int, float *);
+opihi_flt qgaussTD (opihi_flt, opihi_flt, opihi_flt *, int, opihi_flt *);
 void  qgaussCL ();
 
@@ -14,8 +14,8 @@
 
   /* allocate free and fixed parameters */
-  ALLOCATE (par, float, MAX (Npar, 1));
-  bzero (par, Npar*sizeof(float));
-  ALLOCATE (fpar, float, MAX (Nfpar, 1));
-  bzero (fpar, Nfpar*sizeof(float));
+  ALLOCATE (par, opihi_flt, MAX (Npar, 1));
+  bzero (par, Npar*sizeof(opihi_flt));
+  ALLOCATE (fpar, opihi_flt, MAX (Nfpar, 1));
+  bzero (fpar, Nfpar*sizeof(opihi_flt));
 
   par[0]  = get_variable_default ("Xg", 0);
@@ -44,8 +44,8 @@
 
 /* one component, two slopes: (1 + z^M + z^N)^(-1) -- x, y, sx, sy, sxy, I, sky, sr */
-float qgaussTD (float x, float y, float *par, int Npar, float *dpar) {
+opihi_flt qgaussTD (opihi_flt x, opihi_flt y, opihi_flt *par, int Npar, opihi_flt *dpar) {
 
-  float X, Y, px, py;
-  float z, r, q, f;
+  opihi_flt X, Y, px, py;
+  opihi_flt z, r, q, f;
 
   X = x - par[0];
Index: /trunk/Ohana/src/opihi/cmd.astro/imfit-qrgauss.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.astro/imfit-qrgauss.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.astro/imfit-qrgauss.c	(revision 20936)
@@ -1,5 +1,5 @@
 # include "imfit.h"
 
-float qrgaussTD (float, float, float *, int, float *);
+opihi_flt qrgaussTD (opihi_flt, opihi_flt, opihi_flt *, int, opihi_flt *);
 void  qrgaussCL ();
 
@@ -14,8 +14,8 @@
 
   /* allocate free and fixed parameters */
-  ALLOCATE (par, float, MAX (Npar, 1));
-  bzero (par, Npar*sizeof(float));
-  ALLOCATE (fpar, float, MAX (Nfpar, 1));
-  bzero (fpar, Nfpar*sizeof(float));
+  ALLOCATE (par, opihi_flt, MAX (Npar, 1));
+  bzero (par, Npar*sizeof(opihi_flt));
+  ALLOCATE (fpar, opihi_flt, MAX (Nfpar, 1));
+  bzero (fpar, Nfpar*sizeof(opihi_flt));
 
   par[0]  = get_variable_default ("Xg", 0);
@@ -44,8 +44,8 @@
 }
 
-float qrgaussTD (float x, float y, float *par, int Npar, float *dpar) {
+opihi_flt qrgaussTD (opihi_flt x, opihi_flt y, opihi_flt *par, int Npar, opihi_flt *dpar) {
 
-  float X, Y, px, py;
-  float z, r, q, f;
+  opihi_flt X, Y, px, py;
+  opihi_flt z, r, q, f;
 
   X = x - par[0];
@@ -77,8 +77,8 @@
 # if (0)
 /* one component, two slopes: (1 + z^M + z^N)^(-1) -- x, y, sx, sy, sxy, I, sky, sr */
-float qrgaussTD (float x, float y, float *par, int Npar, float *dpar) {
+opihi_flt qrgaussTD (opihi_flt x, opihi_flt y, opihi_flt *par, int Npar, opihi_flt *dpar) {
 
-  float X, Y, px, py;
-  float z, r, q, f;
+  opihi_flt X, Y, px, py;
+  opihi_flt z, r, q, f;
 
   /* if (par[7] < 1.0) par[7] = 1.0; */
Index: /trunk/Ohana/src/opihi/cmd.astro/imfit-rgauss.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.astro/imfit-rgauss.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.astro/imfit-rgauss.c	(revision 20936)
@@ -1,5 +1,5 @@
 # include "imfit.h"
 
-float rgaussTD (float, float, float *, int, float *);
+opihi_flt rgaussTD (opihi_flt, opihi_flt, opihi_flt *, int, opihi_flt *);
 void  rgaussCL ();
 
@@ -14,8 +14,8 @@
 
   /* allocate free and fixed parameters */
-  ALLOCATE (par, float, MAX (Npar, 1));
-  bzero (par, Npar*sizeof(float));
-  ALLOCATE (fpar, float, MAX (Nfpar, 1));
-  bzero (fpar, Nfpar*sizeof(float));
+  ALLOCATE (par, opihi_flt, MAX (Npar, 1));
+  bzero (par, Npar*sizeof(opihi_flt));
+  ALLOCATE (fpar, opihi_flt, MAX (Nfpar, 1));
+  bzero (fpar, Nfpar*sizeof(opihi_flt));
 
   par[0] = get_variable_default ("Xg", 0);
@@ -36,8 +36,8 @@
 
 /* two components: (1 + z_1 + 0.5*z_1^2 + z_2^N)^(-1) -- x, y, sx1, sy1, sxy1, I, sky, sx2, sy2, sxy2 */
-float rgaussTD (float x, float y, float *par, int Npar, float *dpar) {
+opihi_flt rgaussTD (opihi_flt x, opihi_flt y, opihi_flt *par, int Npar, opihi_flt *dpar) {
 
-  float X, Y, px1, py1, px2, py2;
-  float z1, z2, r, q1, q2, f;
+  opihi_flt X, Y, px1, py1, px2, py2;
+  opihi_flt z1, z2, r, q1, q2, f;
 
   X = x - par[0];
Index: /trunk/Ohana/src/opihi/cmd.astro/imfit-serbulge.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.astro/imfit-serbulge.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.astro/imfit-serbulge.c	(revision 20936)
@@ -1,5 +1,5 @@
 # include "imfit.h"
 
-float serbulgeTD (float, float, float *, int, float *);
+opihi_flt serbulgeTD (opihi_flt, opihi_flt, opihi_flt *, int, opihi_flt *);
 void  serbulgeCL ();
 
@@ -14,8 +14,8 @@
 
   /* allocate free and fixed parameters */
-  ALLOCATE (par, float, MAX (Npar, 1));
-  bzero (par, Npar*sizeof(float));
-  ALLOCATE (fpar, float, MAX (Nfpar, 1));
-  bzero (fpar, Nfpar*sizeof(float));
+  ALLOCATE (par, opihi_flt, MAX (Npar, 1));
+  bzero (par, Npar*sizeof(opihi_flt));
+  ALLOCATE (fpar, opihi_flt, MAX (Nfpar, 1));
+  bzero (fpar, Nfpar*sizeof(opihi_flt));
 
   par[0] = get_variable_default ("Xg", 0);
@@ -41,8 +41,8 @@
 /* sersic galaxy model w/ bulge: -- x, y, (sx, sy, sxy)_1, I_1, sky, (sx, sy, sxy)_2, I_2, n */
 /* exp (-b (r/r_e)^(1/n)) + pgauss (r) */
-float serbulgeTD (float x, float y, float *par, int Npar, float *dpar) {
+opihi_flt serbulgeTD (opihi_flt x, opihi_flt y, opihi_flt *par, int Npar, opihi_flt *dpar) {
 
-  float X, Y, px1, px2, py1, py2;
-  float z1, z2, r1, r2, t, q1, q2, f;
+  opihi_flt X, Y, px1, px2, py1, py2;
+  opihi_flt z1, z2, r1, r2, t, q1, q2, f;
 
   X = x - par[0];
Index: /trunk/Ohana/src/opihi/cmd.astro/imfit-sersic.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.astro/imfit-sersic.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.astro/imfit-sersic.c	(revision 20936)
@@ -1,5 +1,5 @@
 # include "imfit.h"
 
-float sersicTD (float, float, float *, int, float *);
+opihi_flt sersicTD (opihi_flt, opihi_flt, opihi_flt *, int, opihi_flt *);
 void  sersicCL ();
 
@@ -14,8 +14,8 @@
 
   /* allocate free and fixed parameters */
-  ALLOCATE (par, float, MAX (Npar, 1));
-  bzero (par, Npar*sizeof(float));
-  ALLOCATE (fpar, float, MAX (Nfpar, 1));
-  bzero (fpar, Nfpar*sizeof(float));
+  ALLOCATE (par, opihi_flt, MAX (Npar, 1));
+  bzero (par, Npar*sizeof(opihi_flt));
+  ALLOCATE (fpar, opihi_flt, MAX (Nfpar, 1));
+  bzero (fpar, Nfpar*sizeof(opihi_flt));
 
   par[0] = get_variable_default ("Xg", 0);
@@ -33,8 +33,8 @@
 /* sersic galaxy model -- x, y, sx, sy, sxy, I, sky, n */
 /* exp (-b (r/r_e)^(1/n)) */
-float sersicTD (float x, float y, float *par, int Npar, float *dpar) {
+opihi_flt sersicTD (opihi_flt x, opihi_flt y, opihi_flt *par, int Npar, opihi_flt *dpar) {
 
-  float X, Y, px, py;
-  float z, r, t, q, f;
+  opihi_flt X, Y, px, py;
+  opihi_flt z, r, t, q, f;
 
   X = x - par[0];
Index: /trunk/Ohana/src/opihi/cmd.astro/imfit-sgauss-psf.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.astro/imfit-sgauss-psf.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.astro/imfit-sgauss-psf.c	(revision 20936)
@@ -1,5 +1,5 @@
 # include "imfit.h"
 
-float sgauss_psfTD (float, float, float *, int, float *);
+opihi_flt sgauss_psfTD (opihi_flt, opihi_flt, opihi_flt *, int, opihi_flt *);
 void  sgauss_psfCL ();
 
@@ -14,8 +14,8 @@
 
   /* allocate free and fixed parameters */
-  ALLOCATE (par, float, MAX (Npar, 1));
-  bzero (par, Npar*sizeof(float));
-  ALLOCATE (fpar, float, MAX (Nfpar, 1));
-  bzero (fpar, Nfpar*sizeof(float));
+  ALLOCATE (par, opihi_flt, MAX (Npar, 1));
+  bzero (par, Npar*sizeof(opihi_flt));
+  ALLOCATE (fpar, opihi_flt, MAX (Nfpar, 1));
+  bzero (fpar, Nfpar*sizeof(opihi_flt));
 
   par[0] = get_variable_default ("Xg", 0);
@@ -43,8 +43,8 @@
 
 /* two components: (1 + z_1 + z_2^N)^(-1) -- x, y, sx1, sy1, sxy1, I, sky, sx2, sy2, sxy2 */
-float sgauss_psfTD (float x, float y, float *par, int Npar, float *dpar) {
+opihi_flt sgauss_psfTD (opihi_flt x, opihi_flt y, opihi_flt *par, int Npar, opihi_flt *dpar) {
 
-  float X, Y, px1, py1, px2, py2;
-  float z1, z2, r, q1, q2, f;
+  opihi_flt X, Y, px1, py1, px2, py2;
+  opihi_flt z1, z2, r, q1, q2, f;
 
   X = x - par[0];
Index: /trunk/Ohana/src/opihi/cmd.astro/imfit-sgauss.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.astro/imfit-sgauss.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.astro/imfit-sgauss.c	(revision 20936)
@@ -3,5 +3,5 @@
 # define FSCALE 1.2
 
-float sgaussTD (float, float, float *, int, float *);
+opihi_flt sgaussTD (opihi_flt, opihi_flt, opihi_flt *, int, opihi_flt *);
 void  sgaussCL ();
 
@@ -16,8 +16,8 @@
 
   /* allocate free and fixed parameters */
-  ALLOCATE (par, float, MAX (Npar, 1));
-  bzero (par, Npar*sizeof(float));
-  ALLOCATE (fpar, float, MAX (Nfpar, 1));
-  bzero (fpar, Nfpar*sizeof(float));
+  ALLOCATE (par, opihi_flt, MAX (Npar, 1));
+  bzero (par, Npar*sizeof(opihi_flt));
+  ALLOCATE (fpar, opihi_flt, MAX (Nfpar, 1));
+  bzero (fpar, Nfpar*sizeof(opihi_flt));
 
   par[0] = get_variable_default ("Xg", 0);
@@ -52,8 +52,8 @@
 
 /* two components: (1 + z_1 + z_2^N)^(-1) -- x, y, sx1, sy1, sxy1, I, sky, sx2, sy2, sxy2 */
-float sgaussTD (float x, float y, float *par, int Npar, float *dpar) {
+opihi_flt sgaussTD (opihi_flt x, opihi_flt y, opihi_flt *par, int Npar, opihi_flt *dpar) {
 
-  float X, Y, px1, py1, px2, py2;
-  float z1, z2, r, q1, q2, f, f1, f2;
+  opihi_flt X, Y, px1, py1, px2, py2;
+  opihi_flt z1, z2, r, q1, q2, f, f1, f2;
 
   X = x - par[0];
Index: /trunk/Ohana/src/opihi/cmd.astro/imfit-tgauss.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.astro/imfit-tgauss.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.astro/imfit-tgauss.c	(revision 20936)
@@ -1,5 +1,5 @@
 # include "imfit.h"
 
-float tgaussTD (float, float, float *, int, float *);
+opihi_flt tgaussTD (opihi_flt, opihi_flt, opihi_flt *, int, opihi_flt *);
 void  tgaussCL ();
 
@@ -31,8 +31,8 @@
 
 /* two components: (1 + z_1^M + z_2^N)^(-1) -- x, y, sx1, sy1, sxy1, I, sky, sx2, sy2, sxy2 */
-float tgaussTD (float x, float y, float *par, int Npar, float *dpar) {
+opihi_flt tgaussTD (opihi_flt x, opihi_flt y, opihi_flt *par, int Npar, opihi_flt *dpar) {
 
-  float X, Y, px1, py1, px2, py2;
-  float z1, z2, r, q1, q2, f;
+  opihi_flt X, Y, px1, py1, px2, py2;
+  opihi_flt z1, z2, r, q1, q2, f;
 
   X = x - par[0];
Index: /trunk/Ohana/src/opihi/cmd.astro/imfit-vgauss.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.astro/imfit-vgauss.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.astro/imfit-vgauss.c	(revision 20936)
@@ -1,5 +1,5 @@
 # include "imfit.h"
 
-float vgaussTD (float, float, float *, int, float *);
+opihi_flt vgaussTD (opihi_flt, opihi_flt, opihi_flt *, int, opihi_flt *);
 void  vgaussCL ();
 
@@ -25,9 +25,9 @@
 }
 
-/* pseudo 2D gaussian with floating 2nd and 3rd order terms -- x, y, sx, sy, sxy, I, sky, f1, f2 */
-float vgaussTD (float x, float y, float *par, int Npar, float *dpar) {
+/* pseudo 2D gaussian with opihi_flting 2nd and 3rd order terms -- x, y, sx, sy, sxy, I, sky, f1, f2 */
+opihi_flt vgaussTD (opihi_flt x, opihi_flt y, opihi_flt *par, int Npar, opihi_flt *dpar) {
 
-  float X, Y, px, py;
-  float z, r, q, f, k;
+  opihi_flt X, Y, px, py;
+  opihi_flt z, r, q, f, k;
 
   X = x - par[0];
Index: /trunk/Ohana/src/opihi/cmd.astro/imfit.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.astro/imfit.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.astro/imfit.c	(revision 20936)
@@ -6,5 +6,6 @@
   int sx, sy, nx, ny, Nx, Ny;
   float chisq, ochisq, dchisq, Gain, RDnoise, SatThreshold;
-  float *x, *y, *z, *dz, *V;
+  opihi_flt *x, *y, *z, *dz;
+  float *V;
   Buffer *buf;
 
@@ -94,8 +95,8 @@
   N = 0;
   Npts = nx*ny;
-  ALLOCATE (x,  float, 2*Npts);
-  ALLOCATE (y,  float, 2*Npts);
-  ALLOCATE (z,  float, 2*Npts);
-  ALLOCATE (dz, float, 2*Npts);
+  ALLOCATE (x,  opihi_flt, 2*Npts);
+  ALLOCATE (y,  opihi_flt, 2*Npts);
+  ALLOCATE (z,  opihi_flt, 2*Npts);
+  ALLOCATE (dz, opihi_flt, 2*Npts);
   for (j = 0; j < ny; j++) {
     if (j + sy < 0) continue;
Index: /trunk/Ohana/src/opihi/cmd.astro/multifit.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.astro/multifit.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.astro/multifit.c	(revision 20936)
@@ -46,18 +46,25 @@
     sprintf (name, "c%d", i);
     if ((Nc[i]  = SelectVector (name, ANYVECTOR, TRUE)) == NULL) goto escape;
+    ResetVector (Nc[i], OPIHI_FLT, 1); 
     sprintf (name, "Mb%d", i);
     if ((NMb[i] = SelectVector (name, OLDVECTOR, TRUE)) == NULL) goto escape;
+    REQUIRE_VECTOR_FLT (NMb[i], FALSE); 
     sprintf (name, "mb%d", i);
     if ((Nmb[i] = SelectVector (name, OLDVECTOR, TRUE)) == NULL) goto escape;
+    REQUIRE_VECTOR_FLT (Nmb[i], FALSE); 
     sprintf (name, "wb%d", i);
     if ((Nwb[i] = SelectVector (name, OLDVECTOR, TRUE)) == NULL) goto escape;
+    REQUIRE_VECTOR_FLT (Nwb[i], FALSE); 
   }
   for (i = 0; i < Norder - 1; i++) {
     sprintf (name, "ml%d", i);
     if ((Nml[i] = SelectVector (name, OLDVECTOR, TRUE)) == NULL) goto escape;
+    REQUIRE_VECTOR_FLT (Nml[i], FALSE); 
     sprintf (name, "mh%d", i);
     if ((Nmh[i] = SelectVector (name, OLDVECTOR, TRUE)) == NULL) goto escape;
+    REQUIRE_VECTOR_FLT (Nmh[i], FALSE); 
     sprintf (name, "wo%d", i);
     if ((Nwo[i] = SelectVector (name, OLDVECTOR, TRUE)) == NULL) goto escape;
+    REQUIRE_VECTOR_FLT (Nwo[i], FALSE); 
   }
 
@@ -72,5 +79,5 @@
 	    v = 0;
 	    for (n = 0; n < Nwo[i-1][0].Nelements; n++) {
-	      v += -pow (Nwo[i-1][0].elements[n], (double)(j+J));
+	      v += -pow (Nwo[i-1][0].elements.Flt[n], (double)(j+J));
 	    }
 	    a[Ny][Nx] = v;
@@ -83,5 +90,5 @@
 	    v = 0;
 	    for (n = 0; n < Nwo[i][0].Nelements; n++) {
-	      v += -pow (Nwo[i][0].elements[n], (double)(j+J));
+	      v += -pow (Nwo[i][0].elements.Flt[n], (double)(j+J));
 	    }
 	    a[Ny][Nx] = v;
@@ -94,14 +101,14 @@
 	    v = 0;
 	    for (n = 0; n < Nwb[i][0].Nelements; n++) {
-	      v += pow (Nwb[i][0].elements[n], (double)(j+J));
+	      v += pow (Nwb[i][0].elements.Flt[n], (double)(j+J));
 	    }
 	    if (i > 0) {
 	      for (n = 0; n < Nwo[i-1][0].Nelements; n++) {
-		v += pow (Nwo[i-1][0].elements[n], (double)(j+J));
+		v += pow (Nwo[i-1][0].elements.Flt[n], (double)(j+J));
 	      }
 	    }
 	    if (i < Norder - 1) {
 	      for (n = 0; n < Nwo[i][0].Nelements; n++) {
-		v += pow (Nwo[i][0].elements[n], (double)(j+J));
+		v += pow (Nwo[i][0].elements.Flt[n], (double)(j+J));
 	      }
 	    }
@@ -123,17 +130,17 @@
       v = 0;
       for (n = 0; n < Nwb[i][0].Nelements; n++) {
-	v += NMb[i][0].elements[n]*pow (Nwb[i][0].elements[n], (double)j);
-	v -= Nmb[i][0].elements[n]*pow (Nwb[i][0].elements[n], (double)j);
+	v += NMb[i][0].elements.Flt[n]*pow (Nwb[i][0].elements.Flt[n], (double)j);
+	v -= Nmb[i][0].elements.Flt[n]*pow (Nwb[i][0].elements.Flt[n], (double)j);
       }
       if (i > 0) {
 	for (n = 0; n < Nwo[i-1][0].Nelements; n++) {
-	  v += Nmh[i-1][0].elements[n] * pow (Nwo[i-1][0].elements[n], (double)j);
-	  v -= Nml[i-1][0].elements[n] * pow (Nwo[i-1][0].elements[n], (double)j);
+	  v += Nmh[i-1][0].elements.Flt[n] * pow (Nwo[i-1][0].elements.Flt[n], (double)j);
+	  v -= Nml[i-1][0].elements.Flt[n] * pow (Nwo[i-1][0].elements.Flt[n], (double)j);
 	}
       }
       if (i < Norder - 1) {
 	for (n = 0; n < Nwo[i][0].Nelements; n++) {
-	  v += Nml[i][0].elements[n] * pow (Nwo[i][0].elements[n], (double)j);
-	  v -= Nmh[i][0].elements[n] * pow (Nwo[i][0].elements[n], (double)j);
+	  v += Nml[i][0].elements.Flt[n] * pow (Nwo[i][0].elements.Flt[n], (double)j);
+	  v -= Nmh[i][0].elements.Flt[n] * pow (Nwo[i][0].elements.Flt[n], (double)j);
 	}
       }
@@ -146,7 +153,7 @@
   for (i = 0; i < Norder; i++) {
     Nc[i][0].Nelements = nterm[i];
-    REALLOCATE (Nc[i][0].elements, float, nterm[i]);
+    REALLOCATE (Nc[i][0].elements.Flt, opihi_flt, nterm[i]);
     for (j = 0; j < nterm[i]; j++, Ny++) {
-      Nc[i][0].elements[j] = b[Ny][0];
+      Nc[i][0].elements.Flt[j] = b[Ny][0];
     }
   }
Index: /trunk/Ohana/src/opihi/cmd.astro/precess.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.astro/precess.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.astro/precess.c	(revision 20936)
@@ -90,7 +90,14 @@
   }
   
-  for (i = 0; i < xvec[0].Nelements; i++) {
-    A = xvec[0].elements[i];
-    D = yvec[0].elements[i];
+  // cast xvec or yvec to FLT if it is type INT
+  CastVector (xvec, OPIHI_FLT);
+  CastVector (yvec, OPIHI_FLT);
+
+  opihi_flt *Av = xvec[0].elements.Flt;
+  opihi_flt *Dv = yvec[0].elements.Flt;
+
+  for (i = 0; i < xvec[0].Nelements; i++, Av, Dv) {
+    A = *Av;
+    D = *Dv;
     SD =  cos(RAD_DEG*A + zeta)*sin(theta)*cos(RAD_DEG*D) + cos(theta)*sin(RAD_DEG*D);
     CD = sqrt (1 - SD*SD);
@@ -101,9 +108,8 @@
     RA  = DEG_RAD*atan2(SA, CA) + z;
 
-    if (RA < 0)
-      RA += 360;
+    if (RA < 0) RA += 360;
     
-    xvec[0].elements[i] = RA;
-    yvec[0].elements[i] = DEC; 
+    *Av = RA;
+    *Dv = DEC; 
   }
 
Index: /trunk/Ohana/src/opihi/cmd.astro/profile.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.astro/profile.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.astro/profile.c	(revision 20936)
@@ -28,8 +28,8 @@
   if ((yvec = SelectVector (argv[3], ANYVECTOR, TRUE)) == NULL) return (FALSE);
 
-  xvec[0].Nelements = yvec[0].Nelements = (int)SQ(2*N+1);
-  REALLOCATE (xvec[0].elements, float, 5*(int)SQ(2*N+1));
-  REALLOCATE (yvec[0].elements, float, 5*(int)SQ(2*N+1));
-  bzero (yvec[0].elements, (int)SQ(2*N+1)*sizeof(float)+1);
+  ResetVector (xvec, OPIHI_FLT, (int)SQ(2*N+1));
+  ResetVector (yvec, OPIHI_FLT, (int)SQ(2*N+1));
+
+  bzero (yvec[0].elements.Flt, (int)SQ(2*N+1)*sizeof(opihi_flt)+1);
   V = (float *)(buf[0].matrix.buffer); 
   Npt = 0;
@@ -37,10 +37,10 @@
   for (i = sx - N; i < sx + N; i++) {
     for (j = sy - N; j < sy + N; j++, Npt++) {
-      yvec[0].elements[Npt] = V[i + j*Nx];
-      xvec[0].elements[Npt] = hypot (i - sx, j - sy);
+      yvec[0].elements.Flt[Npt] = V[i + j*Nx];
+      xvec[0].elements.Flt[Npt] = hypot (i - sx, j - sy);
     }
   }
 
-  fsortpair (xvec[0].elements, yvec[0].elements, xvec[0].Nelements);
+  dsortpair (xvec[0].elements.Flt, yvec[0].elements.Flt, xvec[0].Nelements);
 
   return (TRUE);
Index: /trunk/Ohana/src/opihi/cmd.astro/spec.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.astro/spec.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.astro/spec.c	(revision 20936)
@@ -55,8 +55,6 @@
 
   N = y2 - y1;
-  REALLOCATE (xvec[0].elements, float, N);
-  REALLOCATE (yvec[0].elements, float, N);
-  xvec[0].Nelements = N;
-  yvec[0].Nelements = N;
+  ResetVector (xvec, OPIHI_FLT, N);
+  ResetVector (yvec, OPIHI_FLT, N);
   
   ALLOCATE (buffer, float, Nlong);
@@ -103,6 +101,6 @@
       R += 1.0 / sky2;
     }
-    xvec[0].elements[j] = j + y1; 
-    yvec[0].elements[j] = F / R; 
+    xvec[0].elements.Flt[j] = j + y1; 
+    yvec[0].elements.Flt[j] = F / R; 
     gprint (GP_ERR, " %5.1f %7.1f  %6.2f\n", sky, sky2, (F/R));
   }    
Index: /trunk/Ohana/src/opihi/cmd.basic/test/sprintf.sh
===================================================================
--- /trunk/Ohana/src/opihi/cmd.basic/test/sprintf.sh	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.basic/test/sprintf.sh	(revision 20936)
@@ -35,5 +35,5 @@
  $PASS = 1
 
- if ($endmem - $startmem > 10)
+ if (($endmem - $startmem)/10000 > 1.0)
    $PASS = 0
    echo "growth: {$endmem-$startmem}"
Index: /trunk/Ohana/src/opihi/cmd.data/accum.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/accum.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/accum.c	(revision 20936)
@@ -5,5 +5,6 @@
   int i, Nbins, bin, N, Normalize;
   float start, end, delta;
-  float *V, *K, *O, *NV;
+  int *NV;
+  opihi_flt *V, *K, *O;
   Vector *val, *key, *out;
 
@@ -29,4 +30,7 @@
   if ((out = SelectVector (argv[2], ANYVECTOR, TRUE)) == NULL) return (FALSE);
 
+  REQUIRE_VECTOR_FLT (val, FALSE); 
+  REQUIRE_VECTOR_FLT (key, FALSE); 
+
   start = atof (argv[4]);
   end   = atof (argv[5]);
@@ -45,15 +49,14 @@
   Nbins = (end - start) / delta;
 
-  out[0].Nelements = Nbins;
-  REALLOCATE (out[0].elements, float, out[0].Nelements);
-  bzero (out[0].elements, sizeof(float)*out[0].Nelements);
+  ResetVector (out, OPIHI_FLT, Nbins);
+  bzero (out[0].elements.Flt, sizeof(opihi_flt)*out[0].Nelements);
   if (Normalize) {
-    ALLOCATE (NV, float, Nbins);
-    bzero (NV, sizeof(float)*Nbins);
+    ALLOCATE (NV, int, Nbins);
+    bzero (NV, sizeof(int)*Nbins);
   }
 
-  V = val[0].elements;
-  K = key[0].elements;
-  O = out[0].elements;
+  V = val[0].elements.Flt;
+  K = key[0].elements.Flt;
+  O = out[0].elements.Flt;
 
   for (i = 0; i < val[0].Nelements; i++, V++, K++) {
Index: /trunk/Ohana/src/opihi/cmd.data/applyfit.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/applyfit.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/applyfit.c	(revision 20936)
@@ -1,5 +1,3 @@
 # include "data.h"
-
-char *get_variable (char *);
 
 int applyfit (int argc, char **argv) {
@@ -8,5 +6,5 @@
   char *c, name[64];
   double *C, X;
-  float *x, *y;
+  opihi_flt *y;
   Vector *xvec, *yvec;
 
@@ -38,15 +36,26 @@
     free (c);
   }
-  yvec[0].Nelements = xvec[0].Nelements;
-  REALLOCATE (yvec[0].elements, float, yvec[0].Nelements);
-  bzero (yvec[0].elements, sizeof(float)*yvec[0].Nelements);
-  x = xvec[0].elements;
-  y = yvec[0].elements;
 
-  for (j = 0; j < xvec[0].Nelements; j++, x++, y++) {
-    X = 1;
-    for (i = 0; i < order + 1; i++) {
-      *y += C[i]*X;
-      X = X * (*x);
+  ResetVector (yvec, OPIHI_FLT, xvec[0].Nelements);
+  bzero (yvec[0].elements.Flt, sizeof(opihi_flt)*yvec[0].Nelements);
+  y = yvec[0].elements.Flt;
+
+  if (xvec[0].type == OPIHI_FLT) {
+    opihi_flt *x = xvec[0].elements.Flt;
+    for (j = 0; j < xvec[0].Nelements; j++, x++, y++) {
+      X = 1;
+      for (i = 0; i < order + 1; i++) {
+	*y += C[i]*X;
+	X = X * (*x);
+      }
+    }
+  } else {
+    opihi_int *x = xvec[0].elements.Int;
+    for (j = 0; j < xvec[0].Nelements; j++, x++, y++) {
+      X = 1;
+      for (i = 0; i < order + 1; i++) {
+	*y += C[i]*X;
+	X = X * (*x);
+      }
     }
   }
Index: /trunk/Ohana/src/opihi/cmd.data/applyfit2d.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/applyfit2d.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/applyfit2d.c	(revision 20936)
@@ -1,5 +1,3 @@
 # include "data.h"
-
-char *get_variable (char *);
 
 int applyfit2d (int argc, char **argv) {
@@ -8,5 +6,5 @@
   char *c, name[64];
   double **C, X, Y;
-  float *x, *y, *z;
+  opihi_flt *z;
   Vector *xvec, *yvec, *zvec;
 
@@ -45,22 +43,70 @@
   }
 
-  zvec[0].Nelements = xvec[0].Nelements;
-  REALLOCATE (zvec[0].elements, float, zvec[0].Nelements);
-  bzero (zvec[0].elements, sizeof(float)*zvec[0].Nelements);
-  x = xvec[0].elements;
-  y = yvec[0].elements;
-  z = zvec[0].elements;
+  ResetVector (zvec, OPIHI_FLT, xvec[0].Nelements);
+  bzero (zvec[0].elements.Flt, sizeof(opihi_flt)*zvec[0].Nelements);
+  z = zvec[0].elements.Flt;
 
-  for (n = 0; n < xvec[0].Nelements; n++, x++, y++, z++) {
-    Y = X = 1;
-    for (j = 0; j < order + 1; j++) {
-      X = Y;
-      for (i = 0; i < order + 1 - j; i++) {
-	*z += C[i][j]*X;
-	X = X * (*x);
+  // we have four cases (x == flt or int) and (y == flt or int)
+  if ((xvec[0].type == OPIHI_FLT) && (yvec[0].type == OPIHI_FLT)) {
+    opihi_flt *x = xvec[0].elements.Flt;
+    opihi_flt *y = yvec[0].elements.Flt;
+    for (n = 0; n < xvec[0].Nelements; n++, x++, y++, z++) {
+      Y = X = 1;
+      for (j = 0; j < order + 1; j++) {
+	X = Y;
+	for (i = 0; i < order + 1 - j; i++) {
+	  *z += C[i][j]*X;
+	  X = X * (*x);
+	}
+	Y = Y * (*y);
       }
-      Y = Y * (*y);
     }
   }
+  if ((xvec[0].type == OPIHI_FLT) && (yvec[0].type == OPIHI_INT)) {
+    opihi_flt *x = xvec[0].elements.Flt;
+    opihi_int *y = yvec[0].elements.Int;
+    for (n = 0; n < xvec[0].Nelements; n++, x++, y++, z++) {
+      Y = X = 1;
+      for (j = 0; j < order + 1; j++) {
+	X = Y;
+	for (i = 0; i < order + 1 - j; i++) {
+	  *z += C[i][j]*X;
+	  X = X * (*x);
+	}
+	Y = Y * (*y);
+      }
+    }
+  }
+  if ((xvec[0].type == OPIHI_INT) && (yvec[0].type == OPIHI_FLT)) {
+    opihi_int *x = xvec[0].elements.Int;
+    opihi_flt *y = yvec[0].elements.Flt;
+    for (n = 0; n < xvec[0].Nelements; n++, x++, y++, z++) {
+      Y = X = 1;
+      for (j = 0; j < order + 1; j++) {
+	X = Y;
+	for (i = 0; i < order + 1 - j; i++) {
+	  *z += C[i][j]*X;
+	  X = X * (*x);
+	}
+	Y = Y * (*y);
+      }
+    }
+  }
+  if ((xvec[0].type == OPIHI_INT) && (yvec[0].type == OPIHI_INT)) {
+    opihi_int *x = xvec[0].elements.Int;
+    opihi_int *y = yvec[0].elements.Int;
+    for (n = 0; n < xvec[0].Nelements; n++, x++, y++, z++) {
+      Y = X = 1;
+      for (j = 0; j < order + 1; j++) {
+	X = Y;
+	for (i = 0; i < order + 1 - j; i++) {
+	  *z += C[i][j]*X;
+	  X = X * (*x);
+	}
+	Y = Y * (*y);
+      }
+    }
+  }
+
   for (i = 0; i < order + 1; i++) free (C[i]);
   free (C);
Index: /trunk/Ohana/src/opihi/cmd.data/concat.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/concat.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/concat.c	(revision 20936)
@@ -5,4 +5,5 @@
   int  i, j, Nin;
   double value;
+  opihi_flt *temp;
   Vector *ivec, *ovec;
 
@@ -19,6 +20,11 @@
     Nin = ovec[0].Nelements;
     ovec[0].Nelements++;
-    REALLOCATE (ovec[0].elements, float, ovec[0].Nelements);
-    ovec[0].elements[Nin] = value;
+    if (ovec[0].type == OPIHI_FLT) {
+      REALLOCATE (ovec[0].elements.Flt, opihi_flt, ovec[0].Nelements);
+      ovec[0].elements.Flt[Nin] = value;
+    } else {
+      REALLOCATE (ovec[0].elements.Int, opihi_int, ovec[0].Nelements);
+      ovec[0].elements.Int[Nin] = value;
+    }
     return (TRUE);
   } 
@@ -26,11 +32,39 @@
   if ((ivec = SelectVector (argv[1], OLDVECTOR, TRUE)) == NULL) return (FALSE);
   
-  REALLOCATE (ovec[0].elements, float, ovec[0].Nelements + ivec[0].Nelements);
-  for (j = ovec[0].Nelements, i = 0; i < ivec[0].Nelements; i++, j++) {
-    ovec[0].elements[j] = ivec[0].elements[i];
+  // we have 4 cases: (ivec == flt or int) and (ovec == flt or int)
+  if ((ovec[0].type == OPIHI_FLT) && (ivec[0].type == OPIHI_FLT)) {
+    REALLOCATE (ovec[0].elements.Flt, opihi_flt, ovec[0].Nelements + ivec[0].Nelements);
+    for (j = ovec[0].Nelements, i = 0; i < ivec[0].Nelements; i++, j++) {
+      ovec[0].elements.Flt[j] = ivec[0].elements.Flt[i];
+    }
   }
+  if ((ovec[0].type == OPIHI_FLT) && (ivec[0].type == OPIHI_INT)) {
+    REALLOCATE (ovec[0].elements.Flt, opihi_flt, ovec[0].Nelements + ivec[0].Nelements);
+    for (j = ovec[0].Nelements, i = 0; i < ivec[0].Nelements; i++, j++) {
+      ovec[0].elements.Flt[j] = ivec[0].elements.Int[i];
+    }
+  }
+  if ((ovec[0].type == OPIHI_INT) && (ivec[0].type == OPIHI_INT)) {
+    REALLOCATE (ovec[0].elements.Int, opihi_int, ovec[0].Nelements + ivec[0].Nelements);
+    for (j = ovec[0].Nelements, i = 0; i < ivec[0].Nelements; i++, j++) {
+      ovec[0].elements.Int[j] = ivec[0].elements.Int[i];
+    }
+  }
+
+  // this case forces ovec to be raised to FLT
+  if ((ovec[0].type == OPIHI_INT) && (ivec[0].type == OPIHI_FLT)) {
+    ALLOCATE (temp, opihi_flt, ovec[0].Nelements + ivec[0].Nelements);
+    for (i = 0; i < ovec[0].Nelements; i++) {
+      temp[i] = ovec[0].elements.Int[i];
+    }
+    ovec[0].type = OPIHI_FLT;
+    free (ovec[0].elements.Int);
+    ovec[0].elements.Flt = temp;
+    for (j = ovec[0].Nelements, i = 0; i < ivec[0].Nelements; i++, j++) {
+      ovec[0].elements.Flt[j] = ivec[0].elements.Flt[i];
+    }
+  }
+
   ovec[0].Nelements += ivec[0].Nelements;
-  
   return (TRUE);
-    
 }
Index: /trunk/Ohana/src/opihi/cmd.data/contour.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/contour.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/contour.c	(revision 20936)
@@ -44,11 +44,10 @@
 int N, NVEC;
 
-void DUMP (float x, float y, float dx, float dy) {
-  
-  xv[0].elements[N]   = x;
-  xv[0].elements[N+1] = x+dx;
-  
-  yv[0].elements[N]   = y;
-  yv[0].elements[N+1] = y+dy;
+void DUMP (opihi_flt x, opihi_flt y, opihi_flt dx, opihi_flt dy) {
+  
+  xv[0].elements.Flt[N]   = x;
+  xv[0].elements.Flt[N+1] = x+dx;
+  yv[0].elements.Flt[N]   = y;
+  yv[0].elements.Flt[N+1] = y+dy;
   
   N+=2;
@@ -56,6 +55,6 @@
   if (N >= NVEC - 2) {
     NVEC += 100;
-    REALLOCATE (xv[0].elements, float, NVEC);
-    REALLOCATE (yv[0].elements, float, NVEC);
+    REALLOCATE (xv[0].elements.Flt, opihi_flt, NVEC);
+    REALLOCATE (yv[0].elements.Flt, opihi_flt, NVEC);
   }
 }
@@ -64,6 +63,6 @@
 
   int i, j, Nx, Ny;
+  opihi_flt x, y, dx, dy;
   float level, d00, d01, d10, d11, tmp;
-  float x, y, dx, dy;
   float *v00, *v01, *v10, *v11;
   float *matrix;
@@ -93,6 +92,6 @@
   N = 0;
   NVEC = 100;
-  REALLOCATE (xv[0].elements, float, NVEC);
-  REALLOCATE (yv[0].elements, float, NVEC);
+  ResetVector (xv, OPIHI_FLT, NVEC);
+  ResetVector (yv, OPIHI_FLT, NVEC);
 
   for (j = 1; j < Ny; j++) {
Index: /trunk/Ohana/src/opihi/cmd.data/create.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/create.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/create.c	(revision 20936)
@@ -3,8 +3,14 @@
 int create (int argc, char **argv) {
   
-  int i;
+  int i, N, INT;
   float start, end, delta;
   Vector *vec;
   
+  INT = FALSE;
+  if ((N = get_argument (argc, argv, "-int"))) {
+    INT = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+
   if ((argc != 5) && (argc != 4)) {
     gprint (GP_ERR, "USAGE: create vector start end [delta]\n");
@@ -27,9 +33,23 @@
   }
 
+  if (INT && (delta != (int)delta)) {
+    gprint (GP_ERR, "integer vector requested but fractional step-size specified\n");
+    return (FALSE);
+  }
+
   vec[0].Nelements = (end - start) / delta;
-  REALLOCATE (vec[0].elements, float, vec[0].Nelements);
 
-  for (i = 0; i < vec[0].Nelements; i++) {
-    vec[0].elements[i] = start + i*delta;
+  if (INT) {
+    vec[0].type = OPIHI_INT;
+    REALLOCATE (vec[0].elements.Int, opihi_int, vec[0].Nelements);
+    for (i = 0; i < vec[0].Nelements; i++) {
+      vec[0].elements.Int[i] = start + i*delta;
+    }
+  } else {
+    vec[0].type = OPIHI_FLT;
+    REALLOCATE (vec[0].elements.Flt, opihi_flt, vec[0].Nelements);
+    for (i = 0; i < vec[0].Nelements; i++) {
+      vec[0].elements.Flt[i] = start + i*delta;
+    }
   }
 
Index: /trunk/Ohana/src/opihi/cmd.data/cumulative.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/cumulative.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/cumulative.c	(revision 20936)
@@ -4,5 +4,5 @@
   
   int i;
-  float *Vi, *Vo;
+  opihi_flt *Vo;
   Vector *ivec, *ovec;
 
@@ -14,15 +14,23 @@
   if ((ivec = SelectVector (argv[1], OLDVECTOR, TRUE)) == NULL) return (FALSE);
   if ((ovec = SelectVector (argv[2], ANYVECTOR, TRUE)) == NULL) return (FALSE);
-  ovec[0].Nelements = ivec[0].Nelements;
-    
-  REALLOCATE (ovec[0].elements, float, ovec[0].Nelements);
-  bzero (ovec[0].elements, sizeof(float)*ovec[0].Nelements);
 
-  Vi = ivec[0].elements;
-  Vo = ovec[0].elements;
-  *Vo = *Vi;
-  for (i = 1; i < ivec[0].Nelements; i++, Vi++, Vo++) {
-    *Vo = Vo[-1] + *Vi;
-  }      
+  ResetVector (ovec, OPIHI_FLT, ivec[0].Nelements);
+  bzero (ovec[0].elements.Flt, sizeof(opihi_flt)*ovec[0].Nelements);
+
+  Vo = ovec[0].elements.Flt;
+
+  if (ivec[0].type == OPIHI_FLT) {
+    opihi_flt *Vi = ivec[0].elements.Flt;
+    *Vo = *Vi;
+    for (i = 1; i < ivec[0].Nelements; i++, Vi++, Vo++) {
+      *Vo = Vo[-1] + *Vi;
+    }      
+  } else {
+    opihi_int *Vi = ivec[0].elements.Int;
+    *Vo = *Vi;
+    for (i = 1; i < ivec[0].Nelements; i++, Vi++, Vo++) {
+      *Vo = Vo[-1] + *Vi;
+    }      
+  }
   return (TRUE);
 }
Index: /trunk/Ohana/src/opihi/cmd.data/cut.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/cut.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/cut.c	(revision 20936)
@@ -48,10 +48,9 @@
   case 'X':
     /* create output vectors */
-    xvec[0].Nelements = yvec[0].Nelements = nx;
-    REALLOCATE (xvec[0].elements, float, MAX (nx, 1));
-    REALLOCATE (yvec[0].elements, float, MAX (nx, 1));
-    bzero (yvec[0].elements, nx*sizeof(float));
+    ResetVector (xvec, OPIHI_FLT, MAX (nx, 1));
+    ResetVector (yvec, OPIHI_FLT, MAX (nx, 1));
+    bzero (yvec[0].elements.Flt, nx*sizeof(opihi_flt));
     for (i = 0; i < nx; i++) {
-      xvec[0].elements[i] = i + sx; 
+      xvec[0].elements.Flt[i] = i + sx; 
     }
     ALLOCATE (Vbuf, float, MAX (ny, 1));
@@ -74,5 +73,5 @@
 	if (Mode == MEAN) { value /= ny; }
       }
-      yvec[0].elements[i] = value;
+      yvec[0].elements.Flt[i] = value;
     }
     free (Vbuf);
@@ -81,10 +80,9 @@
   case 'y':
   case 'Y':
-    xvec[0].Nelements = yvec[0].Nelements = ny;
-    REALLOCATE (xvec[0].elements, float, ny);
-    REALLOCATE (yvec[0].elements, float, ny);
-    bzero (yvec[0].elements, ny*sizeof(float));
+    ResetVector (xvec, OPIHI_FLT, MAX (ny, 1));
+    ResetVector (yvec, OPIHI_FLT, MAX (ny, 1));
+    bzero (yvec[0].elements.Flt, ny*sizeof(opihi_flt));
     for (i = 0; i < ny; i++) {
-      xvec[0].elements[i] = i + sy; 
+      xvec[0].elements.Flt[i] = i + sy; 
     }
     ALLOCATE (Vbuf, float, MAX (nx, 1));
@@ -107,5 +105,5 @@
 	if (Mode == MEAN) { value /= nx; }
       }
-      yvec[0].elements[i] = value;
+      yvec[0].elements.Flt[i] = value;
     }
     free (Vbuf);
Index: /trunk/Ohana/src/opihi/cmd.data/dbselect.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/dbselect.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/dbselect.c	(revision 20936)
@@ -67,6 +67,24 @@
       return (FALSE);
     }
-    REALLOCATE (vec[i][0].elements, float, Nrows);
-    vec[i][0].Nelements = Nrows;
+    switch (fields[i].type) {
+      case FIELD_TYPE_TINY:
+      case FIELD_TYPE_SHORT:
+      case FIELD_TYPE_LONG:
+      case FIELD_TYPE_INT24:
+      case FIELD_TYPE_LONGLONG:
+	ResetVector (vec[i], OPIHI_INT, Nrows);
+	break;
+      case FIELD_TYPE_DECIMAL:
+      case FIELD_TYPE_FLOAT:
+      case FIELD_TYPE_DOUBLE:
+      case FIELD_TYPE_TIME:
+      case FIELD_TYPE_DATE:
+      case FIELD_TYPE_DATETIME:
+	ResetVector (vec[i], OPIHI_FLT, Nrows);
+	break;
+      default:
+	ResetVector (vec[i], OPIHI_FLT, Nrows);
+	break;
+    }
   }
 
@@ -88,8 +106,10 @@
 	  case FIELD_TYPE_INT24:
 	  case FIELD_TYPE_LONGLONG:
+	    vec[i][0].elements.Int[j] = atol (row[i]);
+	    break;
 	  case FIELD_TYPE_DECIMAL:
 	  case FIELD_TYPE_FLOAT:
 	  case FIELD_TYPE_DOUBLE:
-	    vec[i][0].elements[j] = atof (row[i]);
+	    vec[i][0].elements.Flt[j] = atof (row[i]);
 	    break;
 	  case FIELD_TYPE_TIME:
@@ -97,11 +117,11 @@
 	  case FIELD_TYPE_DATETIME:
 	    seconds = ohana_date_to_sec (row[i]);
-	    vec[i][0].elements[j] = ohana_sec_to_mjd (seconds);
+	    vec[i][0].elements.Flt[j] = ohana_sec_to_mjd (seconds);
 	    break;
 	  default:
-	    vec[i][0].elements[j] = NAN;
+	    vec[i][0].elements.Flt[j] = NAN;
 	}
       } else {
-	vec[i][0].elements[j] = NAN;
+	vec[i][0].elements.Flt[j] = NAN;
       }
     }
Index: /trunk/Ohana/src/opihi/cmd.data/dimendown.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/dimendown.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/dimendown.c	(revision 20936)
@@ -6,5 +6,6 @@
   
   int i, Nx, Ny, Npix, N, mode;
-  float *in, *out;
+  float *in;
+  opihi_flt *out;
   Vector *vec;
   Buffer *buf;
@@ -29,9 +30,8 @@
   Npix = Nx * Ny;
 
-  vec[0].Nelements = Npix;
-  REALLOCATE (vec[0].elements, float, Npix);
+  ResetVector (vec, OPIHI_FLT, Npix);
 
   in = (float *) buf[0].matrix.buffer;
-  out = vec[0].elements;
+  out = vec[0].elements.Flt;
 
   switch (mode) {
Index: /trunk/Ohana/src/opihi/cmd.data/dimenup.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/dimenup.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/dimenup.c	(revision 20936)
@@ -4,5 +4,5 @@
   
   int i, Nx, Ny, Npix;
-  float *in, *out;
+  float *out;
   Vector *vec;
   Buffer *buf;
@@ -29,8 +29,15 @@
 
   out = (float *) buf[0].matrix.buffer;
-  in = vec[0].elements;
 
-  for (i = 0; i < Npix; i++, in++, out++) {
-    *out = *in;
+  if (vec[0].type == OPIHI_FLT) {
+    opihi_flt *in = vec[0].elements.Flt;
+    for (i = 0; i < Npix; i++, in++, out++) {
+      *out = *in;
+    }
+  } else {
+    opihi_int *in = vec[0].elements.Int;
+    for (i = 0; i < Npix; i++, in++, out++) {
+      *out = *in;
+    }
   }
 
Index: /trunk/Ohana/src/opihi/cmd.data/fft1d.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/fft1d.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/fft1d.c	(revision 20936)
@@ -25,4 +25,7 @@
   if ((Ire = SelectVector (argv[1], OLDVECTOR, TRUE)) == NULL) return (FALSE);
   
+  REQUIRE_VECTOR_FLT (Ire, FALSE); 
+  if (Iim) { REQUIRE_VECTOR_FLT (Iim, FALSE); }
+
   // check the input data (match lengths? binary length?)
   Npix = Ire[0].Nelements;
@@ -40,21 +43,19 @@
   if ((Oim = SelectVector (argv[5], ANYVECTOR, TRUE)) == NULL) return (FALSE);
 
-  // allocate sufficient output space
-  Ore[0].Nelements = Npix;
-  Oim[0].Nelements = Npix;
-  REALLOCATE (Ore[0].elements, float, Npix);
-  REALLOCATE (Oim[0].elements, float, Npix);
+  // allocate sufficient output space, force output to be FLT
+  ResetVector (Ore, OPIHI_FLT, Npix);
+  ResetVector (Oim, OPIHI_FLT, Npix);
  
   // copy data to output vectors (fft is done in place)
-  memcpy (Ore[0].elements, Ire[0].elements, Npix*sizeof(float));
+  memcpy (Ore[0].elements.Flt, Ire[0].elements.Flt, Npix*sizeof(opihi_flt));
 
   // copy imaginary vector or create a zero vector
   if (ZeroImaginary) {
-    memset (Oim[0].elements, 0, Npix*sizeof(float));
+    memset (Oim[0].elements.Flt, 0, Npix*sizeof(opihi_flt));
   } else {
-    memcpy (Oim[0].elements, Iim[0].elements, Npix*sizeof(float));
+    memcpy (Oim[0].elements.Flt, Iim[0].elements.Flt, Npix*sizeof(opihi_flt));
   }    
 
-  fft1D (Ore[0].elements, Oim[0].elements, Npix, Nbit, forward); 
+  dfft1D (Ore[0].elements.Flt, Oim[0].elements.Flt, Npix, Nbit, forward); 
   
   return (TRUE);
Index: /trunk/Ohana/src/opihi/cmd.data/fit.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/fit.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/fit.c	(revision 20936)
@@ -8,5 +8,5 @@
   int N, Weight, Quiet, ClipNiter;
   Vector *xvec, *yvec, *dyvec;
-  float *x, *y, *dy, *yf, *yfit;
+  opihi_flt *x, *y, *dy, *yf, *yfit;
   char name[64], *mask;
 
@@ -53,9 +53,16 @@
     return (FALSE);
   }
-  if (Weight && xvec[0].Nelements != dyvec[0].Nelements) {
-    gprint (GP_ERR, "vectors must have same length\n");
-    return (FALSE);
-  }
-  
+  REQUIRE_VECTOR_FLT (xvec, FALSE); 
+  REQUIRE_VECTOR_FLT (yvec, FALSE); 
+
+  if (Weight) {
+    REQUIRE_VECTOR_FLT (dyvec, FALSE); 
+    if (xvec[0].Nelements != dyvec[0].Nelements) {
+      gprint (GP_ERR, "vectors must have same length\n");
+      return (FALSE);
+    }
+  }
+ 
+
   /* nterm is number of polynomial terms, starting at x^0 */
   order = atof (argv[3]);
@@ -63,5 +70,5 @@
   mterm = 2*nterm;
 
-  ALLOCATE (yfit, float, xvec[0].Nelements);
+  ALLOCATE (yfit, opihi_flt, xvec[0].Nelements);
   ALLOCATE (mask, char, xvec[0].Nelements);
   memset (mask, 0, xvec[0].Nelements);
@@ -88,7 +95,7 @@
 
     /* perform linear fit */
-    x = xvec[0].elements;
-    y = yvec[0].elements;
-    if (Weight) dy = dyvec[0].elements;
+    x = xvec[0].elements.Flt;
+    y = yvec[0].elements.Flt;
+    if (Weight) dy = dyvec[0].elements.Flt;
 
     for (i = 0; i < xvec[0].Nelements; i++, x++, y++) {
@@ -121,5 +128,5 @@
 
     /* generate fitted values */
-    x = xvec[0].elements;
+    x = xvec[0].elements.Flt;
     yf = yfit;
     for (i = 0; i < xvec[0].Nelements; i++, x++, yf++) {
@@ -134,6 +141,6 @@
 
     /* measure fit residual scatter */
-    x  = xvec[0].elements;
-    y  = yvec[0].elements;
+    x  = xvec[0].elements.Flt;
+    y  = yvec[0].elements.Flt;
     yf = yfit;
     dY = dY2 = 0;
@@ -150,6 +157,6 @@
 
     /* mask outlier points */
-    x  = xvec[0].elements;
-    y  = yvec[0].elements;
+    x  = xvec[0].elements.Flt;
+    y  = yvec[0].elements.Flt;
     yf = yfit;
     Nmask = 0;
@@ -193,12 +200,12 @@
     if ((fvec = SelectVector ("yfit", ANYVECTOR, TRUE)) == NULL) return (FALSE);    
     if ((mvec = SelectVector ("mask", ANYVECTOR, TRUE)) == NULL) return (FALSE);    
-    free (fvec[0].elements);
-    fvec[0].elements = yfit;
+    free (fvec[0].elements.Flt);
+    fvec[0].elements.Flt = yfit;
     fvec[0].Nelements = xvec[0].Nelements;
     mvec[0].Nelements = xvec[0].Nelements;
 
-    REALLOCATE (mvec[0].elements, float, xvec[0].Nelements);
+    REALLOCATE (mvec[0].elements.Flt, opihi_flt, xvec[0].Nelements);
     for (i = 0; i < xvec[0].Nelements; i++) {
-      mvec[0].elements[i] = mask[i];
+      mvec[0].elements.Flt[i] = mask[i];
     }
   } else {
Index: /trunk/Ohana/src/opihi/cmd.data/fit2d.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/fit2d.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/fit2d.c	(revision 20936)
@@ -7,5 +7,5 @@
   int k, K, i, j, n, Npt, Nmask, nx, ny, nterm, mterm, wterm, order;
   int N, Weight, Quiet, ClipNiter, VERBOSE;
-  float *x, *y, *z, *dz, *zfit, *zf; 
+  opihi_flt *x, *y, *z, *dz, *zfit, *zf; 
   char name[64], *mask;
   Vector *xvec, *yvec, *zvec, *dzvec;
@@ -64,7 +64,14 @@
     return (FALSE);
   }
-  if (Weight && xvec[0].Nelements != dzvec[0].Nelements) {
-    gprint (GP_ERR, "vectors must have same length\n");
-    return (FALSE);
+  REQUIRE_VECTOR_FLT (xvec, FALSE); 
+  REQUIRE_VECTOR_FLT (yvec, FALSE); 
+  REQUIRE_VECTOR_FLT (zvec, FALSE); 
+
+  if (Weight) {
+    REQUIRE_VECTOR_FLT (dzvec, FALSE); 
+    if (xvec[0].Nelements != dzvec[0].Nelements) {
+      gprint (GP_ERR, "vectors must have same length\n");
+      return (FALSE);
+    }
   }
   
@@ -74,5 +81,5 @@
   mterm = 2*order + 1;
 
-  ALLOCATE (zfit, float, xvec[0].Nelements);
+  ALLOCATE (zfit, opihi_flt, xvec[0].Nelements);
   ALLOCATE (mask, char, xvec[0].Nelements);
   memset (mask, 0, xvec[0].Nelements);
@@ -102,8 +109,8 @@
     }
 
-    x = xvec[0].elements;
-    y = yvec[0].elements;
-    z = zvec[0].elements;
-    if (Weight) dz = dzvec[0].elements;
+    x = xvec[0].elements.Flt;
+    y = yvec[0].elements.Flt;
+    z = zvec[0].elements.Flt;
+    if (Weight) dz = dzvec[0].elements.Flt;
 
     /* add up the x,y values */
@@ -128,7 +135,7 @@
 
     /* add up the z values */
-    x = xvec[0].elements;
-    y = yvec[0].elements;
-    z = zvec[0].elements;
+    x = xvec[0].elements.Flt;
+    y = yvec[0].elements.Flt;
+    z = zvec[0].elements.Flt;
     for (i = 0; i < xvec[0].Nelements; i++, x++, y++, z++) {
       if (mask[i]) continue;
@@ -179,6 +186,6 @@
     */
     /* generate fitted values */
-    x = xvec[0].elements;
-    y = yvec[0].elements;
+    x = xvec[0].elements.Flt;
+    y = yvec[0].elements.Flt;
     zf = zfit;
     for (n = 0; n < xvec[0].Nelements; n++, x++, y++, zf++) {
@@ -197,7 +204,7 @@
 
     /* measure fit residual scatter */
-    x  = xvec[0].elements;
-    y  = yvec[0].elements;
-    z  = zvec[0].elements;
+    x  = xvec[0].elements.Flt;
+    y  = yvec[0].elements.Flt;
+    z  = zvec[0].elements.Flt;
     zf = zfit;
     dZ = dZ2 = 0;
@@ -216,7 +223,7 @@
 
     /* mask outlier points */
-    x  = xvec[0].elements;
-    y  = yvec[0].elements;
-    z  = zvec[0].elements;
+    x  = xvec[0].elements.Flt;
+    y  = yvec[0].elements.Flt;
+    z  = zvec[0].elements.Flt;
     zf = zfit;
     Nmask = 0;
Index: /trunk/Ohana/src/opihi/cmd.data/gaussdeviate.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/gaussdeviate.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/gaussdeviate.c	(revision 20936)
@@ -15,10 +15,9 @@
   sigma = atof (argv[4]);
 
-  vec[0].Nelements = Npts;
-  REALLOCATE (vec[0].elements, float, Npts);
+  ResetVector (vec, OPIHI_FLT, Npts);
 
   gauss_init (2048);
   for (i = 0; i < Npts; i++) {
-    vec[0].elements[i] = rnd_gauss (mean, sigma);
+    vec[0].elements.Flt[i] = rnd_gauss (mean, sigma);
   }
   return (TRUE);
@@ -46,10 +45,9 @@
   sigma = atof (argv[4]);
 
-  vec[0].Nelements = Npts;
-  REALLOCATE (vec[0].elements, float, Npts);
+  ResetVector (vec, OPIHI_FLT, Npts);
 
   gauss_init (Npts);
   for (i = 0; i < Npts; i++) {
-    vec[0].elements[i] = int_gauss (i);
+    vec[0].elements.Flt[i] = int_gauss (i);
   }
   return (TRUE);
Index: /trunk/Ohana/src/opihi/cmd.data/gaussj.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/gaussj.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/gaussj.c	(revision 20936)
@@ -2,8 +2,10 @@
 
 int gaussjordan (int argc, char **argv) {
-  
-  float *m, *v;
+
+  float *m;
+  opihi_flt *vf;
+  opihi_int *vi;
   double **a, **b;
-  int i, j, N, status, QUIET;
+  int i, j, N, status, QUIET, isFloat;
   Vector *B;
   Buffer *A;
@@ -31,14 +33,21 @@
   }
 
+  isFloat = (B[0].type == OPIHI_FLT);
+  vf = B[0].elements.Flt;
+  vi = B[0].elements.Int;
+
   m = (float *) A[0].matrix.buffer;
-  v = B[0].elements;
   for (i = 0; i < N; i++) {
     for (j = 0; j < N; j++) {
       a[i][j] = m[i+j*N];
     }
-    b[i][0] = v[i]; 
+    b[i][0] = isFloat ? vf[i] : vi[i]; 
   }
 
   status = dgaussjordan (a, b, N, 1);
+
+  // output vector needs to be float, so re-cast it
+  ResetVector (B, OPIHI_FLT, N);
+  vf = B[0].elements.Flt;
 
   for (i = 0; i < N; i++) {
@@ -46,5 +55,5 @@
        m[i+j*N] = a[i][j];
     }
-    v[i] = b[i][0]; 
+    vf[i] = b[i][0]; 
   }
 
Index: /trunk/Ohana/src/opihi/cmd.data/grid.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/grid.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/grid.c	(revision 20936)
@@ -23,8 +23,6 @@
 
   N = 0;
-  Xvec.Nelements = 200;
-  Yvec.Nelements = 200;
-  ALLOCATE (Xvec.elements, float, Xvec.Nelements);
-  ALLOCATE (Yvec.elements, float, Yvec.Nelements);
+  SetVector (&Xvec, OPIHI_FLT, 200);
+  SetVector (&Yvec, OPIHI_FLT, 200);
 
   major = minor = 1;
@@ -64,21 +62,21 @@
       if (MajorTick) {
 	/* major tick */
-	Xvec.elements[N] = next;
-	Yvec.elements[N] = graphmode.ymin;
-	N++;
-	if (N == Xvec.Nelements) {
-	  Xvec.Nelements += 200;
-	  Yvec.Nelements += 200;
-	  REALLOCATE (Xvec.elements, float, Xvec.Nelements);
-	  REALLOCATE (Yvec.elements, float, Yvec.Nelements);
-	}
-	Xvec.elements[N] = next;
-	Yvec.elements[N] = graphmode.ymax;
-	N++;
-	if (N == Xvec.Nelements) {
-	  Xvec.Nelements += 200;
-	  Yvec.Nelements += 200;
-	  REALLOCATE (Xvec.elements, float, Xvec.Nelements);
-	  REALLOCATE (Yvec.elements, float, Yvec.Nelements);
+	Xvec.elements.Flt[N] = next;
+	Yvec.elements.Flt[N] = graphmode.ymin;
+	N++;
+	if (N == Xvec.Nelements) {
+	  Xvec.Nelements += 200;
+	  Yvec.Nelements += 200;
+	  REALLOCATE (Xvec.elements.Flt, opihi_flt, Xvec.Nelements);
+	  REALLOCATE (Yvec.elements.Flt, opihi_flt, Yvec.Nelements);
+	}
+	Xvec.elements.Flt[N] = next;
+	Yvec.elements.Flt[N] = graphmode.ymax;
+	N++;
+	if (N == Xvec.Nelements) {
+	  Xvec.Nelements += 200;
+	  Yvec.Nelements += 200;
+	  REALLOCATE (Xvec.elements.Flt, opihi_flt, Xvec.Nelements);
+	  REALLOCATE (Yvec.elements.Flt, opihi_flt, Yvec.Nelements);
 	}
       }
@@ -86,21 +84,21 @@
       if (MinorTick) {
 	/* minor tick */
-	Xvec.elements[N] = next;
-	Yvec.elements[N] = graphmode.ymin;
-	N++;
-	if (N == Xvec.Nelements) {
-	  Xvec.Nelements += 200;
-	  Yvec.Nelements += 200;
-	  REALLOCATE (Xvec.elements, float, Xvec.Nelements);
-	  REALLOCATE (Yvec.elements, float, Yvec.Nelements);
-	}
-	Xvec.elements[N] = next;
-	Yvec.elements[N] = graphmode.ymax;
-	N++;
-	if (N == Xvec.Nelements) {
-	  Xvec.Nelements += 200;
-	  Yvec.Nelements += 200;
-	  REALLOCATE (Xvec.elements, float, Xvec.Nelements);
-	  REALLOCATE (Yvec.elements, float, Yvec.Nelements);
+	Xvec.elements.Flt[N] = next;
+	Yvec.elements.Flt[N] = graphmode.ymin;
+	N++;
+	if (N == Xvec.Nelements) {
+	  Xvec.Nelements += 200;
+	  Yvec.Nelements += 200;
+	  REALLOCATE (Xvec.elements.Flt, opihi_flt, Xvec.Nelements);
+	  REALLOCATE (Yvec.elements.Flt, opihi_flt, Yvec.Nelements);
+	}
+	Xvec.elements.Flt[N] = next;
+	Yvec.elements.Flt[N] = graphmode.ymax;
+	N++;
+	if (N == Xvec.Nelements) {
+	  Xvec.Nelements += 200;
+	  Yvec.Nelements += 200;
+	  REALLOCATE (Xvec.elements.Flt, opihi_flt, Xvec.Nelements);
+	  REALLOCATE (Yvec.elements.Flt, opihi_flt, Yvec.Nelements);
 	}
       }
@@ -144,21 +142,21 @@
       if (MajorTick) {
 	/* major tick */
-	Xvec.elements[N] = graphmode.xmin;
-	Yvec.elements[N] = next;
-	N++;
-	if (N == Xvec.Nelements) {
-	  Xvec.Nelements += 200;
-	  Yvec.Nelements += 200;
-	  REALLOCATE (Xvec.elements, float, Xvec.Nelements);
-	  REALLOCATE (Yvec.elements, float, Yvec.Nelements);
-	}
-	Xvec.elements[N] = graphmode.xmax;
-	Yvec.elements[N] = next;
-	N++;
-	if (N == Xvec.Nelements) {
-	  Xvec.Nelements += 200;
-	  Yvec.Nelements += 200;
-	  REALLOCATE (Xvec.elements, float, Xvec.Nelements);
-	  REALLOCATE (Yvec.elements, float, Yvec.Nelements);
+	Xvec.elements.Flt[N] = graphmode.xmin;
+	Yvec.elements.Flt[N] = next;
+	N++;
+	if (N == Xvec.Nelements) {
+	  Xvec.Nelements += 200;
+	  Yvec.Nelements += 200;
+	  REALLOCATE (Xvec.elements.Flt, opihi_flt, Xvec.Nelements);
+	  REALLOCATE (Yvec.elements.Flt, opihi_flt, Yvec.Nelements);
+	}
+	Xvec.elements.Flt[N] = graphmode.xmax;
+	Yvec.elements.Flt[N] = next;
+	N++;
+	if (N == Xvec.Nelements) {
+	  Xvec.Nelements += 200;
+	  Yvec.Nelements += 200;
+	  REALLOCATE (Xvec.elements.Flt, opihi_flt, Xvec.Nelements);
+	  REALLOCATE (Yvec.elements.Flt, opihi_flt, Yvec.Nelements);
 	}
       }
@@ -166,21 +164,21 @@
       if (MinorTick) {
 	/* minor tick */
-	Xvec.elements[N] = graphmode.xmin;
-	Yvec.elements[N] = next;
-	N++;
-	if (N == Xvec.Nelements) {
-	  Xvec.Nelements += 200;
-	  Yvec.Nelements += 200;
-	  REALLOCATE (Xvec.elements, float, Xvec.Nelements);
-	  REALLOCATE (Yvec.elements, float, Yvec.Nelements);
-	}
-	Xvec.elements[N] = graphmode.xmax;
-	Yvec.elements[N] = next;
-	N++;
-	if (N == Xvec.Nelements) {
-	  Xvec.Nelements += 200;
-	  Yvec.Nelements += 200;
-	  REALLOCATE (Xvec.elements, float, Xvec.Nelements);
-	  REALLOCATE (Yvec.elements, float, Yvec.Nelements);
+	Xvec.elements.Flt[N] = graphmode.xmin;
+	Yvec.elements.Flt[N] = next;
+	N++;
+	if (N == Xvec.Nelements) {
+	  Xvec.Nelements += 200;
+	  Yvec.Nelements += 200;
+	  REALLOCATE (Xvec.elements.Flt, opihi_flt, Xvec.Nelements);
+	  REALLOCATE (Yvec.elements.Flt, opihi_flt, Yvec.Nelements);
+	}
+	Xvec.elements.Flt[N] = graphmode.xmax;
+	Yvec.elements.Flt[N] = next;
+	N++;
+	if (N == Xvec.Nelements) {
+	  Xvec.Nelements += 200;
+	  Yvec.Nelements += 200;
+	  REALLOCATE (Xvec.elements.Flt, opihi_flt, Xvec.Nelements);
+	  REALLOCATE (Yvec.elements.Flt, opihi_flt, Yvec.Nelements);
 	}
       }
@@ -193,8 +191,8 @@
   graphmode.ptype = 100; /* connect a pair */
   graphmode.etype = 0;
-  PlotVectorPair (kapa, N, Xvec.elements, Yvec.elements, &graphmode);
-
-  free (Xvec.elements);
-  free (Yvec.elements);
+  PlotVectorPair (kapa, &Xvec, &Yvec, &graphmode);
+
+  free (Xvec.elements.Flt);
+  free (Yvec.elements.Flt);
 
   return (TRUE);
Index: /trunk/Ohana/src/opihi/cmd.data/gridify.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/gridify.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/gridify.c	(revision 20936)
@@ -5,8 +5,9 @@
   int i, Nx, Ny, Xb, Yb, Normalize, N;
   float Xmin, Xmax, dX, Ymin, Ymax, dY;
-  float *buf, *val, *x, *y, *z;
+  float *buf, *val;
   int *Nval;
   Buffer *bf;
   Vector *vx, *vy, *vz;
+  opihi_flt *x, *y, *z;
 
   Normalize = TRUE;
@@ -28,4 +29,8 @@
   if (vx[0].Nelements != vy[0].Nelements) return (FALSE);
   if (vx[0].Nelements != vz[0].Nelements) return (FALSE);
+
+  REQUIRE_VECTOR_FLT (vx, FALSE); 
+  REQUIRE_VECTOR_FLT (vy, FALSE); 
+  REQUIRE_VECTOR_FLT (vz, FALSE); 
 
   Xmin = atof (argv[5]);
@@ -50,7 +55,7 @@
   bzero (Nval, Nx*Ny*sizeof(int));
 
-  x = vx[0].elements;
-  y = vy[0].elements;
-  z = vz[0].elements;
+  x = vx[0].elements.Flt;
+  y = vy[0].elements.Flt;
+  z = vz[0].elements.Flt;
   for (i = 0; i < vx[0].Nelements; i++, x++, y++, z++) {
     Xb = (*x - Xmin) / dX;
Index: /trunk/Ohana/src/opihi/cmd.data/histogram.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/histogram.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/histogram.c	(revision 20936)
@@ -4,5 +4,6 @@
   
   int i, bin, Nbins;
-  float *V, start, end, delta;
+  opihi_int *OUT;
+  opihi_flt start, end, delta;
   Vector *xvec, *yvec;
 
@@ -30,18 +31,25 @@
   if ((xvec = SelectVector (argv[1], OLDVECTOR, TRUE)) == NULL) return (FALSE);
   if ((yvec = SelectVector (argv[2], ANYVECTOR, TRUE)) == NULL) return (FALSE);
-  yvec[0].Nelements = Nbins;
-    
-  REALLOCATE (yvec[0].elements, float, yvec[0].Nelements);
-  bzero (yvec[0].elements, sizeof(float)*yvec[0].Nelements);
-  if (Nbins < 1) {
-      return (TRUE);
+
+  ResetVector (yvec, OPIHI_INT, Nbins);
+  bzero (yvec[0].elements.Int, sizeof(opihi_int)*yvec[0].Nelements);
+  if (Nbins < 1) return (TRUE);
+  OUT = yvec[0].elements.Int;
+
+  if (xvec[0].type == OPIHI_FLT) {
+    opihi_flt *V = xvec[0].elements.Flt;
+    for (i = 0; i < xvec[0].Nelements; i++, V++) {
+      if (isnan(*V)) continue;
+      bin = MIN (MAX (0, (*V - start) / delta), Nbins - 1);
+      OUT[bin]++;
+    }      
+  } else {
+    opihi_int *V = xvec[0].elements.Int;
+    for (i = 0; i < xvec[0].Nelements; i++, V++) {
+      if (isnan(*V)) continue;
+      bin = MIN (MAX (0, (*V - start) / delta), Nbins - 1);
+      OUT[bin]++;
+    }      
   }
-
-  V = xvec[0].elements;
-  for (i = 0; i < xvec[0].Nelements; i++, V++) {
-    if (isnan(*V)) continue;
-    bin = MIN (MAX (0, (*V - start) / delta), Nbins - 1);
-    yvec[0].elements[bin] += 1.0;
-  }      
 
   return (TRUE);
Index: /trunk/Ohana/src/opihi/cmd.data/imcut.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/imcut.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/imcut.c	(revision 20936)
@@ -37,8 +37,6 @@
   dY = dY / L;
 
-  REALLOCATE (xvec[0].elements, float, MAX (L, 1));
-  REALLOCATE (yvec[0].elements, float, MAX (L, 1));
-  xvec[0].Nelements = L;
-  yvec[0].Nelements = L;
+  ResetVector (xvec, OPIHI_FLT, MAX (L, 1));
+  ResetVector (yvec, OPIHI_FLT, MAX (L, 1));
 
   V = (float *)buf[0].matrix.buffer;
@@ -46,6 +44,6 @@
     xi = xs + i*dX - 0.5;
     yi = ys + i*dY - 0.5;
-    xvec[0].elements[i] = i;
-    yvec[0].elements[i] = V[xi + Nx*yi];
+    xvec[0].elements.Flt[i] = i;
+    yvec[0].elements.Flt[i] = V[xi + Nx*yi];
   }
 
Index: /trunk/Ohana/src/opihi/cmd.data/imhist.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/imhist.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/imhist.c	(revision 20936)
@@ -105,10 +105,8 @@
   }  
 
-  vec1[0].Nelements = Nbins + 1;
-  vec2[0].Nelements = Nbins + 1;
-  REALLOCATE (vec1[0].elements, float, vec1[0].Nelements);
-  bzero (vec1[0].elements, vec1[0].Nelements*sizeof(float));
-  REALLOCATE (vec2[0].elements, float, vec2[0].Nelements);
-  bzero (vec2[0].elements, vec2[0].Nelements*sizeof(float));
+  ResetVector (vec1, OPIHI_FLT, Nbins + 1);
+  ResetVector (vec2, OPIHI_FLT, Nbins + 1);
+  bzero (vec1[0].elements.Flt, vec1[0].Nelements*sizeof(opihi_flt));
+  bzero (vec2[0].elements.Flt, vec2[0].Nelements*sizeof(opihi_flt));
   
   for (j = sy; j < sy + ny; j++) {
@@ -116,9 +114,9 @@
     for (i = 0; i < nx; i++, V++) {
       bin = MAX (MIN (Nbins, (*V - min) / dx), 0);
-      vec2[0].elements[bin] += 1.0;
+      vec2[0].elements.Flt[bin] += 1.0;
     }
   }
   for (i = 0; i < Nbins + 1; i++, V++) {
-    vec1[0].elements[i] = i*dx + min;
+    vec1[0].elements.Flt[i] = i*dx + min;
   }
   
Index: /trunk/Ohana/src/opihi/cmd.data/integrate.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/integrate.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/integrate.c	(revision 20936)
@@ -3,7 +3,8 @@
 int integrate (int argc, char **argv) {
   
-  int i, N, VERBOSE;
-  float *X, *Y;
-  double start, end, value, range;
+  int i, N, VERBOSE, isFloat;
+  opihi_flt *Yf;
+  opihi_int *Yi;
+  double start, end, value, range, dvalue;
   Vector *vecx, *vecy;
 
@@ -25,15 +26,30 @@
   end   = atof (argv[4]);
 
-  X = vecx[0].elements;
-  Y = vecy[0].elements;
+  isFloat = vecy[0].type == OPIHI_FLT;
+  Yf = vecy[0].elements.Flt;
+  Yi = vecy[0].elements.Int;
 
   value = 0;
   range = 0;
-  for (i = 0; i < vecx[0].Nelements-1; i++, X++, Y++) {
-    if ((*X >= start) && (*X <= end)) {
-      value += *Y * (X[1] - X[0]);
-      range += (X[1] - X[0]);
-    }
-  }      
+
+  if (vecx[0].type == OPIHI_FLT) {
+    opihi_flt *X = vecx[0].elements.Flt;
+    for (i = 0; i < vecx[0].Nelements-1; i++, X++, Yi++, Yf++) {
+      if ((*X >= start) && (*X <= end)) {
+	dvalue = (isFloat) ? *Yf : *Yi;
+	value += dvalue * (X[1] - X[0]);
+	range += (X[1] - X[0]);
+      }
+    }      
+  } else {
+    opihi_int *X = vecx[0].elements.Int;
+    for (i = 0; i < vecx[0].Nelements-1; i++, X++, Yi++, Yf++) {
+      if ((*X >= start) && (*X <= end)) {
+	dvalue = (isFloat) ? *Yf : *Yi;
+	value += dvalue * (X[1] - X[0]);
+	range += (X[1] - X[0]);
+      }
+    }      
+  }
 
   set_variable ("sum", value); 
Index: /trunk/Ohana/src/opihi/cmd.data/interpolate.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/interpolate.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/interpolate.c	(revision 20936)
@@ -21,28 +21,30 @@
   if ((yout = SelectVector (argv[4],  ANYVECTOR, TRUE)) == NULL) return (FALSE);
 
-  yout[0].Nelements = xout[0].Nelements;
-  REALLOCATE (yout[0].elements, float, yout[0].Nelements);
+  REQUIRE_VECTOR_FLT (xin, FALSE); 
+  REQUIRE_VECTOR_FLT (yin, FALSE); 
+  REQUIRE_VECTOR_FLT (xout, FALSE); 
+  ResetVector (yout, OPIHI_FLT, xout[0].Nelements);
 
-  dx = xin[0].elements[1] - xin[0].elements[0];
-  dy = yin[0].elements[1] - yin[0].elements[0];
-  x0 = xin[0].elements[0];
-  y0 = yin[0].elements[0];
+  dx = xin[0].elements.Flt[1] - xin[0].elements.Flt[0];
+  dy = yin[0].elements.Flt[1] - yin[0].elements.Flt[0];
+  x0 = xin[0].elements.Flt[0];
+  y0 = yin[0].elements.Flt[0];
   
   /* in vectors are sorted, out vectors are not */
   for (j = 0; j < xin[0].Nelements - 1; j++) {
-    dx = xin[0].elements[j+1] - xin[0].elements[j];
-    dy = yin[0].elements[j+1] - yin[0].elements[j];
-    x0 = xin[0].elements[j];
-    y0 = yin[0].elements[j];
-    x1 = xin[0].elements[j+1];
+    dx = xin[0].elements.Flt[j+1] - xin[0].elements.Flt[j];
+    dy = yin[0].elements.Flt[j+1] - yin[0].elements.Flt[j];
+    x0 = xin[0].elements.Flt[j];
+    y0 = yin[0].elements.Flt[j];
+    x1 = xin[0].elements.Flt[j+1];
     for (i = 0; i < xout[0].Nelements; i++) {
-      if ((xout[0].elements[i] >= x0) && (xout[0].elements[i] < x1)) {
-	yout[0].elements[i] = (dy/dx)*(xout[0].elements[i] - x0) + y0;
+      if ((xout[0].elements.Flt[i] >= x0) && (xout[0].elements.Flt[i] < x1)) {
+	yout[0].elements.Flt[i] = (dy/dx)*(xout[0].elements.Flt[i] - x0) + y0;
       }
-      if ((j == 0) && (xout[0].elements[i] < x0)) {
-	yout[0].elements[i] = (dy/dx)*(xout[0].elements[i] - x0) + y0;
+      if ((j == 0) && (xout[0].elements.Flt[i] < x0)) {
+	yout[0].elements.Flt[i] = (dy/dx)*(xout[0].elements.Flt[i] - x0) + y0;
       }
-      if ((j == xin[0].Nelements - 2) && (xout[0].elements[i] >= x1)) {
-	yout[0].elements[i] = (dy/dx)*(xout[0].elements[i] - x0) + y0;
+      if ((j == xin[0].Nelements - 2) && (xout[0].elements.Flt[i] >= x1)) {
+	yout[0].elements.Flt[i] = (dy/dx)*(xout[0].elements.Flt[i] - x0) + y0;
       }
     }    
Index: /trunk/Ohana/src/opihi/cmd.data/lookup.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/lookup.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/lookup.c	(revision 20936)
@@ -4,5 +4,5 @@
   
   int i, j;
-  float *ip, *op, *xp, *yp;
+  opihi_flt *ip, *op, *xp, *yp;
   Vector *in, *out, *xv, *yv;
 
@@ -17,4 +17,8 @@
   if ((yv  = SelectVector (argv[4], OLDVECTOR, TRUE)) == NULL) return (FALSE);
 
+  REQUIRE_VECTOR_FLT (in, FALSE); 
+  REQUIRE_VECTOR_FLT (xv, FALSE); 
+  REQUIRE_VECTOR_FLT (yv, FALSE); 
+
   if (xv[0].Nelements != yv[0].Nelements) {
       gprint (GP_ERR, "unmatched lookup table lengths\n");
@@ -22,14 +26,13 @@
   }
 
-  out[0].Nelements = in[0].Nelements;
-  REALLOCATE (out[0].elements, float, out[0].Nelements);
+  ResetVector (out, OPIHI_FLT, in[0].Nelements);
 
-  ip = in[0].elements;
-  op = out[0].elements;
+  ip = in[0].elements.Flt;
+  op = out[0].elements.Flt;
 
   for (i = 0; i < in[0].Nelements; i++, ip++, op++) {
     // re-write this using bisection
-    xp = xv[0].elements;
-    yp = yv[0].elements;
+    xp = xv[0].elements.Flt;
+    yp = yv[0].elements.Flt;
 
     for (j = 0; (*ip < *xp) && (j < yv[0].Nelements); j++);
Index: /trunk/Ohana/src/opihi/cmd.data/medacc.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/medacc.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/medacc.c	(revision 20936)
@@ -5,5 +5,5 @@
   int i, j, Nbins, Nvalues, N, N0, N1;
   double start, end, delta, k0, k1, fn;
-  float *V, *K, *V1, *K1, *O, *tmpvec, *tmpkey;
+  opihi_flt *V, *K, *V1, *K1, *O, *tmpvec, *tmpkey;
   Vector *val, *key, *out;
 
@@ -21,4 +21,7 @@
   if ((out = SelectVector (argv[2], ANYVECTOR, TRUE)) == NULL) return (FALSE);
 
+  REQUIRE_VECTOR_FLT (val, FALSE); 
+  REQUIRE_VECTOR_FLT (key, FALSE); 
+
   start = atof (argv[4]);
   end   = atof (argv[5]);
@@ -34,14 +37,13 @@
   Nbins = 1 + (int)((end - start) / delta);
 
-  out[0].Nelements = Nbins;
-  REALLOCATE (out[0].elements, float, out[0].Nelements);
-  bzero (out[0].elements, sizeof(float)*out[0].Nelements);
+  ResetVector (out, OPIHI_FLT, Nbins);
+  bzero (out[0].elements.Flt, sizeof(opihi_flt)*out[0].Nelements);
 
   /* copy vec and key to temp vectors */
-  ALLOCATE (tmpvec, float, val[0].Nelements);
-  ALLOCATE (tmpkey, float, val[0].Nelements);
+  ALLOCATE (tmpvec, opihi_flt, val[0].Nelements);
+  ALLOCATE (tmpkey, opihi_flt, val[0].Nelements);
 
-  V = val[0].elements;
-  K = key[0].elements;
+  V = val[0].elements.Flt;
+  K = key[0].elements.Flt;
   V1 = tmpvec;
   K1 = tmpkey;
@@ -53,7 +55,7 @@
 
   /* sort vec and key by key */
-  fsortpair (tmpkey, tmpvec, Nvalues);
+  dsortpair (tmpkey, tmpvec, Nvalues);
 
-  O = out[0].elements;
+  O = out[0].elements.Flt;
   /* find the start and end key for each range */
   N0 = 0;
@@ -67,5 +69,5 @@
     N1 = j;
     N = N1 - N0;
-    fsort (&tmpvec[N0], N);
+    dsort (&tmpvec[N0], N);
     fn = O[i] = 0;
     for (j = N0 + 0.25*N; j < N0 + 0.75*N; j++) {
Index: /trunk/Ohana/src/opihi/cmd.data/mget.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/mget.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/mget.c	(revision 20936)
@@ -4,5 +4,6 @@
   
   int i, Nx, Ny, Npix, xdir, Nset;
-  float *in, *out;
+  float *in;
+  opihi_flt *out;
   Buffer *buf;
   Vector *vec;
@@ -32,6 +33,6 @@
 
   if (xdir) {
-    vec[0].Nelements = Npix = Nx;
-    REALLOCATE (vec[0].elements, float, Npix);
+    Npix = Nx;
+    ResetVector (vec, OPIHI_FLT, Nx);
     if (Nset >= Ny) {
       gprint (GP_ERR, "row out of range\n");
@@ -39,12 +40,11 @@
     }
     in  = (float *) buf[0].matrix.buffer + Nx*Nset;
-    out = vec[0].elements;
+    out = vec[0].elements.Flt;
     for (i = 0; i < Npix; i++, in++, out++) {
       *out = *in;
     }
-    return (TRUE);
   } else {
-    vec[0].Nelements = Npix = Ny;
-    REALLOCATE (vec[0].elements, float, Npix);
+    Npix = Ny;
+    ResetVector (vec, OPIHI_FLT, Ny);
     if (Nset >= Nx) {
       gprint (GP_ERR, "column out of range\n");
@@ -52,10 +52,9 @@
     }
     in  = (float *) buf[0].matrix.buffer + Nset;
-    out = vec[0].elements;
+    out = vec[0].elements.Flt;
     for (i = 0; i < Npix; i++, in+=Nx, out++) {
       *out = *in;
     }
-    return (TRUE);
-  }    
+  }
+  return (TRUE);
 }
-
Index: /trunk/Ohana/src/opihi/cmd.data/mset.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/mset.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/mset.c	(revision 20936)
@@ -4,5 +4,5 @@
   
   int i, Nx, Ny, Npix, xdir, Nset;
-  float *in, *out;
+  float *out;
   Buffer *buf;
   Vector *vec;
@@ -42,9 +42,18 @@
     }
     out = (float *) buf[0].matrix.buffer + Nx*Nset;
-    in = vec[0].elements;
-    for (i = 0; i < Npix; i++, in++, out++) {
-      *out = *in;
+
+    if (vec[0].type == OPIHI_FLT) {
+      opihi_flt *in = vec[0].elements.Flt;
+      for (i = 0; i < Npix; i++, in++, out++) {
+	*out = *in;
+      }
+    } else {
+      opihi_int *in = vec[0].elements.Int;
+      for (i = 0; i < Npix; i++, in++, out++) {
+	*out = *in;
+      }
     }
     return (TRUE);
+
   } else {
     if (Ny != Npix) {
@@ -57,7 +66,15 @@
     }
     out = (float *) buf[0].matrix.buffer + Nset;
-    in = vec[0].elements;
-    for (i = 0; i < Npix; i++, in++, out+=Nx) {
-      *out = *in;
+
+    if (vec[0].type == OPIHI_FLT) {
+      opihi_flt *in = vec[0].elements.Flt;
+      for (i = 0; i < Npix; i++, in++, out+=Nx) {
+	*out = *in;
+      }
+    } else {
+      opihi_int *in = vec[0].elements.Int;
+      for (i = 0; i < Npix; i++, in++, out+=Nx) {
+	*out = *in;
+      }
     }
     return (TRUE);
Index: /trunk/Ohana/src/opihi/cmd.data/peak.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/peak.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/peak.c	(revision 20936)
@@ -5,5 +5,4 @@
   int i, N, imax, QUIET;
   double start, end, xmax, ymax;
-  float *X, *Y;
   Vector *vecx, *vecy;
 
@@ -26,23 +25,60 @@
     end   = atof (argv[4]);
   } else {
-    start = vecx[0].elements[0];
-    end   = vecx[0].elements[vecx[0].Nelements - 1];
+    start = (vecx[0].type == OPIHI_FLT) ? vecx[0].elements.Flt[0] : vecx[0].elements.Int[0];
+    end   = (vecx[0].type == OPIHI_FLT) ? vecx[0].elements.Flt[vecx[0].Nelements - 1] : vecx[0].elements.Int[vecx[0].Nelements - 1];
   }
 
-  X = vecx[0].elements;
-  Y = vecy[0].elements;
+  imax = -1;
+  xmax = -HUGE_VAL;
+  ymax = -HUGE_VAL;
 
-  imax = -1;
-  xmax = *X;
-  ymax = *Y;
-  for (i = 1; i < vecx[0].Nelements-1; i++, X++, Y++) {
-    if ((*X >= start) && (*X <= end)) {
-      if ((imax == -1) || (*Y > ymax)) {
-	xmax = *X;
-	ymax = *Y;
-	imax = i;
-      }
-    }
-  }      
+  if ((vecx[0].type == OPIHI_FLT) && (vecy[0].type == OPIHI_FLT)) {
+    opihi_flt *X = vecx[0].elements.Flt;
+    opihi_flt *Y = vecy[0].elements.Flt;
+    for (i = 0; i < vecx[0].Nelements; i++, X++, Y++) {
+      if (*X < start) continue;
+      if (*X > end) continue;
+      if (*Y < ymax) continue;
+      xmax = *X;
+      ymax = *Y;
+      imax = i;
+    }      
+  }
+  if ((vecx[0].type == OPIHI_FLT) && (vecy[0].type == OPIHI_INT)) {
+    opihi_flt *X = vecx[0].elements.Flt;
+    opihi_int *Y = vecy[0].elements.Int;
+    for (i = 0; i < vecx[0].Nelements; i++, X++, Y++) {
+      if (*X < start) continue;
+      if (*X > end) continue;
+      if (*Y < ymax) continue;
+      xmax = *X;
+      ymax = *Y;
+      imax = i;
+    }      
+  }
+  if ((vecx[0].type == OPIHI_INT) && (vecy[0].type == OPIHI_FLT)) {
+    opihi_int *X = vecx[0].elements.Int;
+    opihi_flt *Y = vecy[0].elements.Flt;
+    for (i = 0; i < vecx[0].Nelements; i++, X++, Y++) {
+      if (*X < start) continue;
+      if (*X > end) continue;
+      if (*Y < ymax) continue;
+      xmax = *X;
+      ymax = *Y;
+      imax = i;
+    }      
+  }
+  if ((vecx[0].type == OPIHI_INT) && (vecy[0].type == OPIHI_INT)) {
+    opihi_int *X = vecx[0].elements.Int;
+    opihi_int *Y = vecy[0].elements.Int;
+    for (i = 0; i < vecx[0].Nelements; i++, X++, Y++) {
+      if (*X < start) continue;
+      if (*X > end) continue;
+      if (*Y < ymax) continue;
+      xmax = *X;
+      ymax = *Y;
+      imax = i;
+    }      
+  }
 
   set_variable ("peakval", ymax);
Index: /trunk/Ohana/src/opihi/cmd.data/periodogram.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/periodogram.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/periodogram.c	(revision 20936)
@@ -4,5 +4,5 @@
   
   int i, N, Npt, Np, NP, VERBOSE;
-  float *tv, *fv;
+  opihi_flt *tv, *fv;
   float minP, maxP, minT, maxT, dTime;
   float mean, var, w, tau, P, Pc, Ps, Po;
@@ -28,9 +28,12 @@
   if ((power = SelectVector (argv[6], ANYVECTOR, TRUE)) == NULL) return (FALSE);
 
+  REQUIRE_VECTOR_FLT (time, FALSE); 
+  REQUIRE_VECTOR_FLT (flux, FALSE); 
+
   /* find the max baseline, mean, and variance */
-  minT = maxT = time[0].elements[0];
+  minT = maxT = time[0].elements.Flt[0];
   Npt = time[0].Nelements;
-  tv = time[0].elements;
-  fv = flux[0].elements;
+  tv = time[0].elements.Flt;
+  fv = flux[0].elements.Flt;
   mean = var = 0;
   for (i = 0; i < Npt; i++, tv++, fv++) {
@@ -40,5 +43,5 @@
   }
   mean = mean / Npt;
-  fv = flux[0].elements;
+  fv = flux[0].elements.Flt;
   for (i = 0; i < Npt; i++, fv++) {
     var += SQ(*fv - mean);
@@ -56,6 +59,6 @@
   Np = 0;
   NP = 100;
-  REALLOCATE (power[0].elements, float, NP);
-  REALLOCATE (period[0].elements, float, NP);
+  ResetVector (power,  OPIHI_FLT, NP);
+  ResetVector (period, OPIHI_FLT, NP);
 
   P = minP;
@@ -64,5 +67,5 @@
     
     /* find the period offset tau  */
-    tv = time[0].elements;
+    tv = time[0].elements.Flt;
     cs = sn = 0;
     for (i = 0; i < Npt; i++, tv++) {
@@ -73,6 +76,6 @@
       
     /* find the power at this period */
-    tv = time[0].elements;
-    fv = flux[0].elements;
+    tv = time[0].elements.Flt;
+    fv = flux[0].elements.Flt;
     cs = sn = cs2 = sn2 = 0;
     for (i = 0; i < Npt; i++, tv++, fv++) {
@@ -90,11 +93,11 @@
     Po = (Pc + Ps) / (2*var);
 
-    power[0].elements[Np] = Po;
-    period[0].elements[Np] = P;
+    power[0].elements.Flt[Np] = Po;
+    period[0].elements.Flt[Np] = P;
     Np ++;
     if (Np >= NP) {
       NP += 100;
-      REALLOCATE (power[0].elements, float, NP);
-      REALLOCATE (period[0].elements, float, NP);
+      REALLOCATE (power[0].elements.Flt, opihi_flt, NP);
+      REALLOCATE (period[0].elements.Flt, opihi_flt, NP);
     }
 
@@ -106,8 +109,6 @@
   }
 
-  power[0].Nelements = Np;
-  period[0].Nelements = Np;
-  REALLOCATE (power[0].elements, float, Np);
-  REALLOCATE (period[0].elements, float, Np);
+  ResetVector (power,  OPIHI_FLT, Np);
+  ResetVector (period, OPIHI_FLT, Np);
  
   return (TRUE);
Index: /trunk/Ohana/src/opihi/cmd.data/plot.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/plot.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/plot.c	(revision 20936)
@@ -58,13 +58,13 @@
   if (!KapaPrepPlot (kapa, Npts, &graphmode)) return (FALSE);
   
-  KapaPlotVector (kapa, Npts, xvec[0].elements, "x");
-  KapaPlotVector (kapa, Npts, yvec[0].elements, "y");
+  PlotVectorSingle (kapa, xvec, "x");
+  PlotVectorSingle (kapa, yvec, "y");
   if (graphmode.etype & 0x01) {
-    KapaPlotVector (kapa, Npts, dymvec[0].elements, "dym");
-    KapaPlotVector (kapa, Npts, dypvec[0].elements, "dyp");
+    PlotVectorSingle (kapa, dymvec, "dym");
+    PlotVectorSingle (kapa, dypvec, "dyp");
   }
   if (graphmode.etype & 0x02) {
-    KapaPlotVector (kapa, Npts, dxmvec[0].elements, "dxm");
-    KapaPlotVector (kapa, Npts, dxpvec[0].elements, "dxp");
+    PlotVectorSingle (kapa, dxmvec, "dxm");
+    PlotVectorSingle (kapa, dxpvec, "dxp");
   }
   return (TRUE);
Index: /trunk/Ohana/src/opihi/cmd.data/read_vectors.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/read_vectors.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/read_vectors.c	(revision 20936)
@@ -70,4 +70,5 @@
       return (FALSE);    
     }
+    // XXX we could allow flags (eg, N.i) to specify INT vs FLT types vectors...
     colstr = argv[2*i+2];
     for (j = 0; j < strlen (colstr); j++) {
@@ -81,8 +82,9 @@
     col[i] = atof (colstr);
   }
-  
+
+  // currently, all read vectors are forced to be type FLT
   NELEM = 1000;
   for (i = 0; i < Nvec; i++) {
-    REALLOCATE (vec[i][0].elements, float, NELEM);
+    ResetVector (vec[i], OPIHI_FLT, NELEM);
   }
   
@@ -121,6 +123,6 @@
 	for (i = 0; (i < Nvec) && status; i++) {
 	  status = dparse (&value, col[i], c0);
-	  vec[i][0].elements[N] = value;
-	  if (!status) vec[i][0].elements[N] = 0.0/0.0;
+	  vec[i][0].elements.Flt[N] = value;
+	  if (!status) vec[i][0].elements.Flt[N] = NAN;
 	}
 	if (status) N++;
@@ -130,5 +132,5 @@
 	NELEM += 1000;
 	for (i = 0; i < Nvec; i++) {
-	  REALLOCATE (vec[i][0].elements, float, NELEM);
+	  REALLOCATE (vec[i][0].elements.Flt, opihi_flt, NELEM);
 	}
       }
@@ -137,5 +139,5 @@
   }
   for (i = 0; i < Nvec; i++) {
-    REALLOCATE (vec[i][0].elements, float, MAX (N,1));
+    REALLOCATE (vec[i][0].elements.Flt, opihi_flt, MAX (N,1));
     vec[i][0].Nelements = N;
   }
@@ -157,5 +159,5 @@
 int read_table_vectors (int argc, char **argv, char *extname) {
 
-  int i, j, k, N, Nbytes, Nextend, Ny, Binary;
+  int i, j, k, N, Nbytes, Nextend, Ny, Binary, vecType;
   char type[16], ID[80], *CCDKeyword;
   FTable table;
@@ -260,5 +262,11 @@
     }
     if (Nval == 0) ESCAPE ("no data for field in table");
-
+    
+    vecType = OPIHI_INT;
+    if (!strcmp (type, "double") || !strcmp (type, "float")) {
+      vecType = OPIHI_FLT;
+    }
+	
+    // define the multifield vector names
     ALLOCATE (vec, Vector *, Nval);
     for (j = 0; j < Nval; j++) {
@@ -268,6 +276,5 @@
 	sprintf (name, "%s:%d", argv[i], j);
       if ((vec[j] = SelectVector (name, ANYVECTOR, TRUE)) == NULL) ESCAPE ("bad vector name");
-      REALLOCATE (vec[j][0].elements, float, MAX (Ny,1));
-      vec[j][0].Nelements = Ny;
+      ResetVector (vec[j], vecType, MAX (Ny,1));
     }
 
@@ -276,5 +283,5 @@
       for (j = 0; j < Ny; j++) {
 	for (k = 0; k < Nval; k++, Pd++) {
-	  vec[k][0].elements[j] = *Pd;
+	  vec[k][0].elements.Flt[j] = *Pd;
 	}
       }
@@ -284,5 +291,5 @@
       for (j = 0; j < Ny; j++) {
 	for (k = 0; k < Nval; k++, Pf++) {
-	  vec[k][0].elements[j] = *Pf;
+	  vec[k][0].elements.Flt[j] = *Pf;
 	}
       }
@@ -292,5 +299,5 @@
       for (j = 0; j < Ny; j++) {
 	for (k = 0; k < Nval; k++, Pi++) {
-	  vec[k][0].elements[j] = *Pi;
+	  vec[k][0].elements.Int[j] = *Pi;
 	}
       }
@@ -300,5 +307,5 @@
       for (j = 0; j < Ny; j++) {
 	for (k = 0; k < Nval; k++, Ps++) {
-	  vec[k][0].elements[j] = *Ps;
+	  vec[k][0].elements.Int[j] = *Ps;
 	}
       }
@@ -308,5 +315,5 @@
       for (j = 0; j < Ny; j++) {
 	for (k = 0; k < Nval; k++, Pc++) {
-	  vec[k][0].elements[j] = *Pc;
+	  vec[k][0].elements.Int[j] = *Pc;
 	}
       }
Index: /trunk/Ohana/src/opihi/cmd.data/select.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/select.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/select.c	(revision 20936)
@@ -27,10 +27,51 @@
   /* check size of in1, in2, tvec: must match */
 
-  REALLOCATE (ovec[0].elements, float, MAX (tvec[0].Nelements, 1));
-  for (i = 0; i < tvec[0].Nelements; i++) {
-    ovec[0].elements[i] = tvec[0].elements[i] ? in1[0].elements[i] : in2[0].elements[i];
+  if ((in1->type == OPIHI_INT) && (in2->type == OPIHI_INT)) {
+    ResetVector (ovec, OPIHI_INT, MAX (tvec[0].Nelements, 1));
+  } else {
+    ResetVector (ovec, OPIHI_FLT, MAX (tvec[0].Nelements, 1));
   }
-  ovec[0].Nelements = tvec[0].Nelements;
-  REALLOCATE (ovec[0].elements, float, MAX (ovec[0].Nelements, 1));
+
+  // (in1 and in2) == (flt or int) and tvec == (flt or int)
+  if ((in1->type == OPIHI_FLT) && (in2->type == OPIHI_FLT) && (tvec->type == OPIHI_FLT)) {
+    for (i = 0; i < tvec[0].Nelements; i++) {
+      ovec[0].elements.Flt[i] = tvec[0].elements.Flt[i] ? in1[0].elements.Flt[i] : in2[0].elements.Flt[i];
+    }
+  }
+  if ((in1->type == OPIHI_FLT) && (in2->type == OPIHI_FLT) && (tvec->type == OPIHI_INT)) {
+    for (i = 0; i < tvec[0].Nelements; i++) {
+      ovec[0].elements.Flt[i] = tvec[0].elements.Int[i] ? in1[0].elements.Flt[i] : in2[0].elements.Flt[i];
+    }
+  }
+  if ((in1->type == OPIHI_INT) && (in2->type == OPIHI_FLT) && (tvec->type == OPIHI_FLT)) {
+    for (i = 0; i < tvec[0].Nelements; i++) {
+      ovec[0].elements.Flt[i] = tvec[0].elements.Flt[i] ? in1[0].elements.Int[i] : in2[0].elements.Flt[i];
+    }
+  }
+  if ((in1->type == OPIHI_INT) && (in2->type == OPIHI_FLT) && (tvec->type == OPIHI_INT)) {
+    for (i = 0; i < tvec[0].Nelements; i++) {
+      ovec[0].elements.Flt[i] = tvec[0].elements.Int[i] ? in1[0].elements.Int[i] : in2[0].elements.Flt[i];
+    }
+  }
+  if ((in1->type == OPIHI_FLT) && (in2->type == OPIHI_INT) && (tvec->type == OPIHI_FLT)) {
+    for (i = 0; i < tvec[0].Nelements; i++) {
+      ovec[0].elements.Flt[i] = tvec[0].elements.Flt[i] ? in1[0].elements.Flt[i] : in2[0].elements.Int[i];
+    }
+  }
+  if ((in1->type == OPIHI_FLT) && (in2->type == OPIHI_INT) && (tvec->type == OPIHI_INT)) {
+    for (i = 0; i < tvec[0].Nelements; i++) {
+      ovec[0].elements.Flt[i] = tvec[0].elements.Int[i] ? in1[0].elements.Flt[i] : in2[0].elements.Int[i];
+    }
+  }
+  if ((in1->type == OPIHI_INT) && (in2->type == OPIHI_INT) && (tvec->type == OPIHI_FLT)) {
+    for (i = 0; i < tvec[0].Nelements; i++) {
+      ovec[0].elements.Int[i] = tvec[0].elements.Flt[i] ? in1[0].elements.Int[i] : in2[0].elements.Int[i];
+    }
+  }
+  if ((in1->type == OPIHI_INT) && (in2->type == OPIHI_INT) && (tvec->type == OPIHI_INT)) {
+    for (i = 0; i < tvec[0].Nelements; i++) {
+      ovec[0].elements.Int[i] = tvec[0].elements.Int[i] ? in1[0].elements.Int[i] : in2[0].elements.Int[i];
+    }
+  }
   
   DeleteVector (tvec);
Index: /trunk/Ohana/src/opihi/cmd.data/sort.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/sort.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/sort.c	(revision 20936)
@@ -1,8 +1,41 @@
 # include "data.h"
 
+void fsortindex (opihi_flt *X, int *IDX, int N) {
+
+# define SWAPFUNC(A,B){ opihi_flt tmp; int itmp; 	\
+  tmp = X[A]; X[A] = X[B]; X[B] = tmp; \
+  itmp = IDX[A]; IDX[A] = IDX[B]; IDX[B] = itmp; \
+}
+# define COMPARE(A,B)(X[A] < X[B])
+
+  OHANA_SORT (N, COMPARE, SWAPFUNC);
+
+# undef SWAPFUNC
+# undef COMPARE
+
+}
+
+void isortindex (opihi_int *X, int *IDX, int N) {
+
+# define SWAPFUNC(A,B){ opihi_int tmp; int itmp; 	\
+  tmp = X[A]; X[A] = X[B]; X[B] = tmp; \
+  itmp = IDX[A]; IDX[A] = IDX[B]; IDX[B] = itmp; \
+}
+# define COMPARE(A,B)(X[A] < X[B])
+
+  OHANA_SORT (N, COMPARE, SWAPFUNC);
+
+# undef SWAPFUNC
+# undef COMPARE
+
+}
+
+// XXX add an option to NOT sort, but return an index instead?
 int sort_vectors (int argc, char **argv) {
   
   int i, j, Nvec, Nval;
-  float *temp, *index, *T, *V, *I;
+  opihi_flt *ftemp;
+  opihi_int *itemp;
+  int *index, *I;
   Vector **vec;
 
@@ -35,24 +68,43 @@
   }
   
-  /* create index (use float to use sortpair) */
-  ALLOCATE (index, float, Nval);
+  /* create index */
+  ALLOCATE (index, int, Nval);
   for (i = 0; i < Nval; i++) index[i] = i;
 
   /* sort key & index */
-  fsortpair (vec[0][0].elements, index, Nval);
+  if (vec[0][0].type == OPIHI_FLT) {
+    fsortindex (vec[0][0].elements.Flt, index, Nval);
+  } else {
+    isortindex (vec[0][0].elements.Int, index, Nval);
+  }
 
-  ALLOCATE (temp, float, Nval);
+  ALLOCATE (ftemp, opihi_flt, Nval);
+  ALLOCATE (itemp, opihi_int, Nval);
+
   for (i = 1; i < Nvec; i++) {
-    T = temp;
-    V = vec[i][0].elements;
-    I = index;
-    for (j = 0; j < Nval; j++, T++, I++) {
-      *T = V[(int)(*I)];
+    if (vec[i][0].type == OPIHI_FLT) {
+      opihi_flt *T = ftemp;
+      opihi_flt *V = vec[i][0].elements.Flt;
+      I = index;
+      for (j = 0; j < Nval; j++, T++, I++) {
+	*T = V[*I];
+      }
+      /* swap .elements.Flt (== V) and ftemp */ 
+      vec[i][0].elements.Flt = ftemp;
+      ftemp = V;
+    } else {
+      opihi_int *T = itemp;
+      opihi_int *V = vec[i][0].elements.Int;
+      I = index;
+      for (j = 0; j < Nval; j++, T++, I++) {
+	*T = V[*I];
+      }
+      /* swap .elements.Flt (== V) and itemp */ 
+      vec[i][0].elements.Int = itemp;
+      itemp = V;
     }
-    /* swap .elements (== V) and temp */ 
-    vec[i][0].elements = temp;
-    temp = V;
   }
-  free (temp);
+  free (itemp);
+  free (ftemp);
   free (vec);
   free (index);
@@ -61,4 +113,2 @@
 
 }
-
-
Index: /trunk/Ohana/src/opihi/cmd.data/subset.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/subset.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/subset.c	(revision 20936)
@@ -6,5 +6,5 @@
   
   char *out;
-  int  i, j, size;
+  int  i, Npts, size;
   Vector *ivec, *ovec, *tvec;
 
@@ -28,13 +28,47 @@
   /* check size of ivec, tvec: must match */
 
-  REALLOCATE (ovec[0].elements, float, MAX (tvec[0].Nelements, 1));
-  for (j = i = 0; i < tvec[0].Nelements; i++) {
-    if (tvec[0].elements[i]) {
-      ovec[0].elements[j] = ivec[0].elements[i];
-      j++;
+  // ovec matches ivec in type
+  ResetVector (ovec, ivec->type, MAX (tvec[0].Nelements, 1));
+
+  // we have four cases: (ivec == flt or int) and (tvec == flt or int)
+  if ((ivec->type == OPIHI_FLT) && (tvec->type == OPIHI_FLT)) {
+    opihi_flt *vi = ivec[0].elements.Flt;
+    opihi_flt *vt = tvec[0].elements.Flt;
+    for (Npts = i = 0; i < tvec[0].Nelements; i++, vi++, vt++) {
+      if (!*vt) continue;
+      ovec[0].elements.Flt[Npts] = *vi;
+      Npts++;
     }
   }
-  ovec[0].Nelements = j;
-  REALLOCATE (ovec[0].elements, float, MAX (ovec[0].Nelements, 1));
+  if ((ivec->type == OPIHI_FLT) && (tvec->type == OPIHI_INT)) {
+    opihi_flt *vi = ivec[0].elements.Flt;
+    opihi_int *vt = tvec[0].elements.Int;
+    for (Npts = i = 0; i < tvec[0].Nelements; i++, vi++, vt++) {
+      if (!*vt) continue;
+      ovec[0].elements.Flt[Npts] = *vi;
+      Npts++;
+    }
+  }
+  if ((ivec->type == OPIHI_INT) && (tvec->type == OPIHI_FLT)) {
+    opihi_int *vi = ivec[0].elements.Int;
+    opihi_flt *vt = tvec[0].elements.Flt;
+    for (Npts = i = 0; i < tvec[0].Nelements; i++, vi++, vt++) {
+      if (!*vt) continue;
+      ovec[0].elements.Int[Npts] = *vi;
+      Npts++;
+    }
+  }
+  if ((ivec->type == OPIHI_INT) && (tvec->type == OPIHI_INT)) {
+    opihi_int *vi = ivec[0].elements.Int;
+    opihi_int *vt = tvec[0].elements.Int;
+    for (Npts = i = 0; i < tvec[0].Nelements; i++, vi++, vt++) {
+      if (!*vt) continue;
+      ovec[0].elements.Int[Npts] = *vi;
+      Npts++;
+    }
+  }
+
+  // free up unused memory
+  ResetVector (ovec, ivec->type, MAX (Npts, 1));
 
   DeleteVector (tvec);
Index: /trunk/Ohana/src/opihi/cmd.data/svd.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/svd.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/svd.c	(revision 20936)
@@ -4,7 +4,8 @@
   
   int i, Nx, Ny, status;
-  float *in, *out, *A, *U, *W, *V;
+  float *in, *out, *A, *U, *V;
+  Buffer *Ma, *Mu, *Mv;
   Vector *Vw;
-  Buffer *Ma, *Mu, *Mv;
+  opihi_flt *W;
 
   if (argc != 6) goto usage;
@@ -42,12 +43,11 @@
 
   /* w is Nx */
-  Vw[0].Nelements = Nx;
-  REALLOCATE (Vw[0].elements, float, Nx);
+  ResetVector (Vw, OPIHI_FLT, Nx);
 
   /* pointers to the various arrays */
   A = (float *) Ma[0].matrix.buffer;
   U = (float *) Mu[0].matrix.buffer;
-  W = (float *) Vw[0].elements;
   V = (float *) Mv[0].matrix.buffer;
+  W = Vw[0].elements.Flt;
 
   /* copy A to U (svdcmp replaces A with U) */
Index: /trunk/Ohana/src/opihi/cmd.data/test/applyfit2d.sh
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/test/applyfit2d.sh	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/test/applyfit2d.sh	(revision 20936)
@@ -32,4 +32,5 @@
 
 # Memory test
+# NOTE: requires test1 to be run first
 macro memtest1
 
@@ -48,5 +49,5 @@
  $PASS = 1
 
- if ($endmem - $startmem > 10)
+ if (($endmem - $startmem)/1000 > 1.0)
    $PASS = 0
    echo "growth: {$endmem-$startmem}"
Index: /trunk/Ohana/src/opihi/cmd.data/test/fit.sh
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/test/fit.sh	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/test/fit.sh	(revision 20936)
@@ -47,10 +47,13 @@
  if ($Cn != 1)
    $PASS = 0
- end
- if (abs($C0 - 3) > 0.01)
-   $PASS = 0
- end
- if (abs($C1 - 5) > 0.01)
-   $PASS = 0
+   echo "wrong number of elements : $Cn"
+ end
+ if (abs($C0 - 3) > 0.06)
+   $PASS = 0
+   echo "wrong value for C0 : $C0"
+ end
+ if (abs($C1 - 5) > 0.06)
+   $PASS = 0
+   echo "wrong value for C1 : $C1"
  end
 end
@@ -72,8 +75,8 @@
    $PASS = 0
  end
- if (abs($C0 - 3) > 0.02)
-   $PASS = 0
- end
- if (abs($C1 - 5) > 0.02)
+ if (abs($C0 - 3) > 0.06)
+   $PASS = 0
+ end
+ if (abs($C1 - 5) > 0.06)
    $PASS = 0
  end
@@ -102,8 +105,8 @@
    $PASS = 0
  end
- if (abs($C0 - 3) > 0.02)
-   $PASS = 0
- end
- if (abs($C1 - 5) > 0.02)
+ if (abs($C0 - 3) > 0.06)
+   $PASS = 0
+ end
+ if (abs($C1 - 5) > 0.06)
    $PASS = 0
  end
@@ -150,11 +153,11 @@
    $PASS = 0
  end
- if (abs($C0 - 3) > 0.05)
-   $PASS = 0
- end
- if (abs($C1 - 5) > 0.05)
-   $PASS = 0
- end
- if (abs($C2 + 4) > 0.05)
+ if (abs($C0 - 3) > 0.06)
+   $PASS = 0
+ end
+ if (abs($C1 - 5) > 0.06)
+   $PASS = 0
+ end
+ if (abs($C2 + 4) > 0.06)
    $PASS = 0
  end
@@ -177,11 +180,11 @@
    $PASS = 0
  end
- if (abs($C0 - 3) > 0.05)
-   $PASS = 0
- end
- if (abs($C1 - 5) > 0.05)
-   $PASS = 0
- end
- if (abs($C2 + 4) > 0.05)
+ if (abs($C0 - 3) > 0.06)
+   $PASS = 0
+ end
+ if (abs($C1 - 5) > 0.06)
+   $PASS = 0
+ end
+ if (abs($C2 + 4) > 0.06)
    $PASS = 0
  end
@@ -212,12 +215,12 @@
    $PASS = 0
  end
- if (abs($C0 - 3) > 0.05)
-   $PASS = 0
- end
- if (abs($C1 - 5) > 0.05)
-   $PASS = 0
- end
- if (abs($C2 + 4) > 0.05)
-   $PASS = 0
- end
-end
+ if (abs($C0 - 3) > 0.06)
+   $PASS = 0
+ end
+ if (abs($C1 - 5) > 0.06)
+   $PASS = 0
+ end
+ if (abs($C2 + 4) > 0.06)
+   $PASS = 0
+ end
+end
Index: /trunk/Ohana/src/opihi/cmd.data/test/gaussj.sh
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/test/gaussj.sh	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/test/gaussj.sh	(revision 20936)
@@ -232,5 +232,7 @@
  for i 0 B[]
   for j 0 B[]
+   # echo $i $j meas[$i] inA[$i][$j] B[$j] {inA[$i][$j] * B[$j]} {meas[$i] + inA[$i][$j] * B[$j]}
    meas[$i] = meas[$i] + inA[$i][$j] * B[$j]
+   # echo "-> meas[$i]"
   end
  end
@@ -238,4 +240,5 @@
  for i 0 inB[]
   if (abs(inB[$i]-meas[$i]) > 1e-5)
+    echo inB[$i] meas[$i] {abs(inB[$i]-meas[$i])}
     $PASS = 0
   end
Index: /trunk/Ohana/src/opihi/cmd.data/test/histogram.sh
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/test/histogram.sh	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/test/histogram.sh	(revision 20936)
@@ -12,5 +12,6 @@
  local i
 
- create x 0 10 0.1
+ # set data values at the i*0.1 + 0.05 values so round-off does not causs miscounts
+ create x 0.05 10.05 0.1
 
  for i 45 55
@@ -18,4 +19,5 @@
  end
 
+ # histogram bins are 0-0.1, 0.1-0.2, etc
  histogram x xhis 0 10 0.1
 
Index: /trunk/Ohana/src/opihi/cmd.data/test/peak.sh
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/test/peak.sh	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/test/peak.sh	(revision 20936)
@@ -21,5 +21,5 @@
    $PASS = 0
  end
- if ($peaknum != 51)
+ if ($peaknum != 50)
    $PASS = 0
  end
@@ -43,5 +43,5 @@
    $PASS = 0
  end
- if ($peaknum != 51)
+ if ($peaknum != 50)
    $PASS = 0
  end
@@ -67,5 +67,5 @@
    $PASS = 0
  end
- if ($peaknum != 51)
+ if ($peaknum != 50)
    $PASS = 0
  end
Index: /trunk/Ohana/src/opihi/cmd.data/test/vgauss.sh
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/test/vgauss.sh	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/test/vgauss.sh	(revision 20936)
@@ -20,4 +20,6 @@
 
  vgauss -q x y dy yfit
+ # lim x y; clear; box; plot -x 1 -c black x y; plot -c red x yfit
+ # cursor
 
  if (abs($C0 - 0.0) > 0.01)
@@ -51,4 +53,6 @@
 
  vgauss -q x y dy yfit
+ # lim x y; clear; box; plot -x 1 -c black x y; plot -c red x yfit
+ # cursor
 
  if (abs($C0 - 0.0) > 0.01)
@@ -71,6 +75,11 @@
  break -auto off
 
+ $C0o = 0.5
+ $C1o = 2
+ $C2o = 900
+ $C3o = 1
+
  create x -10 10 0.1
- set y = 1000 * exp(-0.5*x^2/3^2)
+ set y = $C3o + $C2o * exp(-0.5*(x - $C0o)^2/$C1o^2)
 
  gaussdev dY y[] 0.0 1.0
@@ -78,21 +87,25 @@
  set y = y + dy
 
- $C0 = 0.5
- $C1 = 2
- $C2 = 900
- $C3 = 1
+ $C0 = $C0o + 2
+ $C1 = $C1o + 2
+ $C2 = $C2o + 50
+ $C3 = $C3o + 10
 
  vgauss -q x y dy yfit
+ # lim x y; clear; box; plot -x 1 -c black x y; plot -c red x yfit
+ # cursor
 
- if (abs($C0 - 0.0) > 0.01)
+ $dS = 3.0 / sqrt(y[])
+
+ if (abs($C0 - $C0o) > $dS)
    $PASS = 0
  end
- if (abs($C1 - 3.0) > 0.01)
+ if (abs($C1 - $C1o)/$C1o > $dS)
    $PASS = 0
  end
- if (abs($C2 - 1000.0) > 1)
+ if (abs($C2 - $C2o)/$C2o > $dS)
    $PASS = 0
  end
- if (abs($C3 - 0.0) > 0.2)
+ if (abs($C3 - $C3o) > $dS)
    $PASS = 0
  end
Index: /trunk/Ohana/src/opihi/cmd.data/test/vmaxwell.sh
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/test/vmaxwell.sh	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/test/vmaxwell.sh	(revision 20936)
@@ -40,30 +40,40 @@
  break -auto off
 
+ $C0o = 250
+ $C1o = 25
+ $C2o = 100
+ $C3o = 1
+ $C4o = 10
+
  create x 0 1000 1
- set y = 1000 * (x-200)^2 * exp(-0.5*(x-300)^2/30^2)
- set dy = (rnd(y) - 0.5)/0.5
+ set y = $C2o * (x-$C4o)^2 * exp(-0.5*(x-$C0o)^2/$C1o^2) + $C3o
+ gaussdev dY y[] 0.0 1.0
+ set dy = dY * sqrt(y)
  set y = y + dy
 
- lim x y; clear; box; plot -x 1 -c black x y
+ $C0 = $C0o + 20
+ $C1 = $C1o + 2
+ $C2 = $C2o + 100
+ $C3 = $C3o + 10
+ $C4 = $C4o + 20
 
- $C0 = 250
- $C1 = 25
- $C2 = 900
- $C3 = 1
- $C4 = 190
+ vmaxwell -q x y dy yfit
+ lim x y; clear; box; plot -x 1 -c black x y; plot x yfit -c red
 
- vmaxwell x y dy yfit
- plot x yfit -c red
+ $dS = 6.0 / sqrt(y[])
 
- if (abs($C0 - 0.0) > 0.01)
+ if (abs($C0 - $C0o) > $dS)
    $PASS = 0
  end
- if (abs($C1 - 3.0) > 0.01)
+ if (abs($C1 - $C1o)/$C1o > $dS)
    $PASS = 0
  end
- if (abs($C2 - 1000.0) > 0.1)
+ if (abs($C2 - $C2o)/$C2o > $dS)
    $PASS = 0
  end
- if (abs($C3 - 0.0) > 0.1)
+ if (abs($C3 - $C3o) > $dS)
+   $PASS = 0
+ end
+ if (abs($C4 - $C4o)/$C4o > $dS)
    $PASS = 0
  end
Index: /trunk/Ohana/src/opihi/cmd.data/ungridify.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/ungridify.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/ungridify.c	(revision 20936)
@@ -1,4 +1,5 @@
 # include "data.h"
 
+// XXX adapt this to accept an optional region to limit the areas, otherwise use the whole image
 int ungridify (int argc, char **argv) {
 
@@ -6,10 +7,12 @@
   int Nx, Ny, NX, NY;
   int Xmin, Xmax, Ymin, Ymax;
-  float *v, *x, *y, *z;
   Buffer *bf;
+  float *v;
   Vector *vx, *vy, *vz;
+  opihi_flt *x, *y, *z;
 
   if (argc != 9) {
     gprint (GP_ERR, "USAGE: ungridify buffer Xmin Xmax Ymin Ymax x y z\n");
+    gprint (GP_ERR, "  convert a portion of an image to a collection a triplet of vectors\n");
     return (FALSE);
   }
@@ -29,26 +32,28 @@
   if ((vy = SelectVector (argv[7], ANYVECTOR, TRUE)) == NULL) return (FALSE);
   if ((vz = SelectVector (argv[8], ANYVECTOR, TRUE)) == NULL) return (FALSE);
-  REALLOCATE (vx[0].elements, float, Nx*Ny);
-  REALLOCATE (vy[0].elements, float, Nx*Ny);
-  REALLOCATE (vz[0].elements, float, Nx*Ny);
 
-  x = vx[0].elements;
-  y = vy[0].elements;
-  z = vz[0].elements;
+  ResetVector (vx, OPIHI_FLT, Nx*Ny);
+  ResetVector (vy, OPIHI_FLT, Nx*Ny);
+  ResetVector (vz, OPIHI_FLT, Nx*Ny);
+
+  x = vx[0].elements.Flt;
+  y = vy[0].elements.Flt;
+  z = vz[0].elements.Flt;
   n = 0;
   v = (float *)bf[0].matrix.buffer;
   for (j = Ymin; j < Ymax; j++) {
     for (i = Xmin; i < Xmax; i++, x++, y++, z++, n++) {
-      vx[0].elements[n] = i;
-      vy[0].elements[n] = j;
+      vx[0].elements.Flt[n] = i;
+      vy[0].elements.Flt[n] = j;
       if (i < 0) continue;
       if (i >= NX) continue;
       if (j < 0) continue;
       if (j >= NY) continue;
-      vz[0].elements[n] = v[i+j*NX];
+      vz[0].elements.Flt[n] = v[i+j*NX];
     }
   }
   if (n != Nx*Ny) {
     gprint (GP_ERR, "error in ungrid: %d vs %d (%d x %d)\n", n, Nx*Ny, Nx, Ny);
+    gprint (GP_ERR, "(this is probably a programming error in ungridify)\n");
   }
   vx[0].Nelements = vy[0].Nelements = vz[0].Nelements = n;
Index: /trunk/Ohana/src/opihi/cmd.data/uniq.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/uniq.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/uniq.c	(revision 20936)
@@ -4,5 +4,4 @@
   
   int Nnew, i, j, found;
-  float *v1, *v2;
   Vector *ivec, *ovec;
 
@@ -16,22 +15,38 @@
 
   /* allocate the maximum possible needed */
-  ALLOCATE (ovec[0].elements, float, ivec[0].Nelements);
+  ResetVector (ovec, ivec->type, ivec->Nelements);
 
   Nnew = 0;
-  v1 = ivec[0].elements;
-  for (i = 0; i < ivec[0].Nelements; i++, v1++) {
-    v2 = ovec[0].elements;
-    found = FALSE;
-    for (j = 0; !found && (j < Nnew); j++, v2++) {
-      if (*v1 == *v2) found = TRUE;
+
+  if (ivec->type == OPIHI_FLT) {
+    opihi_flt *v1 = ivec[0].elements.Flt;
+    for (i = 0; i < ivec[0].Nelements; i++, v1++) {
+      opihi_flt *v2 = ovec[0].elements.Flt;
+      found = FALSE;
+      for (j = 0; !found && (j < Nnew); j++, v2++) {
+	if (*v1 == *v2) found = TRUE;
+      }
+      if (!found) {
+	ovec[0].elements.Flt[Nnew] = *v1;
+	Nnew ++;
+      }
     }
-    if (!found) {
-      ovec[0].elements[Nnew] = *v1;
-      Nnew ++;
+  } else {
+    opihi_int *v1 = ivec[0].elements.Int;
+    for (i = 0; i < ivec[0].Nelements; i++, v1++) {
+      opihi_int *v2 = ovec[0].elements.Int;
+      found = FALSE;
+      for (j = 0; !found && (j < Nnew); j++, v2++) {
+	if (*v1 == *v2) found = TRUE;
+      }
+      if (!found) {
+	ovec[0].elements.Int[Nnew] = *v1;
+	Nnew ++;
+      }
     }
   }
 
-  ovec[0].Nelements = Nnew;
-  REALLOCATE (ovec[0].elements, float, ovec[0].Nelements);
+  // free up extra memory
+  ResetVector (ovec, ivec->type, Nnew);
 
   return (TRUE);
Index: /trunk/Ohana/src/opihi/cmd.data/vbin.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/vbin.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/vbin.c	(revision 20936)
@@ -5,5 +5,5 @@
   int i, j, n, N, Nin, Nout;
   int Normalize, Ignore;
-  float *Vout, *Vin, IgnoreValue;
+  opihi_flt *Vout, IgnoreValue;
   double scale;
   Vector *in, *out;
@@ -42,22 +42,43 @@
   Nout = Nin / scale;
 
-  REALLOCATE (out[0].elements, float, Nout);
-  out[0].Nelements = Nout;
+  // re-binning creates a float vector
+  ResetVector (out, OPIHI_FLT, in[0].Nelements);
 
-  Vin  = in[0].elements;
-  Vout = out[0].elements;
-  for (n = j = 0; j < Nout; j++, Vout++) {
-    *Vout = 0;
-    for (N = i = 0; (i < scale) && (n < Nin); n++, i++, Vin++) {
-      if (!finite (*Vin)) continue;
-      if (Ignore && (*Vin == IgnoreValue)) continue;
-      *Vout += *Vin;
-      N ++;
-    } 
-    if (Normalize) {
-      if (N > 0) { 
-	*Vout /= (float) N; 
-      } else {
-	*Vout = 0;
+  Vout = out[0].elements.Flt;
+
+  if (in[0].type == OPIHI_FLT) {
+    opihi_flt *Vin  = in[0].elements.Flt;
+    for (n = j = 0; j < Nout; j++, Vout++) {
+      *Vout = 0;
+      for (N = i = 0; (i < scale) && (n < Nin); n++, i++, Vin++) {
+	if (!finite (*Vin)) continue;
+	if (Ignore && (*Vin == IgnoreValue)) continue;
+	*Vout += *Vin;
+	N ++;
+      } 
+      if (Normalize) {
+	if (N > 0) { 
+	  *Vout /= (opihi_flt) N; 
+	} else {
+	  *Vout = 0;
+	}
+      }
+    }
+  } else {
+    opihi_int *Vin  = in[0].elements.Int;
+    for (n = j = 0; j < Nout; j++, Vout++) {
+      *Vout = 0;
+      for (N = i = 0; (i < scale) && (n < Nin); n++, i++, Vin++) {
+	if (!finite (*Vin)) continue;
+	if (Ignore && (*Vin == IgnoreValue)) continue;
+	*Vout += *Vin;
+	N ++;
+      } 
+      if (Normalize) {
+	if (N > 0) { 
+	  *Vout /= (opihi_flt) N; 
+	} else {
+	  *Vout = 0;
+	}
       }
     }
Index: /trunk/Ohana/src/opihi/cmd.data/vclip.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/vclip.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/vclip.c	(revision 20936)
@@ -3,7 +3,6 @@
 int vclip (int argc, char **argv) {
 
-  int i, Npix, DO_NAN, DO_INF, N;
+  int i, Npix, DO_NAN, DO_INF, DO_CLIP, N;
   double min, Vmin, max, Vmax, nan_val, inf_val;
-  float *in;
   Vector *vec;
 
@@ -33,4 +32,5 @@
   if ((vec = SelectVector (argv[1], OLDVECTOR, TRUE)) == NULL) return (FALSE);
 
+  DO_CLIP = FALSE;
   if (argc == 6) {
     min = atof (argv[2]);
@@ -38,36 +38,46 @@
     max = atof (argv[4]);
     Vmax = atof (argv[5]);
+    DO_CLIP = TRUE;
   }
 
+  if (DO_NAN && vec[0].type == OPIHI_INT) {
+    gprint (GP_ERR, "  warning : clipping on NAN is invalid for INT vectors\n");
+    return (FALSE);
+  }
+    
+  if (DO_INF && vec[0].type == OPIHI_INT) {
+    gprint (GP_ERR, "  warning : clipping on INF is invalid for INT vectors\n");
+    return (FALSE);
+  }
+    
   Npix = vec[0].Nelements;
-  in =   vec[0].elements;
 
-  if (argc == 6) {
+  if (vec[0].type == OPIHI_FLT) {
+    opihi_flt *in =  vec[0].elements.Flt;
     for (i = 0; i < Npix; i++, in++) {
-      if (*in < min) 
+      if (DO_CLIP && (*in < min)) {
 	*in = Vmin;
-      if (*in > max)
+      }
+      if (DO_CLIP && (*in > max)) {
 	*in = Vmax;
-    }
-  }
-  in = vec[0].elements;
-  if (DO_NAN) {
-    for (i = 0; i < Npix; i++, in++) {
-      if (isnan (*in)) {
+      }
+      if (!finite (*in) && DO_INF) {
+	*in = inf_val;
+      }
+      if (isnan (*in) && DO_NAN) {
 	*in = nan_val;
       }
     }
-  }
-  in = vec[0].elements;
-  if (DO_INF) {
+  } else {
+    opihi_int *in =  vec[0].elements.Int;
     for (i = 0; i < Npix; i++, in++) {
-      if (!finite (*in)) {
-	*in = inf_val;
+      if (DO_CLIP && (*in < min)) {
+	*in = Vmin;
+      }
+      if (DO_CLIP && (*in > max)) {
+	*in = Vmax;
       }
     }
   }
   return (TRUE);
-
 }
-
-
Index: /trunk/Ohana/src/opihi/cmd.data/vgauss.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/vgauss.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/vgauss.c	(revision 20936)
@@ -2,5 +2,5 @@
 
 /* local private functions */
-float fgaussOD (float, float *, int, float *);
+opihi_flt fgaussOD (opihi_flt, opihi_flt *, int, opihi_flt *);
 
 # define GET_VAR(V,A) \
@@ -16,6 +16,6 @@
 
   int i, N, Npts, Npar, Quiet;
-  float par[4], *v1, *v2, *dy, **covar;
-  float chisq, ochisq, dchisq;
+  opihi_flt par[4], *v1, *v2, *dy, **covar;
+  opihi_flt chisq, ochisq, dchisq;
   Vector *xvec, *yvec, *svec, *ovec;
   char *c, name[16];
@@ -42,7 +42,12 @@
   if ((ovec = SelectVector (argv[4], ANYVECTOR, TRUE)) == NULL) return (FALSE);
 
+  REQUIRE_VECTOR_FLT (xvec, FALSE); 
+  REQUIRE_VECTOR_FLT (yvec, FALSE); 
+  REQUIRE_VECTOR_FLT (svec, FALSE); 
+
   Npts = xvec[0].Nelements;
-  ALLOCATE (dy, float, Npts);
-  REALLOCATE (ovec[0].elements, float, Npts);
+  ResetVector (ovec, OPIHI_FLT, Npts);
+
+  ALLOCATE (dy, opihi_flt, Npts);
 
   GET_VAR (par[0], "C0");
@@ -52,5 +57,6 @@
   Npar = 4;
 
-  v1 = svec[0].elements;
+  // mrqmin takes the inverse variance (do not generate NANs)
+  v1 = svec[0].elements.Flt;
   v2 = dy;
   for (i = 0; i < Npts; i++, v1++, v2++) {
@@ -58,9 +64,9 @@
   } 
   
-  ochisq = mrqinit (xvec[0].elements, yvec[0].elements, dy, Npts, par, Npar, fgaussOD, !Quiet);
+  ochisq = mrqinit (xvec[0].elements.Flt, yvec[0].elements.Flt, dy, Npts, par, Npar, fgaussOD, !Quiet);
   dchisq = ochisq + 2*Npts;
 
   for (i = 0; (i < 20) && ((dchisq > 0.1*(Npts - Npar)) || (dchisq <= 0.0)); i++) {
-    chisq = mrqmin (xvec[0].elements, yvec[0].elements, dy, Npts, par, Npar, fgaussOD, !Quiet);
+    chisq = mrqmin (xvec[0].elements.Flt, yvec[0].elements.Flt, dy, Npts, par, Npar, fgaussOD, !Quiet);
     dchisq = ochisq - chisq;
     ochisq = chisq;
@@ -70,5 +76,5 @@
 
   for (i = 0; i < Npts; i++) {
-    ovec[0].elements[i] = fgaussOD (xvec[0].elements[i], par, Npar, dy);
+    ovec[0].elements.Flt[i] = fgaussOD (xvec[0].elements.Flt[i], par, Npar, dy);
   }
   ovec[0].Nelements = Npts;
@@ -90,7 +96,7 @@
 
 /* pars: x_o, sigma, I, back */
-float fgaussOD (float x, float *par, int Npar, float *dpar) {
+opihi_flt fgaussOD (opihi_flt x, opihi_flt *par, int Npar, opihi_flt *dpar) {
 
-  float z, r, f;
+  opihi_flt z, r, f;
 
   z = (x - par[0])/par[1];
Index: /trunk/Ohana/src/opihi/cmd.data/vgrid.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/vgrid.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/vgrid.c	(revision 20936)
@@ -5,5 +5,6 @@
   int i, Nx, Ny, Xb, Yb;
   float Xmin, Xmax, dX, Ymin, Ymax, dY;
-  float *buf, *val, *x, *y, *z;
+  float *buf;
+  opihi_flt *val, *x, *y, *z;
   int *Nval;
   Buffer *bf;
@@ -12,4 +13,6 @@
   if (argc != 11) {
     gprint (GP_ERR, "USAGE: vgrid x y z buffer Xmin Xmax dX Ymin Ymax dY\n");
+    gprint (GP_ERR, "  re-grid values from a triplet of vectors (x,y,z) into an image\n");
+    gprint (GP_ERR, "  the vectors must be floating-point type\n");
     return (FALSE);
   }
@@ -22,4 +25,8 @@
   if (vx[0].Nelements != vy[0].Nelements) return (FALSE);
   if (vx[0].Nelements != vz[0].Nelements) return (FALSE);
+
+  REQUIRE_VECTOR_FLT (vx, FALSE); 
+  REQUIRE_VECTOR_FLT (vy, FALSE); 
+  REQUIRE_VECTOR_FLT (vz, FALSE); 
 
   Xmin = atof (argv[5]);
@@ -39,12 +46,12 @@
   strcpy (bf[0].file, "(empty)");
 
-  ALLOCATE (val, float, Nx*Ny);
-  bzero (val, Nx*Ny*sizeof(float));
+  ALLOCATE (val, opihi_flt, Nx*Ny);
+  bzero (val, Nx*Ny*sizeof(opihi_flt));
   ALLOCATE (Nval, int, Nx*Ny);
   bzero (Nval, Nx*Ny*sizeof(int));
 
-  x = vx[0].elements;
-  y = vy[0].elements;
-  z = vz[0].elements;
+  x = vx[0].elements.Flt;
+  y = vy[0].elements.Flt;
+  z = vz[0].elements.Flt;
   for (i = 0; i < vx[0].Nelements; i++, x++, y++, z++) {
     Xb = (*x - Xmin) / dX;
Index: /trunk/Ohana/src/opihi/cmd.data/vload.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/vload.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/vload.c	(revision 20936)
@@ -6,5 +6,5 @@
   int kapa, type;
   char *name;
-  double dx, dy, size, angle;
+  double dx, dy, angle;
   KiiOverlay *overlay;
   Vector *vecx, *vecy;
@@ -82,6 +82,8 @@
     overlay[i].type = type;
     overlay[i].text = NULL;
-    overlay[i].x = vecx[0].elements[i]+0.5;
-    overlay[i].y = vecy[0].elements[i]+0.5;
+    overlay[i].x = (vecx[0].type == OPIHI_FLT) ? vecx[0].elements.Flt[i] : vecx[0].elements.Int[i];
+    overlay[i].y = (vecy[0].type == OPIHI_FLT) ? vecy[0].elements.Flt[i] : vecy[0].elements.Int[i];
+    overlay[i].x += 0.5;
+    overlay[i].y += 0.5;
     overlay[i].dx = dx;
     overlay[i].dy = dy;
Index: /trunk/Ohana/src/opihi/cmd.data/vmaxwell.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/vmaxwell.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/vmaxwell.c	(revision 20936)
@@ -2,5 +2,5 @@
 
 /* local private functions */
-float fmaxwellOD (float, float *, int, float *);
+opihi_flt fmaxwellOD (opihi_flt, opihi_flt *, int, opihi_flt *);
 
 # define GET_VAR(V,A) \
@@ -16,6 +16,6 @@
 
   int i, N, Npts, Npar, Quiet;
-  float par[5], *v1, *v2, *dy, **covar;
-  float chisq, ochisq, dchisq;
+  opihi_flt par[5], *v1, *v2, *dy, **covar;
+  opihi_flt chisq, ochisq, dchisq;
   Vector *xvec, *yvec, *svec, *ovec;
   char *c, name[16];
@@ -42,7 +42,11 @@
   if ((ovec = SelectVector (argv[4], ANYVECTOR, TRUE)) == NULL) return (FALSE);
 
+  REQUIRE_VECTOR_FLT (xvec, FALSE); 
+  REQUIRE_VECTOR_FLT (yvec, FALSE); 
+  REQUIRE_VECTOR_FLT (svec, FALSE); 
+
   Npts = xvec[0].Nelements;
-  ALLOCATE (dy, float, Npts);
-  REALLOCATE (ovec[0].elements, float, Npts);
+  ALLOCATE (dy, opihi_flt, Npts);
+  ResetVector (ovec, OPIHI_FLT, Npts);
 
   GET_VAR (par[0], "C0");
@@ -54,13 +58,13 @@
   /* careful of variable renomalization */
 
-  v1 = svec[0].elements;
+  v1 = svec[0].elements.Flt;
   v2 = dy;
   for (i = 0; i < Npts; i++, v1++, v2++) *v2 = 1.0 / (*v1 * *v1);
   
-  ochisq = mrqinit (xvec[0].elements, yvec[0].elements, dy, Npts, par, Npar, fmaxwellOD, !Quiet);
+  ochisq = mrqinit (xvec[0].elements.Flt, yvec[0].elements.Flt, dy, Npts, par, Npar, fmaxwellOD, !Quiet);
   dchisq = ochisq + 2*Npts;
 
-  for (i = 0; (i < 20) && ((dchisq > 0.1*(Npts - Npar)) || (dchisq <= 0.0)); i++) {
-    chisq = mrqmin (xvec[0].elements, yvec[0].elements, dy, Npts, par, Npar, fmaxwellOD, !Quiet);
+  for (i = 0; (i < 30) && ((dchisq > 0.1*(Npts - Npar)) || (dchisq <= 0.0)); i++) {
+    chisq = mrqmin (xvec[0].elements.Flt, yvec[0].elements.Flt, dy, Npts, par, Npar, fmaxwellOD, !Quiet);
     dchisq = ochisq - chisq;
     ochisq = chisq;
@@ -70,5 +74,5 @@
 
   for (i = 0; i < Npts; i++) {
-    ovec[0].elements[i] = fmaxwellOD (xvec[0].elements[i], par, Npar, dy);
+    ovec[0].elements.Flt[i] = fmaxwellOD (xvec[0].elements.Flt[i], par, Npar, dy);
   }
   ovec[0].Nelements = Npts;
@@ -90,7 +94,8 @@
 
 /* pars: x_o, -0.5/sigma^2, I, back, ref */
-float fmaxwellOD (float x, float *par, int Npar, float *dpar) {
+// f = C3 + C2*(x - C4)^2 * exp(-0.5*(x - C0)^2 / C1^2)
+opihi_flt fmaxwellOD (opihi_flt x, opihi_flt *par, int Npar, opihi_flt *dpar) {
 
-  float z, r, f;
+  opihi_flt z, r, f;
 
   z = (x - par[0])/par[1];
Index: /trunk/Ohana/src/opihi/cmd.data/vpop.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/vpop.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/vpop.c	(revision 20936)
@@ -17,5 +17,9 @@
 
   if (Npix > 1) {
-    memmove (&vec[0].elements[0], &vec[0].elements[1], Npix*sizeof(float));
+    if (vec[0].type == OPIHI_FLT) {
+      memmove (&vec[0].elements.Flt[0], &vec[0].elements.Flt[1], Npix*sizeof(opihi_flt));
+    } else {
+      memmove (&vec[0].elements.Int[0], &vec[0].elements.Int[1], Npix*sizeof(opihi_int));
+    }
   }
   vec[0].Nelements = Npix - 1;
Index: /trunk/Ohana/src/opihi/cmd.data/vroll.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/vroll.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/vroll.c	(revision 20936)
@@ -4,5 +4,5 @@
 
   int Npix;
-  float first;
+  opihi_flt first;
   Vector *vec;
 
@@ -17,7 +17,13 @@
   if (Npix < 2) return (TRUE);
 
-  first = vec[0].elements[0];
-  memmove (&vec[0].elements[0], &vec[0].elements[1], Npix*sizeof(float));
-  vec[0].elements[Npix-1] = first;
+  if (vec[0].type == OPIHI_FLT) {
+    first = vec[0].elements.Flt[0];
+    memmove (&vec[0].elements.Flt[0], &vec[0].elements.Flt[1], Npix*sizeof(opihi_flt));
+    vec[0].elements.Flt[Npix-1] = first;
+  } else {
+    first = vec[0].elements.Int[0];
+    memmove (&vec[0].elements.Int[0], &vec[0].elements.Int[1], Npix*sizeof(opihi_int));
+    vec[0].elements.Int[Npix-1] = first;
+  }
   return (TRUE);
 }
Index: /trunk/Ohana/src/opihi/cmd.data/vsmooth.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/vsmooth.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/vsmooth.c	(revision 20936)
@@ -3,7 +3,8 @@
 int vsmooth (int argc, char **argv) {
   
-  int i, n, N, Nx, Ns, Ngauss;
-  float *vi, *vo, *gauss, *gaussnorm;
-  float g, s, sigma, Nsigma;
+  int i, n, N, Nx, Ns, Ngauss, isFloat;
+  opihi_flt *vf, *vo, *gauss, *gaussnorm;
+  opihi_int *vi;
+  float g, s, sigma, Nsigma, value;
   Vector *in;
 
@@ -23,10 +24,9 @@
   sigma = atof (argv[2]);
   Nx = in[0].Nelements;
-  vi = in[0].elements;
 
   /* build a 1D gaussian */
   Ns = (int) (Nsigma*sigma + 0.5);
   Ngauss = 2*Ns + 1;
-  ALLOCATE (gaussnorm, float, Ngauss);
+  ALLOCATE (gaussnorm, opihi_flt, Ngauss);
   gauss = &gaussnorm[Ns];
   for (i = -Ns; i < Ns + 1; i++) {
@@ -34,5 +34,9 @@
   }
 
-  ALLOCATE (vo, float, Nx);
+  ALLOCATE (vo, opihi_flt, Nx);
+
+  isFloat = (in[0].type == OPIHI_FLT);
+  vf = in[0].elements.Flt;
+  vi = in[0].elements.Int;
 
   for (i = 0; i < Nx; i++) {
@@ -41,5 +45,6 @@
       if (i+n < 0) continue;
       if (i+n >= Nx) continue;
-      s += gauss[n]*vi[i+n];
+      value = isFloat ? vf[i+n] : vi[i+n];
+      s += gauss[n]*value;
       g += gauss[n];
     }
@@ -47,8 +52,15 @@
   }
 
-  free (in[0].elements);
   free (gaussnorm);
 
-  in[0].elements = vo;
+  if (isFloat) {
+    free (in[0].elements.Flt);
+  } else {
+    free (in[0].elements.Int);
+  }
+
+  // smoothing an int vector results in a float vector
+  in[0].type = OPIHI_FLT;
+  in[0].elements.Flt = vo;
   return (TRUE);
 }
Index: /trunk/Ohana/src/opihi/cmd.data/vstat.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/vstat.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/vstat.c	(revision 20936)
@@ -5,5 +5,5 @@
   int i, N;
   double max, min, sum, var, dvar, mean, stdev;
-  float *X, IgnoreValue;
+  float IgnoreValue;
   int Ignore, Quiet;
 
@@ -41,16 +41,28 @@
 
   /* calculate max, min, mean, sum, npix */
-  X = vec[0].elements;
   max = -HUGE_VAL;
   min = HUGE_VAL;
   sum = N = 0;
-  for (i = 0; i < vec[0].Nelements; i++, X++) {
-    if (!finite (*X)) continue;
-    if (Ignore && (*X == IgnoreValue)) continue;
-    max = MAX (*X, max);
-    min = MIN (*X, min);
-    sum += *X;
-    N++;
-  }      
+  if (vec[0].type == OPIHI_FLT) {
+    opihi_flt *X = vec[0].elements.Flt;
+    for (i = 0; i < vec[0].Nelements; i++, X++) {
+      if (!finite (*X)) continue;
+      if (Ignore && (*X == IgnoreValue)) continue;
+      max = MAX (*X, max);
+      min = MIN (*X, min);
+      sum += *X;
+      N++;
+    }      
+  } else {
+    opihi_int *X = vec[0].elements.Int;
+    for (i = 0; i < vec[0].Nelements; i++, X++) {
+      if (!finite (*X)) continue;
+      if (Ignore && (*X == IgnoreValue)) continue;
+      max = MAX (*X, max);
+      min = MIN (*X, min);
+      sum += *X;
+      N++;
+    }      
+  }
   mean = sum / N;
 
@@ -65,14 +77,26 @@
   ALLOCATE (Nval, int, 1002);
   bzero (Nval, 1000*sizeof(int));
-  X = vec[0].elements;
   var = 0;
-  for (i = 0; i < vec[0].Nelements; i++, X++) {
-    if (!finite (*X)) continue;
-    if (Ignore && (*X == IgnoreValue)) continue;
-    bin = MAX (0, MIN (1000, (*X - min) / dx));
-    Nval[bin] ++;
-    dvar = (*X - mean);
-    var += dvar*dvar;
-  }      
+  if (vec[0].type == OPIHI_FLT) {
+    opihi_flt *X = vec[0].elements.Flt;
+    for (i = 0; i < vec[0].Nelements; i++, X++) {
+      if (!finite (*X)) continue;
+      if (Ignore && (*X == IgnoreValue)) continue;
+      bin = MAX (0, MIN (1000, (*X - min) / dx));
+      Nval[bin] ++;
+      dvar = (*X - mean);
+      var += dvar*dvar;
+    }      
+  } else {
+    opihi_int *X = vec[0].elements.Int;
+    for (i = 0; i < vec[0].Nelements; i++, X++) {
+      if (!finite (*X)) continue;
+      if (Ignore && (*X == IgnoreValue)) continue;
+      bin = MAX (0, MIN (1000, (*X - min) / dx));
+      Nval[bin] ++;
+      dvar = (*X - mean);
+      var += dvar*dvar;
+    }      
+  }
   stdev = sqrt (var / N);
 
Index: /trunk/Ohana/src/opihi/cmd.data/vzload.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/vzload.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/vzload.c	(revision 20936)
@@ -58,11 +58,16 @@
 
   for (i = N = 0; i < Noverlay; i++) {
-    size = MIN (MAX_OUTPUT_SIZE, (vecz[0].elements[i] - min) / range);
+    float z = (vecz[0].type == OPIHI_FLT) ? vecz[0].elements.Flt[i] : vecz[0].elements.Int[i];
+    size = MIN (MAX_OUTPUT_SIZE, (z - min) / range);
     if (size < 0.1) continue;
 
     overlay[N].type = type;
     overlay[N].text = NULL;
-    overlay[N].x = vecx[0].elements[i]+0.5;
-    overlay[N].y = vecy[0].elements[i]+0.5;
+    overlay[N].x = (vecx[0].type == OPIHI_FLT) ? vecx[0].elements.Flt[i] : vecx[0].elements.Int[i];
+    overlay[N].y = (vecy[0].type == OPIHI_FLT) ? vecy[0].elements.Flt[i] : vecy[0].elements.Int[i];
+
+    overlay[N].x += 0.5;
+    overlay[N].y += 0.5;
+
     overlay[N].angle = 0.0;
 
Index: /trunk/Ohana/src/opihi/cmd.data/write_vectors.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/write_vectors.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/write_vectors.c	(revision 20936)
@@ -78,5 +78,9 @@
     for (i = 0; i < vec[0][0].Nelements; i++) {
       for (j = 0; j < Nvec; j++) {
-	fprintf (f, "%.10g ", vec[j][0].elements[i]);
+	if (vec[j][0].type == OPIHI_FLT) {
+	  fprintf (f, "%.12g ", vec[j][0].elements.Flt[i]);
+	} else {
+	  fprintf (f, "%d ", vec[j][0].elements.Int[i]);
+	}
       }
       fprintf (f, "\n");
@@ -135,8 +139,16 @@
     for (j = 0; j < Nvec; j++) {
       if (fmttype[j] == 'd') {
-	fprintf (f, fmtlist[j], (int)(vec[j][0].elements[i]));
+	if (vec[j][0].type == OPIHI_FLT) {
+	  fprintf (f, fmtlist[j], (int)(vec[j][0].elements.Flt[i]));
+	} else {
+	  fprintf (f, fmtlist[j], (int)(vec[j][0].elements.Int[i]));
+	}
       } 
       if (fmttype[j] == 'f') {
-	fprintf (f, fmtlist[j], (float)(vec[j][0].elements[i]));
+	if (vec[j][0].type == OPIHI_FLT) {
+	  fprintf (f, fmtlist[j], (float)(vec[j][0].elements.Flt[i]));
+	} else {
+	  fprintf (f, fmtlist[j], (float)(vec[j][0].elements.Int[i]));
+	}
       } 
     }
Index: /trunk/Ohana/src/opihi/cmd.data/zplot.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/zplot.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/cmd.data/zplot.c	(revision 20936)
@@ -3,6 +3,6 @@
 int zplot (int argc, char **argv) {
   
-  int i, kapa, Npts;
-  float *in, *out;
+  int i, kapa;
+  opihi_flt *out;
   double min, range;
   Graphdata graphmode;
@@ -31,11 +31,17 @@
     return (FALSE);
   }
-  Zvec.Nelements = zvec[0].Nelements;
-  ALLOCATE (Zvec.elements, float, Zvec.Nelements);
+  SetVector (&Zvec, OPIHI_FLT, zvec[0].Nelements);
+  out = Zvec.elements.Flt;
  
-  in = zvec[0].elements;
-  out = Zvec.elements;
-  for (i = 0; i < Zvec.Nelements; i++, in++, out++) {
-    *out = MIN (1.0, MAX (0.01, (*in - min) / range));
+  if (zvec[0].type == OPIHI_FLT) {
+    opihi_flt *in = zvec[0].elements.Flt;
+    for (i = 0; i < Zvec.Nelements; i++, in++, out++) {
+      *out = MIN (1.0, MAX (0.01, (*in - min) / range));
+    }
+  } else {
+    opihi_int *in = zvec[0].elements.Int;
+    for (i = 0; i < Zvec.Nelements; i++, in++, out++) {
+      *out = MIN (1.0, MAX (0.01, (*in - min) / range));
+    }
   }
 
@@ -44,8 +50,7 @@
   graphmode.size = -1; /* point size determined by Zvec */
   graphmode.etype = 0; /* no errorbars */
-  Npts = xvec[0].Nelements;
-  PlotVectorTriplet (kapa, Npts, xvec[0].elements, yvec[0].elements, Zvec.elements, &graphmode);
+  PlotVectorTriplet (kapa, xvec, yvec, &Zvec, &graphmode);
 
-  free (Zvec.elements);
+  free (Zvec.elements.Ptr);
 
   return (TRUE);
Index: /trunk/Ohana/src/opihi/doc/VectorTypes.txt
===================================================================
--- /trunk/Ohana/src/opihi/doc/VectorTypes.txt	(revision 20936)
+++ /trunk/Ohana/src/opihi/doc/VectorTypes.txt	(revision 20936)
@@ -0,0 +1,88 @@
+starcontour      : outputs are FLT
+rawstars         : inputs may be FLT or INT; outputs are FLT
+fitcontour       : input must be FLT
+findpeaks        : outputs are FLT
+skycat           : internal vectors only
+simage           : internal vectors only
+showtile         : internal vectors only
+procks           : internal vectors only
+mmextract        : output vector types are determined by selected db field
+mextract         : output vector types are determined by selected db field
+lightcurve       : outputs are FLT
+lcurve           : outputs are FLT
+imstats          : internal vectors only
+imrough          : outputs are FLT
+imextract        : outputs are FLT
+imdense          : internal vectors only
+imdata           : outputs are FLT
+imbox            : internal vectors only
+images           : internal vectors only
+gstar            : outputs are FLT
+fitcolors        : outputs are FLT
+detrend          : outputs are FLT
+compare          : function's outputs are FLT
+cmpread          : outputs are FLT
+cmd              : outputs are FLT
+ccd              : outputs are FLT
+calmextract      : outputs are FLT
+avextract        : output vector types are determined by selected db field
+zplot            : inputs may be FLT or INT
+write_vectors    : inputs may be FLT or INT
+vzload           : inputs may be FLT or INT
+vstat            : inputs may be FLT or INT
+vsmooth          : inputs may be FLT or INT; outputs are FLT
+vroll            : inputs may be FLT or INT
+vpop             : inputs may be FLT or INT
+vmaxwell         : input must be FLT; outputs are FLT
+vload            : inputs may be FLT or INT
+vgrid            : input must be FLT
+vgauss           : input must be FLT; outputs are FLT
+vclip            : inputs may be FLT or INT
+vbin             : inputs may be FLT or INT; outputs are FLT
+uniq             : inputs may be FLT or INT; outputs are set based on input
+ungridify        : outputs are FLT
+svd              : outputs are FLT
+subset           : inputs may be FLT or INT; outputs are set based on input
+sort             : inputs may be FLT or INT
+select           : inputs may be FLT or INT
+read_vectors     : outputs are FLT (someday add a format option to the read statement?)
+periodogram      : input must be FLT; outputs are FLT
+peak             : inputs may be FLT or INT
+mset             : inputs may be FLT or INT
+mget             : outputs are FLT
+medacc           : input must be FLT; outputs are FLT
+lookup           : input must be FLT; outputs are FLT
+interpolate      : input must be FLT; outputs are FLT
+integrate        : inputs may be FLT or INT
+imhist           : outputs are FLT
+imcut            : outputs are FLT
+histogram        : inputs may be FLT or INT, outputs are INT
+gridify          : input must be FLT
+grid             : internal vectors only
+gaussj           : inputs may be FLT or INT; outputs are FLT
+gaussdeviate     : outputs are FLT
+gaussintegral    : outputs are FLT
+fit              : input must be FLT
+fit2d            : input must be FLT
+fft1d            : input must be FLT
+dimenup          : inputs may be FLT or INT
+dimendown        : outputs are FLT
+dbselect         : output vector types are determined by selected db field
+cut              : outputs are FLT
+cumulative       : inputs may be FLT or INT; outputs are FLT
+create           : output vector type defaults to FLT, but may be optionally set to INT with the -int flag
+contour          : outputs are FLT
+concat           : inputs may be FLT or INT; outputs are set based on input
+applyfit         : inputs may be FLT or INT; outputs are FLT
+applyfit2d       : inputs may be FLT or INT; outputs are FLT
+accum            : input must be FLT; outputs are FLT
+spec             : outputs are FLT
+profile          : outputs are FLT
+precess          : inputs may be FLT or INT; outputs are FLT
+multifit         : input must be FLT; outputs are FLT
+czplot           : input must be FLT
+csystem          : inputs may be FLT or INT
+cplot            : input must be FLT
+coords           : input must be FLT
+cgrid            : internal vectors only
+biassub          : outputs are FLT
Index: /trunk/Ohana/src/opihi/doc/dvo.todo.20081204.txt
===================================================================
--- /trunk/Ohana/src/opihi/doc/dvo.todo.20081204.txt	(revision 20936)
+++ /trunk/Ohana/src/opihi/doc/dvo.todo.20081204.txt	(revision 20936)
@@ -0,0 +1,54 @@
+
+DVO : Outstanding Issues (20081204) TBR before survey start
+
+* fundamentals : 
+  * Commit to and Require C99?  
+  * Integer scalars and vectors to s64?
+  * force float for / for scalars (and vectors?)
+
+* Indices / IDs
+
+  Do we have all of the necessary IDs defined?
+
+  * Image IDs : we need to be able to link back to the IPP tables, but
+    also guarantee an internal unique ID even if images from multiple
+    databases / other sources are injects.  Note that the full 3pi
+    survey will consist of ~ 6000 * 60 * 60 chips = 1.3e7 images.
+
+    * imageID  : Internal image ID (32bit -> 4G rows)
+    * externID : chip_id, warp_id, stack_id, diff_id
+    * sourceID : database + table
+
+  * Object IDs : Our internal ID needs to be unique across all
+    objects.  We enforce this by generating the object ID when the
+    object is created with the objID seq number from the table in
+    which is was created + catID for the table.  We also need to
+    generate and track the external (PSPS) ID (64bit).
+
+    * objID : ID for object in a table
+    * catID : ID of the source table 
+    * extIDlo : high bits for external ID
+    * extIDhi : low bits for external ID
+      (or commit to a 64bit version)
+
+  * Detection IDs : internal only; these are generated as the seq
+    number on the image + the IPP image ID.
+
+* Add PSPS obj ID code
+
+* Orphans / Objects: PSPS considers detections to be orphans until
+  they are correlated with enough (2?) other detections.  IPP needs to
+  send the detections with their IPP objID, but only supply a list of
+  the new PSPS 'objects' when the object is no longer considered an
+  orphan.  The detection-to-object correlation is performed during the
+  addstar process.  IPP needs to generate a table of new non-orphaned
+  objects at that time for distribution.  How do we complete the
+  hand-shake?  
+
+* Schema updates
+
+* External Image IDs :  
+
+  * IMAGEID in header is the ID from chip_imfile, warp_skyfile, etc.
+  * SOURCEID in header maps to the database + stages (chip, warp, etc)
+
Index: /trunk/Ohana/src/opihi/dvo/Makefile
===================================================================
--- /trunk/Ohana/src/opihi/dvo/Makefile	(revision 20935)
+++ /trunk/Ohana/src/opihi/dvo/Makefile	(revision 20936)
@@ -29,5 +29,4 @@
 $(SRC)/dvomisc.$(ARCH).o		\
 $(SRC)/region_list.$(ARCH).o		\
-$(SRC)/dvomisc.$(ARCH).o		\
 $(SRC)/dbBooleanCond.$(ARCH).o		\
 $(SRC)/dbCheckStack.$(ARCH).o		\
@@ -35,4 +34,5 @@
 $(SRC)/dbExtractAverages.$(ARCH).o	\
 $(SRC)/dbExtractMeasures.$(ARCH).o	\
+$(SRC)/dbExtractImages.$(ARCH).o	\
 $(SRC)/dbFields.$(ARCH).o		\
 $(SRC)/dbRPN.$(ARCH).o			\
@@ -113,5 +113,4 @@
 
 # deprecated functions: verify & delete
-#$(SRC)/catalog.$(ARCH).o	  	\
 #$(SRC)/abszero.$(ARCH).o \
 #$(SRC)/cals.$(ARCH).o \
Index: /trunk/Ohana/src/opihi/dvo/avextract.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/avextract.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/dvo/avextract.c	(revision 20936)
@@ -6,22 +6,24 @@
   int Nsecfilt, mode, VERBOSE;
   char **cstack, name[1024];
-  float *values;
   void *Signal;
 
   Catalog catalog;
+
+  Vector **vec;
+  dbStack *stack;
+  dbField *fields;
+  dbValue *values;
   SkyList *skylist;
   SkyRegionSelection *selection;
-  PhotCode *code;
-  Vector **vec;
-  dbField *fields;
-  dbStack *stack;
 
   /* defaults */
+  vec = NULL;
+  stack = NULL;
+  fields = NULL;
+  values = NULL;
   skylist = NULL;
   selection = NULL;
-  code = NULL;
+
   mode = MAG_AVE;
-  fields = NULL;
-  stack = NULL;
 
   if ((N = get_argument (argc, argv, "-h"))) goto help;
@@ -47,5 +49,11 @@
   // parse the fields to be extracted and returned
   fields = dbCmdlineFields (argc, argv, DVO_TABLE_AVERAGE, &last, &Nfields);
-  if (fields == NULL) return (FALSE);
+  if (fields == NULL) goto escape;
+  if (Nfields == 0) {
+    FreeSkyRegionSelection (selection);
+    dbFreeFields (fields, Nfields);
+    dvo_catalog_free (&catalog);
+    goto help;
+  }
 
   // examine line for 'where' or 'match to'.  'match to' is forbidden
@@ -66,5 +74,4 @@
   Nreturn = Nfields; 
   if (!dbCheckStack (stack, Nstack, DVO_TABLE_AVERAGE, &fields, &Nfields)) goto escape;
-  // XXX handle errors
 
   /* load region corresponding to selection above */
@@ -72,5 +79,5 @@
 
   /* create output storage vectors */
-  ALLOCATE (values, float, Nfields);
+  ALLOCATE (values, dbValue, Nfields);
   ALLOCATE (vec, Vector *, Nreturn);
   for (i = 0; i < Nreturn; i++) {
@@ -81,4 +88,5 @@
     }
     if ((vec[i] = SelectVector (name, ANYVECTOR, TRUE)) == NULL) goto escape;
+    ResetVector (vec[i], fields[i].type, NPTS);
   }
 
@@ -109,12 +117,19 @@
 
       m = catalog.average[j].measureOffset;
-      dbExtractAveragesInit (); // reset counters for saved fields 
+
+      // reset counters for saved fields, extract fields
+      dbExtractAveragesInit (); 
       for (n = 0; n < Nfields; n++) {
 	values[n] = dbExtractAverages (&catalog.average[j], &catalog.secfilt[j*Nsecfilt], &catalog.measure[m], &fields[n]);
       }
+
       // test the conditional statement
       if (!dbBooleanCond (stack, Nstack, values)) continue;
       for (n = 0; n < Nreturn; n++) {
-	vec[n][0].elements[Npts] = values[n];
+	if (vec[n][0].type == OPIHI_FLT) {
+	  vec[n][0].elements.Flt[Npts] = values[n].Flt;
+	} else {
+	  vec[n][0].elements.Int[Npts] = values[n].Int;
+	}
       }
       Npts++;
@@ -122,5 +137,9 @@
 	NPTS += 2000;
 	for (n = 0; n < Nreturn; n++) {
-	  REALLOCATE (vec[n][0].elements, float, NPTS);
+	  if (vec[n][0].type == OPIHI_FLT) {
+	    REALLOCATE (vec[n][0].elements.Flt, opihi_flt, NPTS);
+	  } else {
+	    REALLOCATE (vec[n][0].elements.Int, opihi_int, NPTS);
+	  }
 	}
       }
@@ -132,10 +151,16 @@
   for (n = 0; n < Nreturn; n++) {
     vec[n][0].Nelements = Npts;
-    REALLOCATE (vec[n][0].elements, float, MAX(1,Npts));
-  }
-
+    if (vec[n][0].type == OPIHI_FLT) {
+      REALLOCATE (vec[n][0].elements.Flt, opihi_flt, MAX(1,Npts));
+    } else {
+      REALLOCATE (vec[n][0].elements.Int, opihi_int, MAX(1,Npts));
+    }
+  }
+
+  if (vec) free (vec);
+  if (values) free (values);
   dbFreeFields (fields, Nfields);
   dbFreeStack (stack, Nstack);
-  free (stack);
+  if (stack) free (stack);
   SkyListFree (skylist);
   FreeSkyRegionSelection (selection);
@@ -143,7 +168,9 @@
 
  escape:
+  if (vec) free (vec);
+  if (values) free (values);
   dbFreeFields (fields, Nfields);
   dbFreeStack (stack, Nstack);
-  free (stack);
+  if (stack) free (stack);
   SkyListFree (skylist);
   FreeSkyRegionSelection (selection);
Index: /trunk/Ohana/src/opihi/dvo/calmextract.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/calmextract.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/dvo/calmextract.c	(revision 20936)
@@ -38,8 +38,7 @@
   if (!TestPhotSelections (&code[0], &mode[0], MEAS_ZERO)) goto escape;
 
+  gprint (GP_ERR, "warning: this function may be deprecated in the future -- use avextract for better control\n");
+
   /* returned vectors are dmag, mag, color, time, airmass, ra, dec, x, y, exptime */
-  N = 0;
-  Nstar = 0;
-  NSTAR = 100;
   ALLOCATE (vec, Vector *, NVEC);
   if ((vec[Nd ] = SelectVector ("cal:dmag",     ANYVECTOR, TRUE)) == NULL) goto escape;
@@ -60,7 +59,10 @@
   if ((vec[Nd1] = SelectVector ("cal:dm1",      ANYVECTOR, TRUE)) == NULL) goto escape;
   if ((vec[Nd2] = SelectVector ("cal:dm2",      ANYVECTOR, TRUE)) == NULL) goto escape;
+
+  N = 0;
+  Nstar = 0;
+  NSTAR = 100;
   for (k = 0; k < NVEC; k++) {
-    REALLOCATE (vec[k][0].elements, float, NSTAR);
-    vec[k][0].Nelements = 0;
+    ResetVector (vec[k], OPIHI_FLT, NSTAR);
   }
 
@@ -110,5 +112,5 @@
 	NSTAR += N1 + 100;
 	for (k = 0; k < NVEC; k++) {
-	  REALLOCATE (vec[k][0].elements, float, NSTAR);
+	  REALLOCATE (vec[k][0].elements.Flt, opihi_flt, NSTAR);
 	}
       }
@@ -125,12 +127,12 @@
 
       for (j = 0; j < N1; j++, N++) {
-	vec[Nd ][0].elements[N] = M1[j] - M2;
-	vec[Nm1][0].elements[N] = M1[j];
-	vec[Nm2][0].elements[N] = M2;
-	vec[Nd2][0].elements[N] = dM2;
-	vec[Nc ][0].elements[N] = color;
-	vec[Ns ][0].elements[N] = Nstar;
-	vec[NR ][0].elements[N] = catalog.average[i].R;
-	vec[ND ][0].elements[N] = catalog.average[i].D;
+	vec[Nd ][0].elements.Flt[N] = M1[j] - M2;
+	vec[Nm1][0].elements.Flt[N] = M1[j];
+	vec[Nm2][0].elements.Flt[N] = M2;
+	vec[Nd2][0].elements.Flt[N] = dM2;
+	vec[Nc ][0].elements.Flt[N] = color;
+	vec[Ns ][0].elements.Flt[N] = Nstar;
+	vec[NR ][0].elements.Flt[N] = catalog.average[i].R;
+	vec[ND ][0].elements.Flt[N] = catalog.average[i].D;
       }
       Nstar ++; 
@@ -178,5 +180,5 @@
   Ns = vec[0].Nelements;
   for (i = 0; i < N; i++) {
-    vec[0].elements[Ns+i] = value[i];
+    vec[0].elements.Flt[Ns+i] = value[i];
   }
   vec[0].Nelements = Ns + N;
Index: /trunk/Ohana/src/opihi/dvo/ccd.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/ccd.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/dvo/ccd.c	(revision 20936)
@@ -51,8 +51,13 @@
 
   /* init vectors to save data */
-  Npts = 0;
-  NPTS = 1;
   if ((xvec = SelectVector ("xv", ANYVECTOR, TRUE)) == NULL) goto escape;
   if ((yvec = SelectVector ("yv", ANYVECTOR, TRUE)) == NULL) goto escape;
+
+  gprint (GP_ERR, "warning: this function may be deprecated in the future -- use avextract for better control\n");
+
+  Npts = 0;
+  NPTS = 100;
+  ResetVector (xvec, OPIHI_FLT, NPTS);
+  ResetVector (yvec, OPIHI_FLT, NPTS);
 
   // grab data from all selected sky regions
@@ -97,11 +102,11 @@
       for (i1 = 0; i1 < N1; i1++) {
 	for (i2 = 0; i2 < N2; i2++) {
-	  xvec[0].elements[Npts] = M1[i1];
-	  yvec[0].elements[Npts] = M2[i2];
+	  xvec[0].elements.Flt[Npts] = M1[i1];
+	  yvec[0].elements.Flt[Npts] = M2[i2];
 	  Npts++;
 	  if (Npts >= NPTS) {
 	    NPTS += 2000;
-	    REALLOCATE (xvec[0].elements, float, NPTS);
-	    REALLOCATE (yvec[0].elements, float, NPTS);
+	    REALLOCATE (xvec[0].elements.Flt, opihi_flt, NPTS);
+	    REALLOCATE (yvec[0].elements.Flt, opihi_flt, NPTS);
 	  }
 	}
Index: /trunk/Ohana/src/opihi/dvo/cmd.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/cmd.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/dvo/cmd.c	(revision 20936)
@@ -49,8 +49,13 @@
 
   /* init vectors to save data */
-  Npts = 0;
-  NPTS = 1;
   if ((xvec = SelectVector ("xv", ANYVECTOR, TRUE)) == NULL) goto escape;
   if ((yvec = SelectVector ("yv", ANYVECTOR, TRUE)) == NULL) goto escape;
+
+  gprint (GP_ERR, "warning: this function may be deprecated in the future -- use avextract for better control\n");
+
+  Npts = 0;
+  NPTS = 100;
+  ResetVector (xvec, OPIHI_FLT, NPTS);
+  ResetVector (yvec, OPIHI_FLT, NPTS);
 
   // grab data from all selected sky regions
@@ -95,11 +100,11 @@
       for (i1 = 0; i1 < N1; i1++) {
 	for (i3 = 0; i3 < N3; i3++) {
-	  xvec[0].elements[Npts] = M1[i1];
-	  yvec[0].elements[Npts] = M3[i3];
+	  xvec[0].elements.Flt[Npts] = M1[i1];
+	  yvec[0].elements.Flt[Npts] = M3[i3];
 	  Npts++;
 	  if (Npts >= NPTS) {
 	    NPTS += 2000;
-	    REALLOCATE (xvec[0].elements, float, NPTS);
-	    REALLOCATE (yvec[0].elements, float, NPTS);
+	    REALLOCATE (xvec[0].elements.Flt, opihi_flt, NPTS);
+	    REALLOCATE (yvec[0].elements.Flt, opihi_flt, NPTS);
 	  }
 	}
Index: /trunk/Ohana/src/opihi/dvo/cmpread.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/cmpread.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/dvo/cmpread.c	(revision 20936)
@@ -89,7 +89,6 @@
   fclose (f);
 
-  REALLOCATE (vec[0].elements, float, Nstars);
-  vec[0].Nelements = Nstars;
-  bzero (vec[0].elements, Nstars*sizeof(float));
+  ResetVector (vec, OPIHI_FLT, Nstars);
+  bzero (vec[0].elements.Flt, Nstars*sizeof(opihi_flt));
 
   value = 0;
@@ -135,5 +134,5 @@
 	break;
     }
-    vec[0].elements[i] = value;
+    vec[0].elements.Flt[i] = value;
   }      
   free (stars);
Index: /trunk/Ohana/src/opihi/dvo/compare.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/compare.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/dvo/compare.c	(revision 20936)
@@ -10,10 +10,10 @@
   Nmatch = 0;
   NMATCH = D_NMATCH;
-  REALLOCATE (rvec[0].elements, float, NMATCH);
-  REALLOCATE (dvec[0].elements, float, NMATCH);
-  REALLOCATE (mvec[0].elements, float, NMATCH);
-  REALLOCATE (drvec[0].elements, float, NMATCH);
-  REALLOCATE (ddvec[0].elements, float, NMATCH);
-  REALLOCATE (dmvec[0].elements, float, NMATCH);
+  ResetVector ( rvec, OPIHI_FLT, NMATCH);
+  ResetVector ( dvec, OPIHI_FLT, NMATCH);
+  ResetVector ( mvec, OPIHI_FLT, NMATCH);
+  ResetVector (drvec, OPIHI_FLT, NMATCH);
+  ResetVector (ddvec, OPIHI_FLT, NMATCH);
+  ResetVector (dmvec, OPIHI_FLT, NMATCH);
 
   for (i = j = 0; (i < catlog1[0].Naverage) && (j < catlog2[0].Naverage);) {
@@ -36,19 +36,19 @@
 	dR = hypot (dX, dY);
 	if (dR < radius) {
-	  rvec[0].elements[Nmatch] = catlog1[0].average[i].R;
-	  dvec[0].elements[Nmatch] = catlog1[0].average[i].D;
-	  // mvec[0].elements[Nmatch] = catlog1[0].average[i].M;
-	  drvec[0].elements[Nmatch] = dX;
-	  ddvec[0].elements[Nmatch] = dY;
-	  // dmvec[0].elements[Nmatch] = catlog1[0].average[i].M - catlog2[0].average[j].M;
+	  rvec[0].elements.Flt[Nmatch] = catlog1[0].average[i].R;
+	  dvec[0].elements.Flt[Nmatch] = catlog1[0].average[i].D;
+	  // mvec[0].elements.Flt[Nmatch] = catlog1[0].average[i].M;
+	  drvec[0].elements.Flt[Nmatch] = dX;
+	  ddvec[0].elements.Flt[Nmatch] = dY;
+	  // dmvec[0].elements.Flt[Nmatch] = catlog1[0].average[i].M - catlog2[0].average[j].M;
 	  Nmatch ++;
 	  if (Nmatch == NMATCH - 1) {
 	    NMATCH += D_NMATCH;
-	    REALLOCATE ( rvec[0].elements, float, NMATCH);
-	    REALLOCATE ( dvec[0].elements, float, NMATCH);
-	    REALLOCATE ( mvec[0].elements, float, NMATCH);
-	    REALLOCATE (drvec[0].elements, float, NMATCH);
-	    REALLOCATE (ddvec[0].elements, float, NMATCH);
-	    REALLOCATE (dmvec[0].elements, float, NMATCH);
+	    REALLOCATE ( rvec[0].elements.Flt, opihi_flt, NMATCH);
+	    REALLOCATE ( dvec[0].elements.Flt, opihi_flt, NMATCH);
+	    REALLOCATE ( mvec[0].elements.Flt, opihi_flt, NMATCH);
+	    REALLOCATE (drvec[0].elements.Flt, opihi_flt, NMATCH);
+	    REALLOCATE (ddvec[0].elements.Flt, opihi_flt, NMATCH);
+	    REALLOCATE (dmvec[0].elements.Flt, opihi_flt, NMATCH);
 	  }
 	}
@@ -59,18 +59,10 @@
   }
 
-  REALLOCATE ( rvec[0].elements, float, Nmatch);
-  REALLOCATE ( dvec[0].elements, float, Nmatch);
-  REALLOCATE ( mvec[0].elements, float, Nmatch);
-  REALLOCATE (drvec[0].elements, float, Nmatch);
-  REALLOCATE (ddvec[0].elements, float, Nmatch);
-  REALLOCATE (dmvec[0].elements, float, Nmatch);
-  
-  rvec[0].Nelements = Nmatch;
-  dvec[0].Nelements = Nmatch;
-  mvec[0].Nelements = Nmatch;
-  drvec[0].Nelements = Nmatch;
-  ddvec[0].Nelements = Nmatch;
-  dmvec[0].Nelements = Nmatch;
-
+  ResetVector ( rvec, OPIHI_FLT, Nmatch);
+  ResetVector ( dvec, OPIHI_FLT, Nmatch);
+  ResetVector ( mvec, OPIHI_FLT, Nmatch);
+  ResetVector (drvec, OPIHI_FLT, Nmatch);
+  ResetVector (ddvec, OPIHI_FLT, Nmatch);
+  ResetVector (dmvec, OPIHI_FLT, Nmatch);
 }
 
Index: /trunk/Ohana/src/opihi/dvo/dbBooleanCond.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/dbBooleanCond.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/dvo/dbBooleanCond.c	(revision 20936)
@@ -3,5 +3,6 @@
 // evaluate the expression in inStack as a boolean; necessary db field values are
 // supplied by fields, in order 0 - Nfields (validate before calling)
-int dbBooleanCond (dbStack *inStack, int NinStack, float *fields) {
+// 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;
@@ -21,5 +22,5 @@
 
     /***** binary operators *****/
-    if ((stack[i][0].type >= 3) && (stack[i][0].type <= 8)) {
+    if ((stack[i][0].type >= DB_STACK_LOGIC) && (stack[i][0].type <= DB_STACK_POWER)) {
 
       // pre-test that op and entries match
@@ -41,5 +42,5 @@
 
     /***** unary operators **/
-    if (stack[i][0].type == 9) {
+    if (stack[i][0].type == DB_STACK_UNARY) {
 
       // pre-test that op and entries match
@@ -61,9 +62,9 @@
 
   // the result here is a single stack entry with a value:
-  if (stack[0][0].type == 'F') {
+  if (stack[0][0].type & DB_STACK_FIELD) {
     N = stack[0][0].field;
-    value = fields[N];
+    value = (stack[0][0].type & DB_STACK_INT) ? fields[N].Int : fields[N].Flt;
   } else {
-    value = stack[0][0].Float;
+    value = (stack[0][0].type & DB_STACK_INT) ? stack[0][0].IntValue : stack[0][0].FltValue;
   }
     
Index: /trunk/Ohana/src/opihi/dvo/dbCheckStack.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/dbCheckStack.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/dvo/dbCheckStack.c	(revision 20936)
@@ -1,8 +1,14 @@
 # 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 *c;
+  char *c1, *c2;
   dbField *fields;
 
@@ -14,10 +20,16 @@
 
   for (i = 0; i < Nstack; i++) {
-    if (stack[i].type == 'X') {
+    if (stack[i].type == DB_STACK_VALUE) {
 
-      /** if this is a number, put it on the list of scalers and move on **/
-      stack[i].Float = strtod (stack[i].name, &c);
-      if (c == stack[i].name + strlen (stack[i].name)) {
-	stack[i].type  = 'S';
+      /** 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;
       } 
@@ -44,6 +56,6 @@
 	  code = GetPhotcodebyName (tmpstring);
 	  if (code) {
-	      stack[i].Float = code->code;
-	      stack[i].type  = 'S';
+	      stack[i].IntValue = code->code;
+	      stack[i].type = DB_STACK_INT;
 	      continue;
 	  } 
@@ -60,11 +72,16 @@
       if (j < Nfields) {
 	stack[i].field = j;
-	stack[i].type  = 'F';
+	stack[i].type |= DB_STACK_FIELD;
+	if (fields[j].type == OPIHI_INT) {
+	  stack[i].type |= DB_STACK_INT;
+	}
 	stack[i].name  = NULL;
-	stack[i].Float = 0.0;
+	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);
@@ -73,12 +90,18 @@
 	status = ParseAverageField (&fields[Nfields], stack[i].name);
       } 
+      if (table == DVO_TABLE_IMAGE) {
+	status = ParseImageField (&fields[Nfields], stack[i].name);
+      } 
       if (!status) {
-	gprint (GP_ERR, "unknown database field %s\n", stack[i].name);
 	goto failure;
       }
       stack[i].field = Nfields;
-      stack[i].type  = 'F';
+      stack[i].type |= DB_STACK_FIELD;
+      if (fields[Nfields].type == OPIHI_INT) {
+	stack[i].type |= DB_STACK_INT;
+      }
       stack[i].name  = NULL;
-      stack[i].Float = 0.0;
+      stack[i].FltValue = 0.0; // 'F'
+      stack[i].IntValue =   0; // 'f'
 
       Nfields ++;
Index: /trunk/Ohana/src/opihi/dvo/dbCmdlineFields.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/dbCmdlineFields.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/dvo/dbCmdlineFields.c	(revision 20936)
@@ -77,6 +77,8 @@
 	status = ParseAverageField (&fields[Nfields], field);
       } 
+      if (table == DVO_TABLE_IMAGE) {
+	status = ParseImageField (&fields[Nfields], field);
+      } 
       if (!status) {
-	gprint (GP_ERR, "unknown database field %s\n", field);
 	free (field);
 	dbFreeFields (fields, Nfields);
@@ -143,11 +145,18 @@
   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");
-  } else {
-    Rname = strcreate ("RA:AVE");
-    Dname = strcreate ("DEC:AVE");
-  }
+  }
+  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))
@@ -155,38 +164,36 @@
 
   stack[0][N +  0].name = strcreate (Rname);
-  stack[0][N +  0].type = 'X';
+  stack[0][N +  0].type = DB_STACK_VALUE;
   stack[0][N +  1].name = strfloat (Rmin);
-  stack[0][N +  1].type = 'X';
+  stack[0][N +  1].type = DB_STACK_VALUE;
   stack[0][N +  2].name = strcreate (">");
-  stack[0][N +  2].type = 4;
-  // stack[0][N +  3].name = strcreate ("A");
-  // stack[0][N +  3].type = 3;
+  stack[0][N +  2].type = DB_STACK_COMPARE;
 
   stack[0][N +  3].name = strcreate (Rname);
-  stack[0][N +  3].type = 'X';
+  stack[0][N +  3].type = DB_STACK_VALUE;
   stack[0][N +  4].name = strfloat (Rmax);
-  stack[0][N +  4].type = 'X';
+  stack[0][N +  4].type = DB_STACK_VALUE;
   stack[0][N +  5].name = strcreate ("<");
-  stack[0][N +  5].type = 4;
+  stack[0][N +  5].type = DB_STACK_COMPARE;
   stack[0][N +  6].name = strcreate ("A");
-  stack[0][N +  6].type = 3;
+  stack[0][N +  6].type = DB_STACK_LOGIC;
 
   stack[0][N +  7].name = strcreate (Dname);
-  stack[0][N +  7].type = 'X';
+  stack[0][N +  7].type = DB_STACK_VALUE;
   stack[0][N +  8].name = strfloat (Dmin);
-  stack[0][N +  8].type = 'X';
+  stack[0][N +  8].type = DB_STACK_VALUE;
   stack[0][N +  9].name = strcreate (">");
-  stack[0][N +  9].type = 4;
+  stack[0][N +  9].type = DB_STACK_COMPARE;
   stack[0][N + 10].name = strcreate ("A");
-  stack[0][N + 10].type = 3;
+  stack[0][N + 10].type = DB_STACK_LOGIC;
 
   stack[0][N + 11].name = strcreate (Dname);
-  stack[0][N + 11].type = 'X';
+  stack[0][N + 11].type = DB_STACK_VALUE;
   stack[0][N + 12].name = strfloat (Dmax);
-  stack[0][N + 12].type = 'X';
+  stack[0][N + 12].type = DB_STACK_VALUE;
   stack[0][N + 13].name = strcreate ("<");
-  stack[0][N + 13].type = 4;
+  stack[0][N + 13].type = DB_STACK_COMPARE;
   stack[0][N + 14].name = strcreate ("A");
-  stack[0][N + 14].type = 3;
+  stack[0][N + 14].type = DB_STACK_LOGIC;
 
   if (N == 0) {
@@ -194,5 +201,5 @@
   } else {
     stack[0][N + 15].name = strcreate ("A");
-    stack[0][N + 15].type = 3;
+    stack[0][N + 15].type = DB_STACK_LOGIC;
     N += 16;
   }    
Index: /trunk/Ohana/src/opihi/dvo/dbExtractAverages.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/dbExtractAverages.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/dvo/dbExtractAverages.c	(revision 20936)
@@ -40,18 +40,19 @@
 
 /* return average.field based on the selection */
-double dbExtractAverages (Average *average, SecFilt *secfilt, Measure *measure, dbField *field) {
+dbValue dbExtractAverages (Average *average, SecFilt *secfilt, Measure *measure, dbField *field) {
 
   int i, Nsec;
-  double value;
+  dbValue value;
 
-  value = NAN;
+  value.Flt = NAN;
+  value.Int =   0;
 
   /* assign vector values */
   switch (field->ID) {
     case AVE_RA:
-      value = average[0].R;
+      value.Flt = average[0].R;
       break;
     case AVE_DEC:
-      value = average[0].D;
+      value.Flt = average[0].D;
       break;
     case AVE_GLON:
@@ -60,5 +61,5 @@
 	haveGalactic = TRUE;
       }
-      value = GLON;
+      value.Flt = GLON;
       break;
     case AVE_GLAT:
@@ -67,5 +68,5 @@
 	haveGalactic = TRUE;
       }
-      value = GLAT;
+      value.Flt = GLAT;
       break;
     case AVE_ELON:
@@ -74,5 +75,5 @@
 	haveEcliptic = TRUE;
       }
-      value = ELON;
+      value.Flt = ELON;
       break;
     case AVE_ELAT:
@@ -81,44 +82,50 @@
 	haveEcliptic = TRUE;
       }
-      value = ELAT;
+      value.Flt = ELAT;
       break;
     case AVE_RA_ERR:
-      value = average[0].dR;
+      value.Flt = average[0].dR;
       break;
     case AVE_DEC_ERR:
-      value = average[0].dD;
+      value.Flt = average[0].dD;
       break;
 
     case AVE_U_RA:
-      value = average[0].uR;
+      value.Flt = average[0].uR;
       break;
     case AVE_U_DEC:
-      value = average[0].uD;
+      value.Flt = average[0].uD;
       break;
     case AVE_U_RA_ERR:
-      value = average[0].duR;
+      value.Flt = average[0].duR;
       break;
     case AVE_U_DEC_ERR:
-      value = average[0].duD;
+      value.Flt = average[0].duD;
       break;
 
     case AVE_PAR:
-      value = average[0].P;
+      value.Flt = average[0].P;
       break;
     case AVE_PAR_ERR:
-      value = average[0].dP;
+      value.Flt = average[0].dP;
       break;
 
     case AVE_NMEAS:
-      value = average[0].Nmeasure;
+      value.Int = average[0].Nmeasure;
       break;
     case AVE_NMISS:
-      value = average[0].Nmissing;
+      value.Int = average[0].Nmissing;
       break;
     case AVE_Xp:
-      value = 0.01*average[0].Xp;
+      value.Flt = 0.01*average[0].Xp;
       break;
     case AVE_FLAG:
-      value = average[0].code;
+      value.Int = average[0].code;
+      break;
+    case AVE_OBJID:
+      value.Int = average[0].objID;
+      break;
+    case AVE_CATID:
+      value.Int = average[0].catID;
       break;
 
@@ -126,8 +133,8 @@
       switch (field->magMode) {
 	case MAG_AVE:
-	  value = PhotAve  (field->photcode, average, secfilt);
+	  value.Flt = PhotAve  (field->photcode, average, secfilt);
 	  break;
 	case MAG_REF:
-	  value = PhotRef  (field->photcode, average, secfilt, measure);
+	  value.Flt = PhotRef  (field->photcode, average, secfilt, measure);
 	  break;
 	case MAG_INST:
@@ -137,8 +144,8 @@
 	case MAG_CAL:
 	  // XXX need to code this correctly: this returns just the first matching value
-	  value = NAN;
+	  value.Flt = NAN;
 	  for (i = 0; i < average[0].Nmeasure; i++) {
 	    if (field->photcode->code != measure[i].photcode) continue;
-	    value = measure[i].M;
+	    value.Flt = measure[i].M;
 	    break;
 	  }
@@ -146,16 +153,16 @@
 	case MAG_CHISQ:
 	  // GetPhotcodeEquivCodebyCode (field->photcode)
-	  value = PhotXm (field->photcode, average, secfilt);
+	  value.Flt = PhotXm (field->photcode, average, secfilt);
 	  break;
 	case MAG_ERR:
 	  // GetPhotcodeEquivCodebyCode (field->photcode)
-	  if (field->photcode->type == PHOT_REF) {
+	  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 = measure[i].dM;
+	      value.Flt = measure[i].dM;
 	      break;
 	    }
 	  } else {
-	    value = PhotdM (field->photcode, average, secfilt);
+	    value.Flt = PhotdM (field->photcode, average, secfilt);
 	  }
 	  break;
@@ -165,10 +172,10 @@
 	  Nsec = GetPhotcodeNsec (field->photcode->code);
 	  if (Nsec == -1) break;
-	  value = secfilt[Nsec].Ncode;
+	  value.Int = secfilt[Nsec].Ncode;
 	  break;
 	case MAG_NPHOT:
 	  Nsec = GetPhotcodeNsec (field->photcode->code);
 	  if (Nsec == -1) break;
-	  value = secfilt[Nsec].Nused;
+	  value.Int = secfilt[Nsec].Nused;
 	  break;
 
@@ -176,8 +183,8 @@
       break;
     case AVE_dMAG:
-      value = PhotdM (field->photcode, average, secfilt);
+      value.Flt = PhotdM (field->photcode, average, secfilt);
       break;
     case AVE_Xm:
-      value = PhotXm (field->photcode, average, secfilt);
+      value.Flt = PhotXm (field->photcode, average, secfilt);
       break;
     case AVE_TYPE:
@@ -185,23 +192,4 @@
     case AVE_TYPEFRAC:
       break;
-      /*
-    case AVE_NCODE:
-      value = 0;
-      for (i = 0; i < average[0].Nm; i++) {
-	if (field->photcode->code != GetPhotcodeEquivCodebyCode (measure[i].photcode)) continue;
-	value ++;
-      }
-      break;
-    case AVE_NPHOT:
-      value = 0;
-      for (i = 0; i < average[0].Nm; i++) {
-	if (field->photcode->code != GetPhotcodeEquivCodebyCode (measure[i].photcode)) continue;
-	if (measure[i].flags & (ID_MEAS_POOR_PHOTOM | ID_MEAS_SKIP_PHOTOM)) continue;
-	value ++;
-      }
-      break;
-    case AVE_NCRIT:
-      break;
-      */
   }
   return (value);
Index: /trunk/Ohana/src/opihi/dvo/dbExtractImages.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/dbExtractImages.c	(revision 20936)
+++ /trunk/Ohana/src/opihi/dvo/dbExtractImages.c	(revision 20936)
@@ -0,0 +1,304 @@
+# 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, int Nimage, int N, dbField *field) {
+
+  double x, y;
+  time_t t;
+  dbValue value;
+
+  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_TRATE:
+      value.Flt = image[N].trate / 10000.0;
+      break;
+
+    case IMAGE_NCAL:
+      value.Int = image[N].Mxxxx;
+      break;
+    case IMAGE_SKY:
+      value.Flt = image[N].Myyyy + 0x8000;
+      break;
+    case IMAGE_FLAG:
+      value.Int = image[N].code;
+      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;
+  }
+  return (value);
+}  
+
Index: /trunk/Ohana/src/opihi/dvo/dbExtractMeasures.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/dbExtractMeasures.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/dvo/dbExtractMeasures.c	(revision 20936)
@@ -31,7 +31,8 @@
 static double ELAT_MEAS = 0.0;
 
-void dbExtractMeasuresInit () {
+int dbExtractMeasuresInit () {
   TimeRefPM = ohana_date_to_sec ("2000/01/01");
   GetTimeFormat (&TimeReference, &TimeFormat);
+  return (TRUE);
 }
 
@@ -70,8 +71,8 @@
 
 /* return measure.field based on the selection */
-double dbExtractMeasures (Average *average, SecFilt *secfilt, Measure *measure, dbField *field) {
+dbValue dbExtractMeasures (Average *average, SecFilt *secfilt, Measure *measure, dbField *field) {
 
   int Nsec;
-  double value;
+  dbValue value;
   double ra, dec, x, y, dT;
 
@@ -79,5 +80,6 @@
   PhotCode *equiv;
 
-  value = NAN;
+  value.Flt = NAN;
+  value.Int =   0;
 
   switch (field->ID) {
@@ -96,65 +98,65 @@
       switch (field->magMode) {
 	case MAG_INST:
-	  value = PhotInst (measure);  
+	  value.Flt = PhotInst (measure);  
 	  break;
 	case MAG_CAT:
-	  value = PhotCat  (measure); 
+	  value.Flt = PhotCat  (measure); 
 	  break;
 	case MAG_SYS:
-	  value = PhotSys  (measure, average, secfilt); 
+	  value.Flt = PhotSys  (measure, average, secfilt); 
 	  break;
 	case MAG_REL:
-	  value = PhotRel  (measure, average, secfilt); 
+	  value.Flt = PhotRel  (measure, average, secfilt); 
 	  break;
 	case MAG_CAL:
-	  value = PhotCal  (measure, average, secfilt, measure, equiv); 
+	  value.Flt = PhotCal  (measure, average, secfilt, measure, equiv); 
 	  break;
 	case MAG_AVE:
-	  value = PhotAve  (equiv, average, secfilt); 
+	  value.Flt = PhotAve  (equiv, average, secfilt); 
 	  break;
 	case MAG_REF:
-	  value = PhotRef  (equiv, average, secfilt, measure); 
+	  value.Flt = PhotRef  (equiv, average, secfilt, measure); 
 	  break;
 	case MAG_ERR:
 	  if (field->photcode->type == PHOT_SEC) {
-	    value = PhotdM  (equiv, average, secfilt); 
+	    value.Flt = PhotdM  (equiv, average, secfilt); 
 	  } else {
-	    value = measure[0].dM;
+	    value.Flt = measure[0].dM;
 	  }
 	  break;
 	case MAG_CHISQ:
-	  value = PhotXm  (equiv, average, secfilt); 
+	  value.Flt = PhotXm  (equiv, average, secfilt); 
 	  break;
 	case MAG_NCODE:
 	  if (equiv == NULL) {
-	    value = NAN;
+	    value.Int = 0;
 	    break;
 	  }
 	  Nsec = GetPhotcodeNsec (equiv->code);
 	  if (Nsec == -1) break;
-	  value = secfilt[Nsec].Ncode;
+	  value.Int = secfilt[Nsec].Ncode;
 	  break;
 	case MAG_NPHOT:
 	  if (equiv == NULL) {
-	    value = NAN;
+	    value.Int = NAN;
 	    break;
 	  }
 	  Nsec = GetPhotcodeNsec (equiv->code);
 	  if (Nsec == -1) break;
-	  value = secfilt[Nsec].Nused;
+	  value.Int = secfilt[Nsec].Nused;
 	  break;
       }
       break;
     case MEAS_RA: /* OK */
-      value = average[0].R - measure[0].dR / 3600.0;
+      value.Flt = average[0].R - measure[0].dR / 3600.0;
       break;
     case MEAS_DEC: /* OK */
-      value = average[0].D - measure[0].dD / 3600.0;
+      value.Flt = average[0].D - measure[0].dD / 3600.0;
       break;
     case MEAS_RA_AVE: /* OK */
-      value = average[0].R;
+      value.Flt = average[0].R;
       break;
     case MEAS_DEC_AVE: /* OK */
-      value = average[0].D;
+      value.Flt = average[0].D;
       break;
 
@@ -164,5 +166,5 @@
 	haveGalacticMeas = TRUE;
       }
-      value = GLON_MEAS;
+      value.Flt = GLON_MEAS;
       break;
     case MEAS_GLAT:
@@ -171,5 +173,5 @@
 	haveGalacticMeas = TRUE;
       }
-      value = GLAT_MEAS;
+      value.Flt = GLAT_MEAS;
       break;
     case MEAS_ELON:
@@ -178,5 +180,5 @@
 	haveEclipticMeas = TRUE;
       }
-      value = ELON_MEAS;
+      value.Flt = ELON_MEAS;
       break;
     case MEAS_ELAT:
@@ -185,5 +187,5 @@
 	haveEclipticMeas = TRUE;
       }
-      value = ELAT_MEAS;
+      value.Flt = ELAT_MEAS;
       break;
 
@@ -193,5 +195,5 @@
 	haveGalacticAve = TRUE;
       }
-      value = GLON_AVE;
+      value.Flt = GLON_AVE;
       break;
     case MEAS_GLAT_AVE:
@@ -200,5 +202,5 @@
 	haveGalacticAve = TRUE;
       }
-      value = GLAT_AVE;
+      value.Flt = GLAT_AVE;
       break;
     case MEAS_ELON_AVE:
@@ -207,5 +209,5 @@
 	haveEclipticAve = TRUE;
       }
-      value = ELON_AVE;
+      value.Flt = ELON_AVE;
       break;
     case MEAS_ELAT_AVE:
@@ -214,105 +216,105 @@
 	haveEclipticAve = TRUE;
       }
-      value = ELAT_AVE;
+      value.Flt = ELAT_AVE;
       break;
 
     case MEAS_RA_AVE_ERR: /* OK */
-      value = average[0].dR;
+      value.Flt = average[0].dR;
       break;
     case MEAS_DEC_AVE_ERR: /* OK */
-      value = average[0].dD;
+      value.Flt = average[0].dD;
       break;
     case MEAS_U_RA: /* OK */
-      value = average[0].uR;
+      value.Flt = average[0].uR;
       break;
     case MEAS_U_DEC: /* OK */
-      value = average[0].uD;
+      value.Flt = average[0].uD;
       break;
     case MEAS_U_RA_ERR: /* OK */
-      value = average[0].duR;
+      value.Flt = average[0].duR;
       break;
     case MEAS_U_DEC_ERR: /* OK */
-      value = average[0].duD;
+      value.Flt = average[0].duD;
       break;
     case MEAS_PAR: /* OK */
-      value = average[0].R;
+      value.Flt = average[0].R;
       break;
     case MEAS_PAR_ERR: /* OK */
-      value = average[0].D;
+      value.Flt = average[0].D;
       break;
     case MEAS_XP: /* OK */
-      value = average[0].Xp;
+      value.Flt = average[0].Xp;
       break;
     case MEAS_NMEAS: /* OK */
-      value = average[0].Nmeasure;
+      value.Int = average[0].Nmeasure;
       break;
     case MEAS_NMISS: /* OK */
-      value = average[0].Nmissing;
+      value.Int = average[0].Nmissing;
       break;
     case MEAS_OBJFLAGS: /* OK */
-      value = average[0].code;
+      value.Int = average[0].code;
       break;
     // note that these represent the ra displacement relative to the average, not 
     // the error.
     case MEAS_RA_OFFSET: /* OK */
-      value = measure[0].dR;
+      value.Flt = measure[0].dR;
       break;
     case MEAS_DEC_OFFSET: /* OK */
-      value = measure[0].dD;
+      value.Flt = measure[0].dD;
       break;
     case MEAS_RA_FIT_OFFSET: /* OK */
       dT = (measure[0].t - TimeRefPM) / (86400*365.25);
-      value = average[0].uR * dT + measure[0].dR;
+      value.Flt = average[0].uR * dT + measure[0].dR;
       break;
     case MEAS_DEC_FIT_OFFSET: /* OK */
       dT = (measure[0].t - TimeRefPM) / (86400*365.25);
-      value = average[0].uD * dT + measure[0].dD;
+      value.Flt = average[0].uD * dT + measure[0].dD;
       break;
     case MEAS_RA_OFFSET_ERR: /* OK */
-      value = NAN;
+      value.Flt = NAN;
       break;
     case MEAS_DEC_OFFSET_ERR: /* OK */
-      value = NAN;
+      value.Flt = NAN;
       break;
     case MEAS_AIRMASS: /* OK */
-      value = measure[0].airmass;
+      value.Flt = measure[0].airmass;
       break;
     case MEAS_AZ: /* OK */
-      value = measure[0].az;
+      value.Flt = measure[0].az;
       break;
     case MEAS_EXPTIME: /* OK */
-      value = pow (10.0, measure[0].dt * 0.4);
+      value.Flt = pow (10.0, measure[0].dt * 0.4);
       break;
     case MEAS_PHOTCODE: /* OK */
-      value = measure[0].photcode;
+      value.Int = measure[0].photcode;
       break;
     case MEAS_TIME: /* OK */
-      value = TimeValue (measure[0].t, TimeReference, TimeFormat);
+      value.Flt = TimeValue (measure[0].t, TimeReference, TimeFormat);
       break;
     case MEAS_FWHM: /* OK */
-      value = 0.01*(measure[0].FWx + measure[0].FWy) / 2.0;
+      value.Flt = 0.01*(measure[0].FWx + measure[0].FWy) / 2.0;
       break;
     case MEAS_FWHM_MAJ: /* OK */
-      value = 0.01*measure[0].FWx;
+      value.Flt = 0.01*measure[0].FWx;
       break;
     case MEAS_FWHM_MIN: /* OK */
-      value = 0.01*measure[0].FWy;
+      value.Flt = 0.01*measure[0].FWy;
       break;
     case MEAS_THETA: /* OK */
-      value = measure[0].theta;
+      value.Flt = measure[0].theta;
       break;
     case MEAS_DOPHOT: /* OK */
-      value = measure[0].dophot;
+      value.Flt = measure[0].dophot;
       break;
     case MEAS_DB_FLAGS: /* ? */
-      value = measure[0].dbFlags;
+      value.Int = measure[0].dbFlags;
       break;
     case MEAS_PHOT_FLAGS: /* ? */
-      value = measure[0].photFlags;
+      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 = measure[0].Xccd;
+      value.Flt = measure[0].Xccd;
 # else
       { 
@@ -323,5 +325,5 @@
 	if (image == NULL) break;
 	RD_to_XY (&x, &y, ra, dec, &image[0].coords);
-	value = x;
+	value.Flt = x;
       }
 # endif
@@ -330,5 +332,5 @@
 /* I need to perform this conversion for ELIXIR and LONEOS formats on load */      
 # if 1
-      value = measure[0].Yccd;
+      value.Flt = measure[0].Yccd;
 # else
       {
@@ -339,7 +341,13 @@
 	if (image == NULL) break;
 	RD_to_XY (&x, &y, ra, dec, &image[0].coords);
-	value = y;
+	value.Flt = y;
       }
 # endif
+      break;
+    case MEAS_XCCD_ERR: /* OK */
+      value.Flt = measure[0].dXccd;
+      break;
+    case MEAS_YCCD_ERR: /* OK */
+      value.Flt = measure[0].dYccd;
       break;
     case MEAS_XMOSAIC: /* OK */
@@ -349,5 +357,5 @@
       if (mosaic == NULL) break;
       RD_to_XY (&x, &y, ra, dec, mosaic);
-      value = x;
+      value.Flt = x;
       break;
     case MEAS_YMOSAIC: /* OK */
@@ -357,37 +365,40 @@
       if (mosaic == NULL) break;
       RD_to_XY (&x, &y, ra, dec, mosaic);
-      value = y;
+      value.Flt = y;
       break;
 
     case MEAS_SKY: /* OK */
-      value = measure[0].Sky;
+      value.Flt = measure[0].Sky;
       break;
     case MEAS_dSKY: /* OK */
-      value = measure[0].dSky;
+      value.Flt = measure[0].dSky;
       break;
     case MEAS_DET_ID: /* OK */
-      value = measure[0].detID;
+      value.Int = measure[0].detID;
       break;
     case MEAS_OBJ_ID: /* OK */
-      value = measure[0].averef;
+      // XXX this should probably return average[0].objID
+      value.Int = average[0].objID;
       break;
     case MEAS_IMAGE_ID: /* OK */
-      value = measure[0].imageID;
+      value.Int = measure[0].imageID;
       break;
     case MEAS_PSF_QF: /* OK */
-      value = measure[0].qPSF;
+      value.Flt = measure[0].qPSF;
       break;
     case MEAS_PSF_CHISQ: /* OK */
-      value = measure[0].psfChisq;
+      value.Flt = measure[0].psfChisq;
       break;
     case MEAS_CR_NSIGMA: /* OK */
-      value = measure[0].crNsigma;
+      value.Flt = measure[0].crNsigma;
       break;
     case MEAS_EXT_NSIGMA: /* OK */
-      value = measure[0].extNsigma;
+      value.Flt = measure[0].extNsigma;
       break;
     case MEAS_STARGAL: /* OK */
-      value = measure[0].stargal;
-      break;
+      value.Flt = measure[0].stargal;
+      break;
+
+      // add the star/galaxy sep -- 
   }
   return (value);
Index: /trunk/Ohana/src/opihi/dvo/dbFields.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/dbFields.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/dvo/dbFields.c	(revision 20936)
@@ -23,4 +23,5 @@
   field->table = 0;
   field->ID = 0;
+  field->type = OPIHI_FLT;
   field->magMode = 0;
   field->photcode = NULL;
@@ -89,7 +90,8 @@
 }
 
-# define ESCAPE(F,M) { \
+# define ESCAPE(F,M,T) { \
   field->ID = (F); \
   field->magMode = (M); \
+  field->type = (T); \
   field->photcode = NULL; \
   return (TRUE); }
@@ -105,90 +107,91 @@
   if (!strcasecmp (fieldName, "GLON"))       {
     dbExtractMeasuresInitTransform (COORD_GALACTIC);
-    ESCAPE (MEAS_GLON, MAG_NONE);
+    ESCAPE (MEAS_GLON, MAG_NONE, OPIHI_FLT);
   }
   if (!strcasecmp (fieldName, "GLAT")) {
     dbExtractMeasuresInitTransform (COORD_GALACTIC);
-    ESCAPE (MEAS_GLAT, MAG_NONE);
+    ESCAPE (MEAS_GLAT, MAG_NONE, OPIHI_FLT);
   }
   if (!strcasecmp (fieldName, "GLON:AVE")) {
     dbExtractMeasuresInitTransform (COORD_GALACTIC);
-    ESCAPE (MEAS_GLON_AVE, MAG_NONE);
+    ESCAPE (MEAS_GLON_AVE, MAG_NONE, OPIHI_FLT);
   }
   if (!strcasecmp (fieldName, "GLAT:AVE")) {
     dbExtractMeasuresInitTransform (COORD_GALACTIC);
-    ESCAPE (MEAS_GLAT_AVE, MAG_NONE);
+    ESCAPE (MEAS_GLAT_AVE, MAG_NONE, OPIHI_FLT);
   }
 
   if (!strcasecmp (fieldName, "ELON"))       {
     dbExtractMeasuresInitTransform (COORD_ECLIPTIC);
-    ESCAPE (MEAS_ELON, MAG_NONE);
+    ESCAPE (MEAS_ELON, MAG_NONE, OPIHI_FLT);
   }
   if (!strcasecmp (fieldName, "ELAT")) {
     dbExtractMeasuresInitTransform (COORD_ECLIPTIC);
-    ESCAPE (MEAS_ELAT, MAG_NONE);
+    ESCAPE (MEAS_ELAT, MAG_NONE, OPIHI_FLT);
   }
   if (!strcasecmp (fieldName, "ELON:AVE")) {
     dbExtractMeasuresInitTransform (COORD_ECLIPTIC);
-    ESCAPE (MEAS_ELON_AVE, MAG_NONE);
+    ESCAPE (MEAS_ELON_AVE, MAG_NONE, OPIHI_FLT);
   }
   if (!strcasecmp (fieldName, "ELAT:AVE")) {
     dbExtractMeasuresInitTransform (COORD_ECLIPTIC);
-    ESCAPE (MEAS_ELAT_AVE, MAG_NONE);
-  }
-
-  if (!strcasecmp (fieldName, "RA"))         ESCAPE (MEAS_RA,   	MAG_NONE);
-  if (!strcasecmp (fieldName, "DEC"))        ESCAPE (MEAS_DEC,  	MAG_NONE);
-  if (!strcasecmp (fieldName, "RA:AVE"))     ESCAPE (MEAS_RA_AVE,      	MAG_NONE);
-  if (!strcasecmp (fieldName, "DEC:AVE"))    ESCAPE (MEAS_DEC_AVE,     	MAG_NONE);
-  if (!strcasecmp (fieldName, "RA:ERR"))     ESCAPE (MEAS_RA_AVE_ERR,  	MAG_NONE);
-  if (!strcasecmp (fieldName, "DEC:ERR"))    ESCAPE (MEAS_DEC_AVE_ERR, 	MAG_NONE);
-
-  if (!strcasecmp (fieldName, "uRA"))        ESCAPE (MEAS_U_RA,        	MAG_NONE);
-  if (!strcasecmp (fieldName, "uDEC"))       ESCAPE (MEAS_U_DEC,       	MAG_NONE);
-  if (!strcasecmp (fieldName, "duRA"))       ESCAPE (MEAS_U_RA_ERR,    	MAG_NONE);
-  if (!strcasecmp (fieldName, "duDEC"))      ESCAPE (MEAS_U_DEC_ERR,   	MAG_NONE);
-  if (!strcasecmp (fieldName, "PAR"))        ESCAPE (MEAS_PAR,         	MAG_NONE);
-  if (!strcasecmp (fieldName, "dPAR"))       ESCAPE (MEAS_PAR_ERR,      MAG_NONE);
-  if (!strcasecmp (fieldName, "dR"))         ESCAPE (MEAS_RA_OFFSET,   	MAG_NONE);
-  if (!strcasecmp (fieldName, "dD"))         ESCAPE (MEAS_DEC_OFFSET,  	MAG_NONE);
-  if (!strcasecmp (fieldName, "dR:FIT"))     ESCAPE (MEAS_RA_FIT_OFFSET,  MAG_NONE);
-  if (!strcasecmp (fieldName, "dD:FIT"))     ESCAPE (MEAS_DEC_FIT_OFFSET, MAG_NONE);
-  if (!strcasecmp (fieldName, "dR:ERR"))     ESCAPE (MEAS_RA_OFFSET_ERR,  MAG_NONE);
-  if (!strcasecmp (fieldName, "dD:ERR"))     ESCAPE (MEAS_DEC_OFFSET_ERR, MAG_NONE);
-  if (!strcasecmp (fieldName, "xp"))         ESCAPE (MEAS_XP,          	MAG_NONE);
-  if (!strcasecmp (fieldName, "nmeas"))      ESCAPE (MEAS_NMEAS,       	MAG_NONE);
-  if (!strcasecmp (fieldName, "nmiss"))      ESCAPE (MEAS_NMISS,       	MAG_NONE);
-  if (!strcasecmp (fieldName, "objflags"))   ESCAPE (MEAS_OBJFLAGS,     MAG_NONE);
-  if (!strcasecmp (fieldName, "AIRMASS"))    ESCAPE (MEAS_AIRMASS,     	MAG_NONE);
-  if (!strcasecmp (fieldName, "ALT"))        ESCAPE (MEAS_ALT,     	MAG_NONE);
-  if (!strcasecmp (fieldName, "AZ"))         ESCAPE (MEAS_AZ,     	MAG_NONE);
-  if (!strcasecmp (fieldName, "EXPTIME"))    ESCAPE (MEAS_EXPTIME,     	MAG_NONE);
-  if (!strcasecmp (fieldName, "PHOTCODE"))   ESCAPE (MEAS_PHOTCODE,    	MAG_NONE);
-  if (!strcasecmp (fieldName, "TIME"))       ESCAPE (MEAS_TIME,        	MAG_NONE);
-  if (!strcasecmp (fieldName, "FWHM"))       ESCAPE (MEAS_FWHM,        	MAG_NONE);
-  if (!strcasecmp (fieldName, "FWHM_MAJ"))   ESCAPE (MEAS_FWHM_MAJ,    	MAG_NONE);
-  if (!strcasecmp (fieldName, "FWHM_MIN"))   ESCAPE (MEAS_FWHM_MIN,    	MAG_NONE);
-  if (!strcasecmp (fieldName, "THETA"))      ESCAPE (MEAS_THETA,       	MAG_NONE);
-  if (!strcasecmp (fieldName, "DOPHOT"))     ESCAPE (MEAS_DOPHOT,      	MAG_NONE);
-  if (!strcasecmp (fieldName, "DB_FLAGS"))   ESCAPE (MEAS_DB_FLAGS,    	MAG_NONE);
-  if (!strcasecmp (fieldName, "PHOT_FLAGS")) ESCAPE (MEAS_PHOT_FLAGS, 	MAG_NONE);
-  if (!strcasecmp (fieldName, "XCCD"))       ESCAPE (MEAS_XCCD, 	MAG_NONE);
-  if (!strcasecmp (fieldName, "YCCD"))       ESCAPE (MEAS_YCCD, 	MAG_NONE);
-  if (!strcasecmp (fieldName, "XMOSAIC"))    ESCAPE (MEAS_XMOSAIC,     	MAG_NONE);
-  if (!strcasecmp (fieldName, "YMOSAIC"))    ESCAPE (MEAS_YMOSAIC,     	MAG_NONE);
-  if (!strcasecmp (fieldName, "XCHIP"))      ESCAPE (MEAS_XCCD, 	MAG_NONE);
-  if (!strcasecmp (fieldName, "YCHIP"))      ESCAPE (MEAS_YCCD, 	MAG_NONE);
-  if (!strcasecmp (fieldName, "XFPA"))       ESCAPE (MEAS_XMOSAIC,     	MAG_NONE);
-  if (!strcasecmp (fieldName, "YFPA"))       ESCAPE (MEAS_YMOSAIC,     	MAG_NONE);
-  if (!strcasecmp (fieldName, "DETID"))      ESCAPE (MEAS_DET_ID,     	MAG_NONE);
-  if (!strcasecmp (fieldName, "OBJID"))      ESCAPE (MEAS_OBJ_ID,     	MAG_NONE);
-  if (!strcasecmp (fieldName, "IMAGEID"))    ESCAPE (MEAS_IMAGE_ID,     MAG_NONE);
-  if (!strcasecmp (fieldName, "PSF_QF"))     ESCAPE (MEAS_PSF_QF,     	MAG_NONE);
-  if (!strcasecmp (fieldName, "PSF_CHISQ"))  ESCAPE (MEAS_PSF_CHISQ,    MAG_NONE);
-  if (!strcasecmp (fieldName, "CR_NSIGMA"))  ESCAPE (MEAS_CR_NSIGMA,    MAG_NONE);
-  if (!strcasecmp (fieldName, "EXT_NSIGMA")) ESCAPE (MEAS_EXT_NSIGMA,   MAG_NONE);
-  if (!strcasecmp (fieldName, "SKY"))        ESCAPE (MEAS_SKY,     	MAG_NONE);
-  if (!strcasecmp (fieldName, "SKY_ERR"))    ESCAPE (MEAS_dSKY,     	MAG_NONE);
-  if (!strcasecmp (fieldName, "STARGAL"))    ESCAPE (MEAS_STARGAL,     	MAG_NONE);
+    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, "xp"))         ESCAPE (MEAS_XP,          	  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, "objflags"))   ESCAPE (MEAS_OBJFLAGS,       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, "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, "DOPHOT"))     ESCAPE (MEAS_DOPHOT,      	  MAG_NONE, OPIHI_FLT);
+  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, "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, "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, "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_CHISQ"))  ESCAPE (MEAS_PSF_CHISQ,      MAG_NONE, OPIHI_FLT);
+  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, "STARGAL"))    ESCAPE (MEAS_STARGAL,     	  MAG_NONE, OPIHI_FLT);
 
   // for words that don't parse, try a photcode
@@ -196,8 +199,12 @@
   // check for code:mode in photcode name 
   code = ParsePhotcodeField (fieldName, &mode, MAG_REL);
-  if (code == NULL) return (FALSE);
+  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;
+  field->type = OPIHI_FLT;
   field->photcode = code;
   return (TRUE);
@@ -216,9 +223,9 @@
   if (!strcasecmp (fieldName, "GLON"))  { 
     dbExtractAveragesInitTransform (COORD_GALACTIC);
-    ESCAPE (AVE_GLON, MAG_NONE);
+    ESCAPE (AVE_GLON, MAG_NONE, OPIHI_FLT);
   }
   if (!strcasecmp (fieldName, "GLAT"))  {
     dbExtractAveragesInitTransform (COORD_GALACTIC);
-    ESCAPE (AVE_GLAT, MAG_NONE);
+    ESCAPE (AVE_GLAT, MAG_NONE, OPIHI_FLT);
   }
 
@@ -227,27 +234,32 @@
   if (!strcasecmp (fieldName, "ELON"))  { 
     dbExtractAveragesInitTransform (COORD_ECLIPTIC);
-    ESCAPE (AVE_ELON, MAG_NONE);
+    ESCAPE (AVE_ELON, MAG_NONE, OPIHI_FLT);
   }
   if (!strcasecmp (fieldName, "ELAT"))  {
     dbExtractAveragesInitTransform (COORD_ECLIPTIC);
-    ESCAPE (AVE_ELAT, MAG_NONE);
-  }
-
-  if (!strcasecmp (fieldName, "RA"))    ESCAPE (AVE_RA,        MAG_NONE);
-  if (!strcasecmp (fieldName, "DEC"))   ESCAPE (AVE_DEC,       MAG_NONE);
-  if (!strcasecmp (fieldName, "dRA"))   ESCAPE (AVE_RA_ERR,    MAG_NONE);
-  if (!strcasecmp (fieldName, "dDEC"))  ESCAPE (AVE_DEC_ERR,   MAG_NONE);
-  if (!strcasecmp (fieldName, "uRA"))   ESCAPE (AVE_U_RA,      MAG_NONE);
-  if (!strcasecmp (fieldName, "uDEC"))  ESCAPE (AVE_U_DEC,     MAG_NONE);
-  if (!strcasecmp (fieldName, "duRA"))  ESCAPE (AVE_U_RA_ERR,  MAG_NONE);
-  if (!strcasecmp (fieldName, "duDEC")) ESCAPE (AVE_U_DEC_ERR, MAG_NONE);
-  if (!strcasecmp (fieldName, "PAR"))   ESCAPE (AVE_PAR,       MAG_NONE);
-  if (!strcasecmp (fieldName, "dPAR"))  ESCAPE (AVE_PAR_ERR,   MAG_NONE);
-  if (!strcasecmp (fieldName, "Xp"))    ESCAPE (AVE_Xp,        MAG_NONE);
-  if (!strcasecmp (fieldName, "NMEAS")) ESCAPE (AVE_NMEAS,     MAG_NONE);
-  if (!strcasecmp (fieldName, "NMISS")) ESCAPE (AVE_NMISS,     MAG_NONE);
-  if (!strcasecmp (fieldName, "FLAG"))  ESCAPE (AVE_FLAG,      MAG_NONE);
-  if (!strcasecmp (fieldName, "TYPE"))  ESCAPE (AVE_TYPE,      MAG_NONE);
-  if (!strcasecmp (fieldName, "OBJID")) ESCAPE (AVE_OBJID,     MAG_NONE);
+    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, "Xp"))    ESCAPE (AVE_Xp,        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, "FLAG"))  ESCAPE (AVE_FLAG,      MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "TYPE"))  ESCAPE (AVE_TYPE,      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);
 
   // for words that don't parse, try a photcode
@@ -255,5 +267,9 @@
   // check for code:mode in photcode name 
   code = ParsePhotcodeField (fieldName, &mode, MAG_AVE);
-  if (code == NULL) return (FALSE);
+  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");
@@ -264,5 +280,104 @@
   field->ID = AVE_MAG;
   field->magMode = mode;
+  field->type = OPIHI_FLT;
   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, "trate"    )) ESCAPE (IMAGE_TRATE,     MAG_NONE, OPIHI_FLT);
+
+  // XXX : these are mapped to ridiculous things: Myyyy + 0x8000 and Mxxxx
+  if (!strcasecmp (fieldName, "ncal"     )) ESCAPE (IMAGE_NCAL,      MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "sky"      )) ESCAPE (IMAGE_SKY,       MAG_NONE, OPIHI_FLT);
+
+  if (!strcasecmp (fieldName, "flag"     )) ESCAPE (IMAGE_FLAG,      MAG_NONE, OPIHI_INT);
+  if (!strcasecmp (fieldName, "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);
+
+  // 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/opihi/dvo/dbRPN.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/dbRPN.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/dvo/dbRPN.c	(revision 20936)
@@ -21,78 +21,74 @@
     
     /* decide on priority of object */
-    type = 0;
+    type = DB_STACK_NONE;
     /* unary operations */
-    if (!strcmp (argv[i], "abs"))    { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "int"))    { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "exp"))    { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "ten"))    { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "log"))    { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "ln"))     { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "sqrt"))   { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "erf"))    { type = 9; goto gotit; }
-
-    if (!strcmp (argv[i], "sinh"))   { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "cosh"))   { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "asinh"))  { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "acosh"))  { type = 9; goto gotit; }
-
-    if (!strcmp (argv[i], "sin"))    { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "cos"))    { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "tan"))    { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "dsin"))   { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "dcos"))   { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "dtan"))   { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "asin"))   { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "acos"))   { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "atan"))   { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "dasin"))  { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "dacos"))  { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "datan"))  { type = 9; goto gotit; }
-
-    if (!strcmp (argv[i], "lgamma")) { type = 9; goto gotit; }
-
-    if (!strcmp (argv[i], "rnd"))    { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "xramp"))  { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "yramp"))  { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "ramp"))   { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "zero"))   { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "--"))     { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "not"))    { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "isinf"))  { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "isnan"))  { type = 9; goto gotit; }
+    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 = 8; goto gotit; }
-
-    if (!strcmp (argv[i], "@"))      { type = 7; goto gotit; }
-    if (!strcmp (argv[i], "/"))      { type = 7; goto gotit; }
-    if (!strcmp (argv[i], "*"))      { type = 7; goto gotit; }
-    if (!strcmp (argv[i], "%"))      { type = 7; goto gotit; }
-
-    if (!strcmp (argv[i], "+"))      { type = 6; goto gotit; }
-    if (!strcmp (argv[i], "-"))      { type = 6; goto gotit; }
+    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 = 5; goto gotit; }
-    if (!strcmp (argv[i], "|"))      { type = 5; goto gotit; }
-
-    if (!strcmp (argv[i], "<"))      { type = 4; goto gotit; }
-    if (!strcmp (argv[i], ">"))      { type = 4; goto gotit; }
-    if (!strcmp (argv[i], "=="))     { type = 4; strcpy (argv[i], "E"); goto gotit; }
-    if (!strcmp (argv[i], "!="))     { type = 4; strcpy (argv[i], "N"); goto gotit; }
-    if (!strcmp (argv[i], "<="))     { type = 4; strcpy (argv[i], "L"); goto gotit; }
-    if (!strcmp (argv[i], ">="))     { type = 4; strcpy (argv[i], "G"); goto gotit; }
-    if (!strcmp (argv[i], ">>"))     { type = 4; strcpy (argv[i], "U"); goto gotit; }
-    if (!strcmp (argv[i], "<<"))     { type = 4; strcpy (argv[i], "D"); goto gotit; }
-
-    if (!strcmp (argv[i], "&&"))     { type = 3; strcpy (argv[i], "A"); goto gotit; }
-    if (!strcmp (argv[i], "||"))     { type = 3; strcpy (argv[i], "O"); goto gotit; }
-
-    if (!strcmp (argv[i], "("))      { type = 2; goto gotit; }
-    if (!strcmp (argv[i], ")"))      { type = 1; 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 8:  /* exponentiation: 2^2^3 = 64 != 256 (precedence is right-to-left, not left-to-right!) */
+      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--) {
@@ -107,10 +103,10 @@
 	Nop_stack ++;
 	break;
-      case 9: /* unary OPs */
-      case 7: /* binary OPs */
-      case 6:
-      case 5: 
-      case 4: 
-      case 3: 
+      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--) {
@@ -125,5 +121,5 @@
 	Nop_stack ++;
 	break;
-      case 2:  
+      case DB_STACK_OPEN_PAR:  
 	/* push operator on OP stack */
 	op_stack[Nop_stack].name = strcreate (argv[i]);
@@ -131,7 +127,7 @@
 	Nop_stack ++;
 	break;
-      case 1: 
+      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 != 2); j--) {
+	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;
@@ -139,5 +135,5 @@
 	  Nop_stack --;
 	}
-	if ((j == -1) || (op_stack[j].type != 2)) {
+	if ((j == -1) || (op_stack[j].type != DB_STACK_OPEN_PAR)) {
 	  push_error ("syntax error: mismatched parenthesis");
 	  Nstack = 0;
@@ -150,5 +146,5 @@
 	/* value of 'X' is used as sentinel until we sort out values */
 	stack[Nstack].name = strcreate (argv[i]);
-	stack[Nstack].type = 'X';
+	stack[Nstack].type = DB_STACK_VALUE;
 	Nstack ++;
 	break;
@@ -156,7 +152,7 @@
   }
 
-  /* dump remaining operators on stack, checking for ')' */
+  /* dump remaining operators on stack, checking for '(' */
   for (j = Nop_stack - 1; j >= 0; j--) {
-    if (op_stack[j].type == 2) {
+    if (op_stack[j].type == DB_STACK_OPEN_PAR) {
       push_error ("syntax error: mismatched parenthesis");
       Nstack = 0;
Index: /trunk/Ohana/src/opihi/dvo/dbStackMath.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/dbStackMath.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/dvo/dbStackMath.c	(revision 20936)
@@ -4,143 +4,133 @@
 static int NallocUnary = 0;
 
-dbStack *dbBinary (dbStack *V1, dbStack *V2, char *op, float *fields) {
+dbStack *dbBinary (dbStack *V1, dbStack *V2, char *op, dbValue *fields) {
 
-  int N;
-  float M1, M2;
   dbStack *OUT;
   
-  if (V1->type == 'F') {
-    N = V1->field;
-    M1 = fields[N];
-  } else {
-    M1 = V1->Float;
-  }
-  
-  if (V2->type == 'F') {
-    N = V2->field;
-    M2 = fields[N];
-  } else {
-    M2 = V2->Float;
+# 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->type = 'T';
   OUT->name = NULL;
 
-  // use an enum for the op...
+  // XXX use an enum for the op...
   switch (op[0]) { 
-  case '+': 
-    OUT->Float = M1 + M2;
-    break; 
-  case '-': 
-    OUT->Float = M1 - M2;
-    break; 
-  case '*': 
-    OUT->Float = M1 * M2;
-    break; 
-  case '/': 
-    OUT->Float = M1 / M2;
-    break; 
-  case '%': 
-    OUT->Float = (int) M1 % (int) M2;
-    break; 
-  case 0x5e: 
-    OUT->Float = pow (M1, M2);
-    break; 
-  case 'D': 
-    OUT->Float = MIN (M1, M2);
-    break; 
-  case 'U': 
-    OUT->Float = MAX (M1, M2);
-    break; 
-  case '<': 
-    OUT->Float = (M1 < M2) ? 1 : 0;
-    break; 
-  case '>': 
-    OUT->Float = (M1 > M2) ? 1 : 0;
-    break; 
-  case '&': 
-    OUT->Float = ((int)M1 & (int)M2);
-    break; 
-  case '|': 
-    OUT->Float = ((int)M1 | (int)M2);
-    break; 
-  case 'E': 
-    OUT->Float = (M1 == M2) ? 1 : 0;
-    break; 
-  case 'N': 
-    OUT->Float = (M1 != M2) ? 1 : 0;
-    break; 
-  case 'L': 
-    OUT->Float = (M1 <= M2) ? 1 : 0;
-    break; 
-  case 'G': 
-    OUT->Float = (M1 >= M2) ? 1 : 0;
-    break; 
-  case 'A': 
-    OUT->Float = (M1 && M2) ? 1 : 0;
-    break; 
-  case 'O': 
-    OUT->Float = (M1 || M2) ? 1 : 0;
-    break; 
+    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, float *fields) {
+dbStack *dbUnary (dbStack *V1, char *op, dbValue *fields) {
 
-  int N;
-  float M1;
   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);							\
+    }									\
+  }
 
-  if (V1->type == 'F') {
-    N = V1->field;
-    M1 = fields[N];
-  } else {
-    M1 = V1->Float;
-  }
-  
   NallocUnary ++;
   ALLOCATE (OUT, dbStack, 1);
-  OUT->type = 'T';
   OUT->name = NULL;
 
-  if (!strcmp (op, "="))      {   OUT->Float = M1;                 }
-  if (!strcmp (op, "abs"))    {   OUT->Float = fabs(M1);           }
-  if (!strcmp (op, "int"))    {   OUT->Float = (float)(int)(M1);   }
-  if (!strcmp (op, "exp"))    {   OUT->Float = exp (M1);           }
-  if (!strcmp (op, "ten"))    {   OUT->Float = pow (10.0,M1);      }
-  if (!strcmp (op, "log"))    {   OUT->Float = log10 (M1);         }
-  if (!strcmp (op, "ln"))     {   OUT->Float = log (M1);           }
-  if (!strcmp (op, "sqrt"))   {   OUT->Float = sqrt (M1);          }
-  if (!strcmp (op, "erf"))    {   OUT->Float = erf (M1);           }
-			      			      
-  if (!strcmp (op, "sinh"))   {   OUT->Float = sinh (M1);          }
-  if (!strcmp (op, "cosh"))   {   OUT->Float = cosh (M1);          }
-  if (!strcmp (op, "asinh"))  {   OUT->Float = asinh (M1);         }
-  if (!strcmp (op, "acosh"))  {   OUT->Float = acosh (M1);         }
-  if (!strcmp (op, "lgamma")) {   OUT->Float = lgamma (M1);        }
+  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, "sin"))    {   OUT->Float = sin (M1);           }
-  if (!strcmp (op, "cos"))    {   OUT->Float = cos (M1);           }
-  if (!strcmp (op, "tan"))    {   OUT->Float = tan (M1);           }
-  if (!strcmp (op, "dsin"))   {   OUT->Float = sin (M1*RAD_DEG);   }
-  if (!strcmp (op, "dcos"))   {   OUT->Float = cos (M1*RAD_DEG);   }
-  if (!strcmp (op, "dtan"))   {   OUT->Float = tan (M1*RAD_DEG);   }
-  if (!strcmp (op, "asin"))   {   OUT->Float = asin (M1);          }
-  if (!strcmp (op, "acos"))   {   OUT->Float = acos (M1);          }
-  if (!strcmp (op, "atan"))   {   OUT->Float = atan (M1);          }
-  if (!strcmp (op, "dasin"))  {   OUT->Float = asin (M1)*DEG_RAD;  }
-  if (!strcmp (op, "dacos"))  {   OUT->Float = acos (M1)*DEG_RAD;  }
-  if (!strcmp (op, "datan"))  {   OUT->Float = atan (M1)*DEG_RAD;  }
-  if (!strcmp (op, "rnd"))    {   OUT->Float = drand48();          }
-  if (!strcmp (op, "not"))    {   OUT->Float = !(M1);              }
-  if (!strcmp (op, "--"))     {   OUT->Float = - (M1);             }
-  if (!strcmp (op, "isinf"))  {   OUT->Float = !finite(M1);        }
-  if (!strcmp (op, "isnan"))  {   OUT->Float = isnan(M1);          } 
+  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);
Index: /trunk/Ohana/src/opihi/dvo/dbStackOps.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/dbStackOps.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/dvo/dbStackOps.c	(revision 20936)
@@ -2,5 +2,5 @@
 
 void dbInitStack (dbStack *stack) {
-  stack[0].type   = 0;
+  stack[0].type   = DB_STACK_NONE;
   stack[0].name   = NULL;
 }
@@ -34,5 +34,5 @@
 void dbFreeTempEntry (dbStack *stack) {
 
-  if (stack->type != 'T') return;
+  if (!(stack->type & DB_STACK_TEMP)) return;
 
   if (stack[0].name != NULL)  free (stack[0].name);
Index: unk/Ohana/src/opihi/dvo/db_check_stack.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/db_check_stack.c	(revision 20935)
+++ 	(revision )
@@ -1,54 +1,0 @@
-# include "opihi.h"
-
-int db_check_stack (dvoStack *stack, int Nstack, int table, dvoField *fields, int *Nfields) {
-
-  int i, Nx, Ny, Nv, size;
-  char *c;
-
-  NFIELDS = *Nfields + 10;
-  REALLOCATE (fields, dvoField, NFIELDS);
-
-  for (i = 0; i < Nstack; i++) {
-    if (stack[i].type == 'X') {
-
-      /** if this is a number, put it on the list of scalers and move on **/
-      stack[i].Float = strtod (stack[i].name, &c);
-      if (c == stack[i].name + strlen (stack[i].name)) {
-	stack[i].type  = 'S';
-	continue;
-      } 
-
-      // 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  = 'F';
-	continue;
-      }
-
-      // this must be a field : is it a valid name?
-      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 (!status) {
-	gprint (GP_ERR, "unknown database field %s\n", stack[i].name);
-	return (FALSE);
-      }
-      stack[i].field = *Nfields;
-      stack[i].type  = 'F';
-
-      *Nfields ++;
-      CHECK_REALLOCATE (fields, dvoField, NFIELDS, *Nfields, 10);
-    }
-  }
-  return (TRUE);
-}
-
-/* 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/db_convert_to_RPN.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/db_convert_to_RPN.c	(revision 20935)
+++ 	(revision )
@@ -1,210 +1,0 @@
-# include "opihi.h"
-# define DUMPSTACK 0
-
-dvoStack *convert_to_RPN (int argc, char **argv, int *nstack) {
-  
-  int type, Nx, Ny;
-  int i, j, Nstack, Nop_stack, NSTACK;
-  dvoStack *stack, *op_stack;
-
-  /* max total stack size is argc, though should be less, this is safe */
-  NSTACK = argc + 5;
-  ALLOCATE (stack, dvoStack, NSTACK);
-  ALLOCATE (op_stack, dvoStack, NSTACK);
-  for (i = 0; i < NSTACK; i++) {
-    init_stack (&stack[i]);
-    init_stack (&op_stack[i]);
-  }
-  
-  Nx = Ny = Nstack = Nop_stack = 0;
-  for (i = 0; i < argc; i++) {
-    
-    /* decide on priority of object */
-    type = 0;
-    /* unary operations */
-    if (!strcmp (argv[i], "abs"))    { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "int"))    { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "exp"))    { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "ten"))    { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "log"))    { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "ln"))     { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "sqrt"))   { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "erf"))    { type = 9; goto gotit; }
-
-    if (!strcmp (argv[i], "sinh"))   { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "cosh"))   { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "asinh"))  { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "acosh"))  { type = 9; goto gotit; }
-
-    if (!strcmp (argv[i], "sin"))    { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "cos"))    { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "tan"))    { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "dsin"))   { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "dcos"))   { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "dtan"))   { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "asin"))   { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "acos"))   { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "atan"))   { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "dasin"))  { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "dacos"))  { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "datan"))  { type = 9; goto gotit; }
-
-    if (!strcmp (argv[i], "lgamma")) { type = 9; goto gotit; }
-
-    if (!strcmp (argv[i], "rnd"))    { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "xramp"))  { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "yramp"))  { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "ramp"))   { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "zero"))   { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "--"))     { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "not"))    { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "isinf"))  { type = 9; goto gotit; }
-    if (!strcmp (argv[i], "isnan"))  { type = 9; goto gotit; }
-
-    /* binary operations */
-    if (!strcmp (argv[i], "^"))      { type = 8; goto gotit; }
-
-    if (!strcmp (argv[i], "@"))      { type = 7; goto gotit; }
-    if (!strcmp (argv[i], "/"))      { type = 7; goto gotit; }
-    if (!strcmp (argv[i], "*"))      { type = 7; goto gotit; }
-    if (!strcmp (argv[i], "%"))      { type = 7; goto gotit; }
-
-    if (!strcmp (argv[i], "+"))      { type = 6; goto gotit; }
-    if (!strcmp (argv[i], "-"))      { type = 6; goto gotit; }
-	
-    if (!strcmp (argv[i], "&"))      { type = 5; goto gotit; }
-    if (!strcmp (argv[i], "|"))      { type = 5; goto gotit; }
-
-    if (!strcmp (argv[i], "<"))      { type = 4; goto gotit; }
-    if (!strcmp (argv[i], ">"))      { type = 4; goto gotit; }
-    if (!strcmp (argv[i], "=="))     { type = 4; strcpy (argv[i], "E"); goto gotit; }
-    if (!strcmp (argv[i], "!="))     { type = 4; strcpy (argv[i], "N"); goto gotit; }
-    if (!strcmp (argv[i], "<="))     { type = 4; strcpy (argv[i], "L"); goto gotit; }
-    if (!strcmp (argv[i], ">="))     { type = 4; strcpy (argv[i], "G"); goto gotit; }
-    if (!strcmp (argv[i], ">>"))     { type = 4; strcpy (argv[i], "U"); goto gotit; }
-    if (!strcmp (argv[i], "<<"))     { type = 4; strcpy (argv[i], "D"); goto gotit; }
-
-    if (!strcmp (argv[i], "&&"))     { type = 3; strcpy (argv[i], "A"); goto gotit; }
-    if (!strcmp (argv[i], "||"))     { type = 3; strcpy (argv[i], "O"); goto gotit; }
-
-    if (!strcmp (argv[i], "("))      { type = 2; goto gotit; }
-    if (!strcmp (argv[i], ")"))      { type = 1; goto gotit; }
-
-  gotit:
-    /* choose how to deal with object */
-    switch (type) {
-      case 8:  /* 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--) {
-	  strcpy (stack[Nstack].name, op_stack[j].name);
-	  stack[Nstack].type = op_stack[j].type;
-	  Nstack ++;
-	  Nop_stack --;
-	}
-	/* push operator on OP stack */
-	strcpy (op_stack[Nop_stack].name, argv[i]);
-	op_stack[Nop_stack].type = type;
-	Nop_stack ++;
-	break;
-      case 9: /* unary OPs */
-      case 7: /* binary OPs */
-      case 6:
-      case 5: 
-      case 4: 
-      case 3: 
-	/* pop previous, higher or equal operators from OP stack to stack */
-	for (j = Nop_stack - 1; (j >= 0) && (op_stack[j].type >= type); j--) {
-	  strcpy (stack[Nstack].name, op_stack[j].name);
-	  stack[Nstack].type = op_stack[j].type;
-	  Nstack ++;
-	  Nop_stack --;
-	}
-	/* push operator on OP stack */
-	strcpy (op_stack[Nop_stack].name, argv[i]);
-	op_stack[Nop_stack].type = type;
-	Nop_stack ++;
-	break;
-      case 2:  
-	/* push operator on OP stack */
-	strcpy (op_stack[Nop_stack].name, argv[i]);
-	op_stack[Nop_stack].type = type;
-	Nop_stack ++;
-	break;
-      case 1: 
-	/* pop rest of operators from OP stack to stack, looking for '(' */
-	for (j = Nop_stack - 1; (j >= 0) && (op_stack[j].type != 2); j--) {
-	  strcpy (stack[Nstack].name, op_stack[j].name);
-	  stack[Nstack].type = op_stack[j].type;
-	  Nstack ++;
-	  Nop_stack --;
-	}
-	if ((j == -1) || (op_stack[j].type != 2)) {
-	  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 */
-	strcpy (stack[Nstack].name, argv[i]);
-	stack[Nstack].type = 'X';
-	Nstack ++;
-	break;
-    }
-  }
-
-  /* dump remaining operators on stack, checking for ')' */
-  for (j = Nop_stack - 1; j >= 0; j--) {
-    if (op_stack[j].type == 2) {
-      push_error ("syntax error: mismatched parenthesis");
-      Nstack = 0;
-      goto cleanup;
-    }
-    strcpy (stack[Nstack].name, op_stack[j].name);
-    stack[Nstack].type = op_stack[j].type;
-    Nstack ++;
-  }
-
-cleanup: 
-  /*** free up unused stack space ***/
-  clean_stack (op_stack, NSTACK);
-  free (op_stack);
-  clean_stack (&stack[Nstack], NSTACK - Nstack);
-  REALLOCATE (stack, dvoStack, 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 line 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/opihi/dvo/detrend.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/detrend.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/dvo/detrend.c	(revision 20936)
@@ -15,5 +15,5 @@
   int Type, mode, CCD;
   int NVALUE;
-  float *value;
+  opihi_flt *value;
   time_t TimeReference;
   int TimeFormat;
@@ -151,6 +151,6 @@
   N = 0;
   NVALUE = 1000;
-  REALLOCATE (vec[0].elements, float, NVALUE);
-  value = vec[0].elements;
+  ResetVector (vec, OPIHI_FLT, NVALUE);
+  value = vec[0].elements.Flt;
 
   GetTimeFormat (&TimeReference, &TimeFormat);
@@ -193,10 +193,10 @@
     if (N >= NVALUE - 1) {
       NVALUE += 1000;
-      REALLOCATE (vec[0].elements, float, NVALUE);
-      value = vec[0].elements;
-    }
-  }
-
-  REALLOCATE (vec[0].elements, float, MAX (1,N));
+      REALLOCATE (vec[0].elements.Flt, opihi_flt, NVALUE);
+      value = vec[0].elements.Flt;
+    }
+  }
+
+  REALLOCATE (vec[0].elements.Flt, opihi_flt, MAX (1,N));
   vec[0].Nelements = N;
 
Index: unk/Ohana/src/opihi/dvo/dvodb.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/dvodb.c	(revision 20935)
+++ 	(revision )
@@ -1,77 +1,0 @@
-
-/* dvo fields and boolean expressions
-   - evaluate the command line:
-     * avextract ra,dec,g,r,i where (uRA < 0.1)
-     1) identify all fields in extraction list
-     2) parse boolean expression
-     3) identify additional fields from expression
-*/
-
-enum {DVO_TABLE_AVERAGE, DVO_TABLE_MEASURE};
-
-// a single db field 
-typedef struct {
-  char *name;
-  int extract;
-  int table;
-  int ID;
-  int magMode;
-  PhotCode *photcode;
-} dvoField;
-
-// db boolean operations
-typedef struct {
-  char   *name;
-  char    type;
-  int     field;
-  float   Float;
-} dvoStack;
-
-dvoField *ParseCmdlineFields (int argc, char **argv, int table, int *last, int *nfields) {
-
-  int i, Nfields, NFIELDS, 
-
-  *nfields = 0;
-  Nfields = 0;
-  NFIELDS = 10;
-  ALLOCATE (fields, dvoField, NFIELDS);
-
-  // examine each argv[i] entry until we reach a where 
-  for (i = 1; (i < argc) && strcasecmp (argv[i], "where"); 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 (!status) {
-	gprint (GP_ERR, "unknown database field %s\n", field);
-	free (field);
-	free (fields);
-	return (NULL);
-      }
-      free (field);
-
-      Nfields ++;
-      CHECK_REALLOCATE (fields, dvoField, NFIELDS, Nfields, 10);
-    }
-  }
-
-  *last = i;
-  *nfields = Nfields;
-  return (fields);
-}
Index: unk/Ohana/src/opihi/dvo/dvofields.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/dvofields.c	(revision 20935)
+++ 	(revision )
@@ -1,129 +1,0 @@
-
-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, "err"))   return (MAG_ERR);
-  if (!strcasecmp (string, "chisq")) return (MAG_CHISQ);
-  return (MAG_NONE);
-}
-
-PhotCode *ParsePhotcodeField (char *field, int *mode, int default) {
-
-  char *tmpstring, *p;
-  PhotCode *code;
-
-  *mode = default;
-
-  p = strchr (field, ':');
-  if (p != NULL) {
-    *mode = GetMagMode (p + 1);
-    if (*mode == MAG_NONE) return (NULL);
-    tmpstring = strncreate (field, p - field);
-  } else {
-    tmpstring = strcreate (field);
-  }
-  code = GetPhotcodebyName (tmpstring);
-  free (tmpstring);
-
-  return (code);
-}
-
-# define ESCAPE(F,M) { \
-  field->ID = (F); \
-  field->magMode = (M); \
-  field->photcode = NULL; \
-  return (TRUE);
-
-int ParseMeasureField (dvoField *field, char *fieldName) {
-
-  PhotCode *code;
-
-  field->table = DVO_TABLE_MEASURE;
-  field->name  = strcreate (fieldName);
-
-  if (!strcasecmp (fieldName, "RA"))       ESCAPE (MEAS_RA,   	  MAG_NONE);
-  if (!strcasecmp (fieldName, "DEC"))      ESCAPE (MEAS_DEC,  	  MAG_NONE);
-  if (!strcasecmp (fieldName, "MAG"))      ESCAPE (MEAS_MAG,  	  MAG_REL);
-  if (!strcasecmp (fieldName, "dMAG"))     ESCAPE (MEAS_dMAG, 	  MAG_ERR);
-  if (!strcasecmp (fieldName, "AIRMASS"))  ESCAPE (MEAS_AIRMASS,  MAG_NONE);
-  if (!strcasecmp (fieldName, "EXPTIME"))  ESCAPE (MEAS_EXPTIME,  MAG_NONE);
-  if (!strcasecmp (fieldName, "PHOTCODE")) ESCAPE (MEAS_PHOTCODE, MAG_NONE);
-  if (!strcasecmp (fieldName, "TIME"))     ESCAPE (MEAS_TIME,     MAG_NONE);
-  if (!strcasecmp (fieldName, "dR"))       ESCAPE (MEAS_dR, 	  MAG_NONE);
-  if (!strcasecmp (fieldName, "dD"))       ESCAPE (MEAS_dD, 	  MAG_NONE);
-  if (!strcasecmp (fieldName, "FWHM"))     ESCAPE (MEAS_FWHM,     MAG_NONE);
-  if (!strcasecmp (fieldName, "DOPHOT"))   ESCAPE (MEAS_DOPHOT,   MAG_NONE);
-  if (!strcasecmp (fieldName, "FLAGS"))    ESCAPE (MEAS_FLAGS,    MAG_NONE);
-  if (!strcasecmp (fieldName, "XCCD"))     ESCAPE (MEAS_XCCD, 	  MAG_NONE);
-  if (!strcasecmp (fieldName, "YCCD"))     ESCAPE (MEAS_YCCD, 	  MAG_NONE);
-  if (!strcasecmp (fieldName, "XMOSAIC"))  ESCAPE (MEAS_XMOSAIC,  MAG_NONE);
-  if (!strcasecmp (fieldName, "YMOSAIC"))  ESCAPE (MEAS_YMOSAIC,  MAG_NONE);
-
-  // for words that don't parse, try a photcode
-
-  // check for code:mode in photcode name 
-  code = ParsePhotcodeField (&mode, MAG_REL);
-  if (code == NULL) return (FALSE);
-
-  if (mode == MAG_ERR) {
-    field->ID = MEAS_dMAG;
-  } else {
-    field->ID = MEAS_MAG;
-  }    
-  
-  field->magMode = mode;
-  field->photcode = code;
-  return (TRUE);
-}
-  
-int ParseAverageField (char *fieldName) {
-
-  PhotCode *code;
-
-  field->table = DVO_TABLE_AVERAGE;
-
-  if (!strcasecmp (fieldName, "RA"))    ESCAPE (AVE_RA,        MAG_NONE);
-  if (!strcasecmp (fieldName, "DEC"))   ESCAPE (AVE_DEC,       MAG_NONE);
-  if (!strcasecmp (fieldName, "dRA"))   ESCAPE (AVE_RA_ERR,    MAG_NONE);
-  if (!strcasecmp (fieldName, "dDEC"))  ESCAPE (AVE_DEC_ERR,   MAG_NONE);
-  if (!strcasecmp (fieldName, "uRA"))   ESCAPE (AVE_U_RA,      MAG_NONE);
-  if (!strcasecmp (fieldName, "uDEC"))  ESCAPE (AVE_U_DEC,     MAG_NONE);
-  if (!strcasecmp (fieldName, "duRA"))  ESCAPE (AVE_U_RA_ERR,  MAG_NONE);
-  if (!strcasecmp (fieldName, "duDEC")) ESCAPE (AVE_U_DEC_ERR, MAG_NONE);
-  if (!strcasecmp (fieldName, "PAR"))   ESCAPE (AVE_PAR,       MAG_NONE);
-  if (!strcasecmp (fieldName, "dPAR"))  ESCAPE (AVE_PAR_ERR,   MAG_NONE);
-  if (!strcasecmp (fieldName, "MAG"))   ESCAPE (AVE_MAG,       MAG_AVE);
-  if (!strcasecmp (fieldName, "dMAG"))  ESCAPE (AVE_dMAG,      MAG_AVE_ERR);
-  if (!strcasecmp (fieldName, "NMEAS")) ESCAPE (AVE_NMEAS,     MAG_NONE);
-  if (!strcasecmp (fieldName, "NMISS")) ESCAPE (AVE_NMISS,     MAG_NONE);
-  if (!strcasecmp (fieldName, "Xp"))    ESCAPE (AVE_Xp,        MAG_NONE);
-  if (!strcasecmp (fieldName, "Xm"))    ESCAPE (AVE_Xm,        MAG_CHISQ);
-  if (!strcasecmp (fieldName, "FLAG"))  ESCAPE (AVE_FLAG,      MAG_NONE);
-  if (!strcasecmp (fieldName, "TYPE"))  ESCAPE (AVE_TYPE,      MAG_NONE);
-  if (!strcasecmp (fieldName, "NPHOT")) ESCAPE (AVE_NPHOT,     MAG_NONE);
-  if (!strcasecmp (fieldName, "NCODE")) ESCAPE (AVE_NCODE,     MAG_NONE);
-  if (!strcasecmp (fieldName, "NCRIT")) ESCAPE (AVE_NCRIT,     MAG_NONE);
-
-  // for words that don't parse, try a photcode
-
-  // check for code:mode in photcode name 
-  code = ParsePhotcodeField (&mode, MAG_AVE);
-  if (code == NULL) return (FALSE);
-
-  // need to distinguish phot, sys errors and scatter
-  if (mode == MAG_ERR) {
-    field->ID = MEAS_dMAG;
-  } else {
-    field->ID = MEAS_MAG;
-  }    
-  
-  field->magMode = mode;
-  field->photcode = code;
-  return (TRUE);
-}
Index: /trunk/Ohana/src/opihi/dvo/fitcolors.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/fitcolors.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/dvo/fitcolors.c	(revision 20936)
@@ -17,6 +17,7 @@
   char name[64], filename[64], plotname[64], label[64];
   double *M1, *M2;
-  float *out, *colorFit, *deltaFit, dColor, C0, C1;
-  float minDelta, maxDelta, minColor, maxColor;
+  float *out;
+  float *colorFit, *deltaFit, dColor, C0, C1;
+  opihi_flt minDelta, maxDelta, minColor, maxColor;
   int kapa, Npx, Npy, NPX, NPY, Nplot, PLOT;
   Graphdata graphdata;
@@ -176,7 +177,10 @@
   /* vectors to save data */
   Npts = 0;
-  NPTS = 1;
+  NPTS = 64;
   if ((xvec = SelectVector ("tmp_x", ANYVECTOR, TRUE)) == NULL) goto escape;
   if ((yvec = SelectVector ("tmp_y", ANYVECTOR, TRUE)) == NULL) goto escape;
+
+  ResetVector (xvec, OPIHI_FLT, NPTS);
+  ResetVector (yvec, OPIHI_FLT, NPTS);
 
   // set up basic windows
@@ -232,11 +236,11 @@
 	      if (M2[i2] < minColor) continue;
 	      if (M2[i2] > maxColor) continue;
-	      yvec[0].elements[Npts] = M1[i1];
-	      xvec[0].elements[Npts] = M2[i2];
+	      yvec[0].elements.Flt[Npts] = M1[i1];
+	      xvec[0].elements.Flt[Npts] = M2[i2];
 	      Npts++;
 	      if (Npts >= NPTS) {
 		NPTS += 2000;
-		REALLOCATE (xvec[0].elements, float, NPTS);
-		REALLOCATE (yvec[0].elements, float, NPTS);
+		REALLOCATE (xvec[0].elements.Flt, opihi_flt, NPTS);
+		REALLOCATE (yvec[0].elements.Flt, opihi_flt, NPTS);
 	      }
 	    }
@@ -305,7 +309,6 @@
 	KapaSetLimits (kapa, &graphdata);
 	KapaBox (kapa, &graphdata);
-	KapaPrepPlot (kapa, Npts, &graphdata);
-	KapaPlotVector (kapa, Npts, xvec[0].elements, "x");
-	KapaPlotVector (kapa, Npts, yvec[0].elements, "y");
+
+	PlotVectorPair (kapa, xvec, yvec, &graphdata);
 
 	for (i = 0; i < 11; i++) {
@@ -314,4 +317,5 @@
 	graphdata.style = 0;
 	graphdata.color = KapaColorByName ("red");
+
 	KapaPrepPlot (kapa, 11, &graphdata);
 	KapaPlotVector (kapa, 11, colorFit, "x");
Index: /trunk/Ohana/src/opihi/dvo/gstar.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/gstar.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/dvo/gstar.c	(revision 20936)
@@ -136,8 +136,8 @@
     N = 0;
     NPTS = 1000;
-    ALLOCATE (vec1[0].elements, float, NPTS);
-    ALLOCATE (vec2[0].elements, float, NPTS);
-    ALLOCATE (vec3[0].elements, float, NPTS);
-    ALLOCATE (vec4[0].elements, float, NPTS);
+    ResetVector (vec1, OPIHI_FLT, NPTS);
+    ResetVector (vec2, OPIHI_FLT, NPTS);
+    ResetVector (vec3, OPIHI_FLT, NPTS);
+    ResetVector (vec4, OPIHI_FLT, NPTS);
   }
 
@@ -250,15 +250,15 @@
 	  
 	  if (SaveVectors) {
-	    vec1[0].elements[N] = Mcat;
-	    vec2[0].elements[N] = TimeValue (catalog.measure[m].t, TimeReference, TimeFormat);
-	    vec3[0].elements[N] = catalog.measure[m].airmass;
-	    vec4[0].elements[N] = catalog.measure[m].photcode;
+	    vec1[0].elements.Flt[N] = Mcat;
+	    vec2[0].elements.Flt[N] = TimeValue (catalog.measure[m].t, TimeReference, TimeFormat);
+	    vec3[0].elements.Flt[N] = catalog.measure[m].airmass;
+	    vec4[0].elements.Flt[N] = catalog.measure[m].photcode;
 	    N ++;
 	    if (N == NPTS - 1) {
 	      NPTS += 2000;
-	      REALLOCATE (vec1[0].elements, float, NPTS);
-	      REALLOCATE (vec2[0].elements, float, NPTS);
-	      REALLOCATE (vec3[0].elements, float, NPTS);
-	      REALLOCATE (vec4[0].elements, float, NPTS);
+	      REALLOCATE (vec1[0].elements.Flt, opihi_flt, NPTS);
+	      REALLOCATE (vec2[0].elements.Flt, opihi_flt, NPTS);
+	      REALLOCATE (vec3[0].elements.Flt, opihi_flt, NPTS);
+	      REALLOCATE (vec4[0].elements.Flt, opihi_flt, NPTS);
 	    }
 	  }
Index: /trunk/Ohana/src/opihi/dvo/images.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/images.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/dvo/images.c	(revision 20936)
@@ -113,6 +113,7 @@
 
   npts = NPTS = 200;
-  ALLOCATE (Xvec.elements, float, NPTS);
-  ALLOCATE (Yvec.elements, float, NPTS);
+  SetVector (&Xvec, OPIHI_FLT, NPTS);
+  SetVector (&Yvec, OPIHI_FLT, NPTS);
+
   ALLOCATE (plist, int, NPTS);
   n = N = 0;
@@ -238,12 +239,12 @@
     status = FALSE;
     for (j = 0; j < Npts; j++) {
-      status |= fRD_to_XY (&Xvec.elements[N+2*j], &Yvec.elements[N+2*j], r[j], d[j], &graphmode.coords);
+      status |= RD_to_XY (&Xvec.elements.Flt[N+2*j], &Yvec.elements.Flt[N+2*j], r[j], d[j], &graphmode.coords);
       if (j > 0) {
-	Xvec.elements[N+2*j - 1] = Xvec.elements[N+2*j];
-	Yvec.elements[N+2*j - 1] = Yvec.elements[N+2*j];
+	Xvec.elements.Flt[N+2*j - 1] = Xvec.elements.Flt[N+2*j];
+	Yvec.elements.Flt[N+2*j - 1] = Yvec.elements.Flt[N+2*j];
       }
     }
-    Xvec.elements[N+2*Npts-1] = Xvec.elements[N];
-    Yvec.elements[N+2*Npts-1] = Yvec.elements[N];
+    Xvec.elements.Flt[N+2*Npts-1] = Xvec.elements.Flt[N];
+    Yvec.elements.Flt[N+2*Npts-1] = Yvec.elements.Flt[N];
     if (!status) continue;
     // if none of the points are on the visible side of the projection, do not plot the image
@@ -251,8 +252,8 @@
     InPic = FALSE;
     for (j = 0; j < 2*Npts; j+=2) {
-      if ((Xvec.elements[N+j] >= graphmode.xmin) && 
-	  (Xvec.elements[N+j] <= graphmode.xmax) && 
-	  (Yvec.elements[N+j] >= graphmode.ymin) && 
-	  (Yvec.elements[N+j] <= graphmode.ymax))
+      if ((Xvec.elements.Flt[N+j] >= graphmode.xmin) && 
+	  (Xvec.elements.Flt[N+j] <= graphmode.xmax) && 
+	  (Yvec.elements.Flt[N+j] >= graphmode.ymin) && 
+	  (Yvec.elements.Flt[N+j] <= graphmode.ymax))
 	InPic = TRUE;
     }
@@ -269,20 +270,20 @@
     if (N + 16 >= NPTS) {  /* need to leave room for 8 point image */
       NPTS += 400;
-      REALLOCATE (Xvec.elements, float, NPTS);
-      REALLOCATE (Yvec.elements, float, NPTS);
+      REALLOCATE (Xvec.elements.Flt, opihi_flt, NPTS);
+      REALLOCATE (Yvec.elements.Flt, opihi_flt, NPTS);
     }
   }
 
   gprint (GP_ERR, "plotting %d images\n", n);
-  Xvec.Nelements = Xvec.Nelements = N;
+  Xvec.Nelements = Yvec.Nelements = N;
   if (N > 0) {
     graphmode.style = 2; /* points */
     graphmode.ptype = 100; /* connect pairs of points */
     graphmode.etype = 0;
-    PlotVectorPair (kapa, N, Xvec.elements, Yvec.elements, &graphmode);
-  }
-
-  free (Xvec.elements);
-  free (Yvec.elements);
+    PlotVectorPair (kapa, &Xvec, &Yvec, &graphmode);
+  }
+
+  free (Xvec.elements.Flt);
+  free (Yvec.elements.Flt);
   free (image);
   return (TRUE);
Index: /trunk/Ohana/src/opihi/dvo/imbox.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/imbox.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/dvo/imbox.c	(revision 20936)
@@ -36,6 +36,6 @@
   
   /* project this image to screen display coords */
-  ALLOCATE (Xvec.elements, float, 8);
-  ALLOCATE (Yvec.elements, float, 8);
+  SetVector (&Xvec, OPIHI_FLT, 8);
+  SetVector (&Yvec, OPIHI_FLT, 8);
 
   while (gfits_fread_header (f, &header)) {
@@ -82,27 +82,27 @@
 	while (r > Rmid) r-= 360.0;
       }
-      status |= fRD_to_XY (&Xvec.elements[2*j], &Yvec.elements[2*j], r, d, &graphmode.coords);
+      status |= RD_to_XY (&Xvec.elements.Flt[2*j], &Yvec.elements.Flt[2*j], r, d, &graphmode.coords);
       if (j > 0) {
-	Xvec.elements[2*j - 1] = Xvec.elements[2*j];
-	Yvec.elements[2*j - 1] = Yvec.elements[2*j];
+	Xvec.elements.Flt[2*j - 1] = Xvec.elements.Flt[2*j];
+	Yvec.elements.Flt[2*j - 1] = Yvec.elements.Flt[2*j];
       }
     }
-    Xvec.elements[7] = Xvec.elements[0];
-    Yvec.elements[7] = Yvec.elements[0];
+    Xvec.elements.Flt[7] = Xvec.elements.Flt[0];
+    Yvec.elements.Flt[7] = Yvec.elements.Flt[0];
     InPic = FALSE;
     for (j = 0; j < 8; j+=2) {
-      if ((Xvec.elements[j] >= graphmode.xmin) && 
-	  (Xvec.elements[j] <= graphmode.xmax) && 
-	  (Yvec.elements[j] >= graphmode.ymin) && 
-	  (Yvec.elements[j] <= graphmode.ymax))
+      if ((Xvec.elements.Flt[j] >= graphmode.xmin) && 
+	  (Xvec.elements.Flt[j] <= graphmode.xmax) && 
+	  (Yvec.elements.Flt[j] >= graphmode.ymin) && 
+	  (Yvec.elements.Flt[j] <= graphmode.ymax))
 	InPic = TRUE;
     }
 
-    Xvec.Nelements = Xvec.Nelements = 8;
+    Xvec.Nelements = Yvec.Nelements = 8;
     if (InPic) {
       graphmode.style = 2; /* points */
       graphmode.ptype = 100; /* connect pairs of points */
       graphmode.etype = 0;
-      PlotVectorPair (kapa, 8, Xvec.elements, Yvec.elements, &graphmode);
+      PlotVectorPair (kapa, &Xvec, &Yvec, &graphmode);
     }
   skip:
@@ -112,6 +112,6 @@
   }
   fclose (f);
-  free (Xvec.elements);
-  free (Yvec.elements);
+  free (Xvec.elements.Flt);
+  free (Yvec.elements.Flt);
   return (TRUE);
 
Index: /trunk/Ohana/src/opihi/dvo/imdata.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/imdata.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/dvo/imdata.c	(revision 20936)
@@ -49,4 +49,5 @@
 
   gprint (GP_ERR, "function is poorly defined; disabled and may be removed\n");
+  gprint (GP_ERR, "this function extracts measure data corresponding to a given image?\n");
   return (FALSE);
 
@@ -124,7 +125,7 @@
   
   /* create output vector */
+  N = 0;
   NPTS = 1000;
-  REALLOCATE (vec[0].elements, float, NPTS);
-  vec[0].Nelements = N = 0;
+  ResetVector (vec, OPIHI_FLT, NPTS);
 
   // prepare to handle interrupt signals
@@ -153,7 +154,7 @@
 	  if ((catalog.measure[i].t < start) || (catalog.measure[i].t > stop)) continue;
 	  n = catalog.measure[i].averef;
-	  vec[0].elements[N] = catalog.average[n].R - catalog.measure[i].dR / 3600.0;
-	  N++;
-	  CHECK_REALLOCATE (vec[0].elements, float, NPTS, N, 1000);
+	  vec[0].elements.Flt[N] = catalog.average[n].R - catalog.measure[i].dR / 3600.0;
+	  N++;
+	  CHECK_REALLOCATE (vec[0].elements.Flt, opihi_flt, NPTS, N, 1000);
 	}
 	break;
@@ -162,7 +163,7 @@
 	  if ((catalog.measure[i].t < start) || (catalog.measure[i].t > stop)) continue;
 	  n = catalog.measure[i].averef;
-	  vec[0].elements[N] = catalog.average[n].D - catalog.measure[i].dD / 3600.0;
-	  N++;
-	  CHECK_REALLOCATE (vec[0].elements, float, NPTS, N, 1000);
+	  vec[0].elements.Flt[N] = catalog.average[n].D - catalog.measure[i].dD / 3600.0;
+	  N++;
+	  CHECK_REALLOCATE (vec[0].elements.Flt, opihi_flt, NPTS, N, 1000);
 	}
 	break;
@@ -170,7 +171,7 @@
 	for (i = 0; i < catalog.Nmeasure; i++) {
 	  if ((catalog.measure[i].t < start) || (catalog.measure[i].t > stop)) continue;
-	  vec[0].elements[N] = catalog.measure[i].M;
-	  N++;
-	  CHECK_REALLOCATE (vec[0].elements, float, NPTS, N, 1000);
+	  vec[0].elements.Flt[N] = catalog.measure[i].M;
+	  N++;
+	  CHECK_REALLOCATE (vec[0].elements.Flt, opihi_flt, NPTS, N, 1000);
 	}
 	break;
@@ -178,7 +179,7 @@
 	for (i = 0; i < catalog.Nmeasure; i++) {
 	  if ((catalog.measure[i].t < start) || (catalog.measure[i].t > stop)) continue;
-	  vec[0].elements[N] = catalog.measure[i].dM;
-	  N++;
-	  CHECK_REALLOCATE (vec[0].elements, float, NPTS, N, 1000);
+	  vec[0].elements.Flt[N] = catalog.measure[i].dM;
+	  N++;
+	  CHECK_REALLOCATE (vec[0].elements.Flt, opihi_flt, NPTS, N, 1000);
 	}
 	break;
@@ -186,7 +187,7 @@
 	for (i = 0; i < catalog.Nmeasure; i++) {
 	  if ((catalog.measure[i].t < start) || (catalog.measure[i].t > stop)) continue;
-	  vec[0].elements[N] = catalog.measure[i].Mcal;
-	  N++;
-	  CHECK_REALLOCATE (vec[0].elements, float, NPTS, N, 1000);
+	  vec[0].elements.Flt[N] = catalog.measure[i].Mcal;
+	  N++;
+	  CHECK_REALLOCATE (vec[0].elements.Flt, opihi_flt, NPTS, N, 1000);
 	}
 	break;
@@ -195,5 +196,5 @@
 	  if ((catalog.measure[i].t < start) || (catalog.measure[i].t > stop)) continue;
 	  n = catalog.measure[i].averef;
-	  // vec[0].elements[N] = catalog.average[n].M;
+	  // vec[0].elements.Flt[N] = catalog.average[n].M;
 	  N++;
 	}
@@ -202,7 +203,7 @@
 	for (i = 0; i < catalog.Nmeasure; i++) {
 	  if ((catalog.measure[i].t < start) || (catalog.measure[i].t > stop)) continue;
-	  vec[0].elements[N] = catalog.measure[i].photcode;
-	  N++;
-	  CHECK_REALLOCATE (vec[0].elements, float, NPTS, N, 1000);
+	  vec[0].elements.Flt[N] = catalog.measure[i].photcode;
+	  N++;
+	  CHECK_REALLOCATE (vec[0].elements.Flt, opihi_flt, NPTS, N, 1000);
 	}
 	break;
@@ -210,7 +211,7 @@
 	for (i = 0; i < catalog.Nmeasure; i++) {
 	  if ((catalog.measure[i].t < start) || (catalog.measure[i].t > stop)) continue;
-	  vec[0].elements[N] = TimeValue (catalog.measure[i].t, TimeReference, TimeFormat);
-	  N++;
-	  CHECK_REALLOCATE (vec[0].elements, float, NPTS, N, 1000);
+	  vec[0].elements.Flt[N] = TimeValue (catalog.measure[i].t, TimeReference, TimeFormat);
+	  N++;
+	  CHECK_REALLOCATE (vec[0].elements.Flt, opihi_flt, NPTS, N, 1000);
 	}
 	break;
@@ -220,5 +221,5 @@
   
   vec[0].Nelements = N;
-  REALLOCATE (vec[0].elements, float, MAX(1,N));
+  REALLOCATE (vec[0].elements.Flt, opihi_flt, MAX(1,N));
   return (TRUE);
 }
Index: /trunk/Ohana/src/opihi/dvo/imdense.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/imdense.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/dvo/imdense.c	(revision 20936)
@@ -30,8 +30,9 @@
   srand48(B);
 
+  N = 0;
   NPTS = 200;
-  ALLOCATE (Xvec.elements, float, NPTS);
-  ALLOCATE (Yvec.elements, float, NPTS);
-  N = 0;
+  SetVector (&Xvec, OPIHI_FLT, NPTS);
+  SetVector (&Yvec, OPIHI_FLT, NPTS);
+
   for (i = 0; i < Nimage; i++) {
     /* choose a position for point within image box */
@@ -45,27 +46,27 @@
     while (r < Rmin) r += 360.0; 
     while (r > Rmax) r -= 360.0; 
-    status |= fRD_to_XY (&Xvec.elements[N], &Yvec.elements[N], r, d, &graphmode.coords);
-    if ((Xvec.elements[N] >= graphmode.xmin) && 
-	(Xvec.elements[N] <= graphmode.xmax) && 
-	(Yvec.elements[N] >= graphmode.ymin) && 
-	(Yvec.elements[N] <= graphmode.ymax) && status) {
+    status |= RD_to_XY (&Xvec.elements.Flt[N], &Yvec.elements.Flt[N], r, d, &graphmode.coords);
+    if ((Xvec.elements.Flt[N] >= graphmode.xmin) && 
+	(Xvec.elements.Flt[N] <= graphmode.xmax) && 
+	(Yvec.elements.Flt[N] >= graphmode.ymin) && 
+	(Yvec.elements.Flt[N] <= graphmode.ymax) && status) {
       N++;
       if (N > NPTS - 1) { 
 	NPTS += 200;
-	REALLOCATE (Xvec.elements, float, NPTS);
-	REALLOCATE (Yvec.elements, float, NPTS);
+	REALLOCATE (Xvec.elements.Flt, opihi_flt, NPTS);
+	REALLOCATE (Yvec.elements.Flt, opihi_flt, NPTS);
       }
     }
   }
 
-  Xvec.Nelements = Xvec.Nelements = N;
+  Xvec.Nelements = Yvec.Nelements = N;
   if (N > 0) {
     graphmode.style = 2; /* points */
     graphmode.etype = 0;
-    PlotVectorPair (kapa, N, Xvec.elements, Yvec.elements, &graphmode);
+    PlotVectorPair (kapa, &Xvec, &Yvec, &graphmode);
   }
 
-  free (Xvec.elements);
-  free (Yvec.elements);
+  free (Xvec.elements.Flt);
+  free (Yvec.elements.Flt);
   free (image);
   return (TRUE);
Index: /trunk/Ohana/src/opihi/dvo/imextract.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/imextract.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/dvo/imextract.c	(revision 20936)
@@ -1,320 +1,233 @@
 # include "dvoshell.h"
 
-// need to upgrade this to support multiple fields and WHERE clauses
-
-enum {ZERO, 
-      RA, 
-      DEC, 
-      Xm, 
-      AIRMASS, 
-      MCAL, 
-      dMCAL, 
-      PHOTCODE, 
-      TIME, 
-      FWHM, 
-      EXPTIME, 
-      NSTAR, 
-      NCAL, 
-      SKY, 
-      FLAG, 
-      NX_PIX, 
-      NY_PIX, 
-      THETA, 
-      SKEW, 
-      SCALE, 
-      DSCALE, 
-      IMAGE_ID,
-      X_LL_CHIP,
-      X_LR_CHIP,
-      X_UL_CHIP,
-      X_UR_CHIP,
-      Y_LL_CHIP,
-      Y_LR_CHIP,
-      Y_UL_CHIP,
-      Y_UR_CHIP,
-      X_LL_FP,
-      X_LR_FP,
-      X_UL_FP,
-      X_UR_FP,
-      Y_LL_FP,
-      Y_LR_FP,
-      Y_UL_FP,
-      Y_UR_FP,
-};
-
 int imextract (int argc, char **argv) {
   
-  int i, j, Nimage, mode, N, PhotcodeSelect;
-  int TimeSelect, *subset, Nsubset, TimeFormat, FlagSelect, FlagValue;
-  double x, y, ra, dec, t, trange;
-  time_t tzero, TimeReference;
+  // int *subset, Nsubset;  -- not sure if we need to use this or not...
+
+  int i, j, n, N, Npts, NPTS, last, next, state, Nfields, Nreturn, Ncstack, Nstack;
+  int Nimage, VERBOSE;
+  char **cstack, name[1024];
+  void *Signal;
+
+  Vector **vec;
+  Image *image;
+  dbStack *stack;
+  dbField *fields;
+  dbValue *values;
   SkyRegionSelection *selection;
 
-  PhotCode *code;
-  Image *image;
-  Vector *vec;
-
-  if (!InitPhotcodes ()) return (FALSE);
+  /* defaults */
+  vec = NULL;
+  image = NULL;
+  stack = NULL;
+  fields = NULL;
+  values = NULL;
+  selection = NULL;
+
+  if ((N = get_argument (argc, argv, "-h"))) goto help;
+  if ((N = get_argument (argc, argv, "--help"))) goto help;
+
+  VERBOSE = FALSE;
+  if ((N = get_argument (argc, argv, "-v"))) {
+    remove_argument (N, &argc, argv);
+    VERBOSE = TRUE;
+  }
+
+  if (!InitPhotcodes ()) goto escape;
 
   // parse skyregion options
   if ((selection = SetRegionSelection (&argc, argv)) == NULL) {
     gprint (GP_ERR, "invalid sky region selection\n");
-    return FALSE;
-  }
-
-  /* check for time-based selection */
-  TimeSelect = FALSE;
-  if ((N = get_argument (argc, argv, "-time"))) {
-    remove_argument (N, &argc, argv);
-    if (!ohana_str_to_time (argv[N], &tzero)) { 
-      gprint (GP_ERR, "syntax error\n");
-      return (FALSE);
-    }
-    remove_argument (N, &argc, argv);
-    if (!ohana_str_to_dtime (argv[N], &trange)) { 
-      gprint (GP_ERR, "syntax error\n");
-      return (FALSE);
-    }
-    remove_argument (N, &argc, argv);
-    TimeSelect = TRUE;
-  }
-
-  /* check for region-based selection */
-  FlagValue = 0;
-  FlagSelect = FALSE;
-  if ((N = get_argument (argc, argv, "-flag"))) {
-    remove_argument (N, &argc, argv);
-    FlagValue = atoi (argv[N]);
-    remove_argument (N, &argc, argv);
-    FlagSelect = TRUE;
-  }
-
-  /* check for photcode-based selection */
-  code = NULL;
-  PhotcodeSelect = FALSE;
-  if ((N = get_argument (argc, argv, "-photcode"))) {
-    PhotcodeSelect = TRUE;
-    remove_argument (N, &argc, argv);
-    if ((code = GetPhotcodebyName (argv[N])) == NULL) {
-      gprint (GP_ERR, "ERROR: photcode %s not found in photcode table\n", argv[N]);
-      return (FALSE);
-    }
-    if ((code[0].type != PHOT_SEC) && (code[0].type != PHOT_DEP)) {
-      gprint (GP_ERR, "photcode must be primary, secondary, or dependent code\n");
-      return (FALSE);
-    }
-    remove_argument (N, &argc, argv);
-  }
-
-  if (argc != 2) {
-    gprint (GP_ERR, "USAGE: imextract (value) [-region] [-time start range] [-photcode photcode]\n");
+    goto escape;
+  }
+
+  // command-line is of the form: imextract field,field, field [where (field op value)...]
+
+  // parse the fields to be extracted and returned
+  fields = dbCmdlineFields (argc, argv, DVO_TABLE_IMAGE, &last, &Nfields);
+  if (fields == NULL) goto escape;
+  if (Nfields == 0) {
+    FreeSkyRegionSelection (selection);
+    dbFreeFields (fields, Nfields);
+    goto help;
+  }
+
+  // examine line for 'where' or 'match to'.  'match to' is forbidden
+  state = dbCmdlineConditions (argc, argv, last, &next);
+  if (state == DVO_DB_CMDLINE_ERROR) goto escape;
+  if (state == DVO_DB_CMDLINE_IS_MATCH) goto escape; // not allowed for mextract
+
+  // parse the remainder of the line as a boolean math expression
+  cstack = isolate_elements (argc-next, &argv[next], &Ncstack);
+  
+  // construct the db Boolean math stack (frees cstack)
+  stack = dbRPN (Ncstack, cstack, &Nstack);
+
+  // add the skyregion limits to the where statement (or create)
+  // XXX we may want to drop this and use just the image_subset function
+  dbAstroRegionLimits (&stack, &Nstack, selection, DVO_TABLE_IMAGE);
+
+  // parse stack elements into fields and scalars as needed
+  Nreturn = Nfields; 
+  if (!dbCheckStack (stack, Nstack, DVO_TABLE_IMAGE, &fields, &Nfields)) goto escape;
+
+  /* create output storage vectors */
+  ALLOCATE (values, dbValue, Nfields);
+  ALLOCATE (vec, Vector *, Nreturn);
+  for (i = 0; i < Nreturn; i++) {
+    if (ISNUM(fields[i].name[0])) {
+      sprintf (name, "v_%s", fields[i].name);
+    } else {
+      sprintf (name, "%s", fields[i].name);
+    }
+    if ((vec[i] = SelectVector (name, ANYVECTOR, TRUE)) == NULL) goto escape;
+    ResetVector (vec[i], fields[i].type, NPTS);
+  }
+
+  Npts = 0;
+  NPTS = 1;
+
+  if ((image = LoadImages (&Nimage)) == NULL) goto escape;
+  BuildChipMatch (image, Nimage);
+  dbExtractImagesInit (); 
+
+  // XXX do I need to use this, or the region portion
+  // image_subset (image, Nimage, &subset, &Nsubset, selection, tzero, trange, TimeSelect);
+
+  // grab data from all selected sky regions
+  Signal = signal (SIGINT, handle_interrupt);
+  interrupt = FALSE;
+  for (j = 0; (j < Nimage) && !interrupt; j++) {
+
+    // reset counters for saved fields, extract fields
+    dbExtractImagesReset (); 
+    for (n = 0; n < Nfields; n++) {
+      values[n] = dbExtractImages (image, Nimage, j, &fields[n]);
+    }
+
+    // test the conditional statement
+    if (!dbBooleanCond (stack, Nstack, values)) continue;
+    for (n = 0; n < Nreturn; n++) {
+      if (vec[n][0].type == OPIHI_FLT) {
+	vec[n][0].elements.Flt[Npts] = values[n].Flt;
+      } else {
+	vec[n][0].elements.Int[Npts] = values[n].Int;
+      }
+    }
+    Npts++;
+    if (Npts >= NPTS) {
+      NPTS += 2000;
+      for (n = 0; n < Nreturn; n++) {
+	if (vec[n][0].type == OPIHI_FLT) {
+	  REALLOCATE (vec[n][0].elements.Flt, opihi_flt, NPTS);
+	} else {
+	  REALLOCATE (vec[n][0].elements.Int, opihi_int, NPTS);
+	}
+      }
+    }
+  }
+  signal (SIGINT, Signal);
+  interrupt = FALSE;
+  for (n = 0; n < Nreturn; n++) {
+    vec[n][0].Nelements = Npts;
+    if (vec[n][0].type == OPIHI_FLT) {
+      REALLOCATE (vec[n][0].elements.Flt, opihi_flt, MAX(1,Npts));
+    } else {
+      REALLOCATE (vec[n][0].elements.Int, opihi_int, MAX(1,Npts));
+    }
+  }
+
+  // free (subset);
+  free (image);
+
+  if (vec) free (vec);
+  if (values) free (values);
+  dbFreeFields (fields, Nfields);
+  dbFreeStack (stack, Nstack);
+  if (stack) free (stack);
+  return (TRUE);
+  
+ escape:
+  if (vec) free (vec);
+  if (values) free (values);
+  dbFreeFields (fields, Nfields);
+  dbFreeStack (stack, Nstack);
+  if (stack) free (stack);
+  return (FALSE);
+
+ help:
+  gprint (GP_ERR, "USAGE: imextract field[,field,field...] where (expression)\n");
+
+  if ((argc > N + 1) && !strcasecmp (argv[N+1], "fields")) {
+    gprint (GP_ERR, " USAGE: imextract field[,field,field...] where (expression)\n");
+    gprint (GP_ERR, "  RA : right ascension of field center (J2000)\n");
+    gprint (GP_ERR, "  DEC : declination of field center\n");
+    gprint (GP_ERR, "  GLON : galactic longitude of field center (J2000)\n");
+    gprint (GP_ERR, "  GLAT : galactic latitude of field center (J2000)\n");
+    gprint (GP_ERR, "  ELON : ecliptic longitude of field center (J2000)\n");
+    gprint (GP_ERR, "  ELAT : ecliptic latitude of field center (J2000)\n");
+
+    gprint (GP_ERR, "  theta : position angle of image\n");
+    gprint (GP_ERR, "  skew : distortion from rectangle\n");
+    gprint (GP_ERR, "  scale : pixel scale\n");
+    gprint (GP_ERR, "  dscale : pixel-scale error (or variation?)\n");
+
+    gprint (GP_ERR, "  time : time of exposure\n");
+    gprint (GP_ERR, "  nstar : number of stars detected in exposure\n");
+    gprint (GP_ERR, "  airmass : mean airmass of exposure\n");
+    gprint (GP_ERR, "  NX : image dimensions\n");
+    gprint (GP_ERR, "  NY : image dimensions\n");
+
+    gprint (GP_ERR, "  apresid : aperture - fit magnitude\n");
+    gprint (GP_ERR, "  dapresid : aperture - fit magnitude scatter\n");
+
+    gprint (GP_ERR, "  Mcal : photometry calibration (mags)\n");
+    gprint (GP_ERR, "  dMcal : photometry calibration error (mags)\n");
+    gprint (GP_ERR, "  Xm : chisq of photometry calibration\n");
+    gprint (GP_ERR, "  photcode : numeric photcode value for image\n");
+    gprint (GP_ERR, "  exptime : exposure duration (seconds)\n");
+    gprint (GP_ERR, "  sidtime : sidereal time of exposure\n");
+
+    gprint (GP_ERR, "  latitude : observatory latitude\n");
+
+    gprint (GP_ERR, "  detlimit : detection limit of exposure\n");
+    gprint (GP_ERR, "  satlimit : saturation limit of exposure\n");
+    gprint (GP_ERR, "  cerror : astrometric scatter\n");
+
+    gprint (GP_ERR, "  FWHM : mean fwhm of exposure\n");
+    gprint (GP_ERR, "  FWHM_MAJ : fwhm of major axis\n");
+    gprint (GP_ERR, "  FWHM_MIN : fwhm of minor axis\n");
+    gprint (GP_ERR, "  trate : tracking rate for TDI images\n");
+
+    gprint (GP_ERR, "  ncal : number of stars used for photometry calibration\n");
+    gprint (GP_ERR, "  sky : mean background flux\n");
+
+    gprint (GP_ERR, "  flag : processing bit flags\n");
+    gprint (GP_ERR, "  ccdnum : identifier for CCD\n");
+
+    gprint (GP_ERR, "  imageID  : unique image identifier\n");
+    gprint (GP_ERR, "  externID : external image identifier\n");
+    gprint (GP_ERR, "  sourceID : external db reference\n");
+
+    gprint (GP_ERR, "  X_LL_CHIP : chip x-pixel coordinate of lower left corner\n");
+    gprint (GP_ERR, "  X_LR_CHIP : chip x-pixel coordinate of lower right corner\n");
+    gprint (GP_ERR, "  X_UL_CHIP : chip x-pixel coordinate of upper left corner\n");
+    gprint (GP_ERR, "  X_UR_CHIP : chip x-pixel coordinate of upper right corner\n");
+    gprint (GP_ERR, "  Y_LL_CHIP : chip y-pixel coordinate of lower left corner\n");
+    gprint (GP_ERR, "  Y_LR_CHIP : chip y-pixel coordinate of lower right corner\n");
+    gprint (GP_ERR, "  Y_UL_CHIP : chip y-pixel coordinate of upper left corner\n");
+    gprint (GP_ERR, "  Y_UR_CHIP : chip y-pixel coordinate of upper right corner\n");
+    gprint (GP_ERR, "  X_LL_FP   : focal-plane x-pixel coordinate of lower left corner\n");
+    gprint (GP_ERR, "  X_LR_FP   : focal-plane x-pixel coordinate of lower right corner\n");
+    gprint (GP_ERR, "  X_UL_FP   : focal-plane x-pixel coordinate of upper left corner\n");
+    gprint (GP_ERR, "  X_UR_FP   : focal-plane x-pixel coordinate of upper right corner\n");
+    gprint (GP_ERR, "  Y_LL_FP   : focal-plane y-pixel coordinate of lower left corner\n");
+    gprint (GP_ERR, "  Y_LR_FP   : focal-plane y-pixel coordinate of lower right corner\n");
+    gprint (GP_ERR, "  Y_UL_FP   : focal-plane y-pixel coordinate of upper left corner\n");
+    gprint (GP_ERR, "  Y_UR_FP   : focal-plane y-pixel coordinate of upper right corner\n");
     return (FALSE);
   }
-  
-  /* identify selection */
-  mode = ZERO;
-  if (!strcasecmp (argv[1], "ra"       )) mode = RA;
-  if (!strcasecmp (argv[1], "dec"      )) mode = DEC;
-  if (!strcasecmp (argv[1], "Xm"       )) mode = Xm;
-  if (!strcasecmp (argv[1], "airmass"  )) mode = AIRMASS;
-  if (!strcasecmp (argv[1], "Mcal"     )) mode = MCAL;
-  if (!strcasecmp (argv[1], "dMcal"    )) mode = dMCAL;
-  if (!strcasecmp (argv[1], "photcode" )) mode = PHOTCODE;
-  if (!strcasecmp (argv[1], "time"     )) mode = TIME;
-  if (!strcasecmp (argv[1], "FWHM"     )) mode = FWHM;
-  if (!strcasecmp (argv[1], "exptime"  )) mode = EXPTIME;
-  if (!strcasecmp (argv[1], "nstar"    )) mode = NSTAR;
-  if (!strcasecmp (argv[1], "ncal"     )) mode = NCAL;
-  if (!strcasecmp (argv[1], "sky"      )) mode = SKY;
-  if (!strcasecmp (argv[1], "flag"     )) mode = FLAG;
-  if (!strcasecmp (argv[1], "NX"       )) mode = NX_PIX;
-  if (!strcasecmp (argv[1], "NY"       )) mode = NY_PIX;
-  if (!strcasecmp (argv[1], "theta"    )) mode = THETA;
-  if (!strcasecmp (argv[1], "skew"     )) mode = SKEW;
-  if (!strcasecmp (argv[1], "scale"    )) mode = SCALE;
-  if (!strcasecmp (argv[1], "dscale"   )) mode = DSCALE;
-  if (!strcasecmp (argv[1], "imageID"  )) mode = IMAGE_ID;
-  if (!strcasecmp (argv[1], "X_LL_CHIP")) mode = X_LL_CHIP;
-  if (!strcasecmp (argv[1], "X_LR_CHIP")) mode = X_LR_CHIP;
-  if (!strcasecmp (argv[1], "X_UL_CHIP")) mode = X_UL_CHIP;
-  if (!strcasecmp (argv[1], "X_UR_CHIP")) mode = X_UR_CHIP;
-  if (!strcasecmp (argv[1], "Y_LL_CHIP")) mode = Y_LL_CHIP;
-  if (!strcasecmp (argv[1], "Y_LR_CHIP")) mode = Y_LR_CHIP;
-  if (!strcasecmp (argv[1], "Y_UL_CHIP")) mode = Y_UL_CHIP;
-  if (!strcasecmp (argv[1], "Y_UR_CHIP")) mode = Y_UR_CHIP;
-  if (!strcasecmp (argv[1], "X_LL_FP"  )) mode = X_LL_FP;
-  if (!strcasecmp (argv[1], "X_LR_FP"  )) mode = X_LR_FP;
-  if (!strcasecmp (argv[1], "X_UL_FP"  )) mode = X_UL_FP;
-  if (!strcasecmp (argv[1], "X_UR_FP"  )) mode = X_UR_FP;
-  if (!strcasecmp (argv[1], "Y_LL_FP"  )) mode = Y_LL_FP;
-  if (!strcasecmp (argv[1], "Y_LR_FP"  )) mode = Y_LR_FP;
-  if (!strcasecmp (argv[1], "Y_UL_FP"  )) mode = Y_UL_FP;
-  if (!strcasecmp (argv[1], "Y_UR_FP"  )) mode = Y_UR_FP;
-  if (mode == ZERO) {
-    gprint (GP_ERR, "value may be one of the following:\n");
-    gprint (GP_ERR, " ra dec airmass Mcal dMcal Xm photcode time fwhm exptime nstar ncal sky flag\n");
-    return (FALSE);
-  }
-  if ((vec = SelectVector (argv[1], ANYVECTOR, TRUE)) == NULL) return (FALSE);
-
-  if ((image = LoadImages (&Nimage)) == NULL) return (FALSE);
-  image_subset (image, Nimage, &subset, &Nsubset, selection, tzero, trange, TimeSelect);
-  if ((mode == RA) || (mode == DEC)) BuildChipMatch (image, Nimage);
-
-  GetTimeFormat (&TimeReference, &TimeFormat);
-
-  /* create storage vector */
-  REALLOCATE (vec[0].elements, float, Nimage);
-  vec[0].Nelements = Nimage;
-  
-  N = 0;
-  /* assign vector values */
-  for (i = 0; i < Nsubset; i++) {
-    j = subset[i];
-    if (PhotcodeSelect) {
-      if (code[0].type == PHOT_DEP) {
-	if (code[0].code != image[j].photcode) continue;
-      } else {
-	if (code[0].code != GetPhotcodeEquivCodebyCode (image[j].photcode)) continue;
-      }
-    }
-    if (FlagSelect && (FlagValue != image[j].code)) continue;
-    switch (mode) {
-      case RA:
-	if (!FindMosaicForImage (image, Nimage, j)) continue;
-	x = 0.5*image[j].NX;
-	y = 0.5*image[j].NY;
-	XY_to_RD (&ra, &dec, x, y, &image[j].coords);
-	vec[0].elements[N] = ra;
-	break;
-      case DEC:
-	if (!FindMosaicForImage (image, Nimage, j)) continue;
-	x = 0.5*image[j].NX;
-	y = 0.5*image[j].NY;
-	XY_to_RD (&ra, &dec, x, y, &image[j].coords);
-	vec[0].elements[N] = dec;
-	break;
-      case Xm:
-	vec[0].elements[N] = pow(10.0, 0.01*image[j].Xm);
-	break;
-      case AIRMASS:
-	vec[0].elements[N] = image[j].secz;
-	break;
-      case MCAL:
-	vec[0].elements[N] = image[j].Mcal;
-	break;
-      case dMCAL:
-	vec[0].elements[N] = image[j].dMcal;
-	break;
-      case PHOTCODE:
-	vec[0].elements[N] = image[j].photcode;
-	break;
-      case TIME:
-	t = image[j].tzero + 0.5*image[j].NY * image[j].trate / 10000;
-	vec[0].elements[N] = TimeValue (t, TimeReference, TimeFormat);
-	break;
-      case FWHM:
-	vec[0].elements[N] = image[j].fwhm_x / 25.0;
-	break;
-      case EXPTIME:
-	vec[0].elements[N] = image[j].exptime;
-	break;
-      case NSTAR:
-	vec[0].elements[N] = image[j].nstar;
-	break;
-      case NCAL:
-	vec[0].elements[N] = image[j].Mxxxx;
-	break;
-      case SKY:
-	vec[0].elements[N] = image[j].Myyyy + 0x8000;
-	break;
-      case FLAG:
-	vec[0].elements[N] = image[j].code;
-	break;
-      case NX_PIX:
-	vec[0].elements[N] = image[j].NX;
-	break;
-      case NY_PIX:
-	vec[0].elements[N] = image[j].NY;
-	break;
-      case IMAGE_ID:
-	vec[0].elements[N] = image[j].imageID;
-	break;
-      case THETA: {
-	double theta1, theta2, s1, s2;
-	s1 = SIGN(image[j].coords.pc1_1);
-	s2 = SIGN(image[j].coords.pc2_2);
-	theta1 = DEG_RAD*atan2 (+s1*image[j].coords.pc1_2, s1*image[j].coords.pc1_1);
-	theta2 = DEG_RAD*atan2 (-s2*image[j].coords.pc2_1, s2*image[j].coords.pc2_2);
-	vec[0].elements[N] = 0.5*(theta1+theta2);
-	break; }
-      case SKEW: {
-	double theta1, theta2, s1, s2;
-	s1 = SIGN(image[j].coords.pc1_1);
-	s2 = SIGN(image[j].coords.pc2_2);
-	theta1 = DEG_RAD*atan2 (+s1*image[j].coords.pc1_2, s1*image[j].coords.pc1_1);
-	theta2 = DEG_RAD*atan2 (-s2*image[j].coords.pc2_1, s2*image[j].coords.pc2_2);
-	vec[0].elements[N] = (theta1-theta2);
-	break; }
-      case SCALE: {
-	double scale1, scale2;
-	scale1 = fabs(image[j].coords.cdelt1);
-	scale2 = fabs(image[j].coords.cdelt2);
-	vec[0].elements[N] = 0.5*(scale1+scale2);
-	break; }
-      case DSCALE: {
-	double scale1, scale2;
-	scale1 = fabs(image[j].coords.cdelt1);
-	scale2 = fabs(image[j].coords.cdelt2);
-	vec[0].elements[N] = (scale1-scale2);
-	break; }
-
-    // reference pixel extractions
-    case X_LL_CHIP:
-    case Y_LL_CHIP:
-    case Y_LR_CHIP:
-    case X_UL_CHIP:
-      vec[0].elements[N] = 0.0;
-      break;
-    case X_LR_CHIP:
-    case X_UR_CHIP:
-      vec[0].elements[N] = image[j].NX;
-      break;
-    case Y_UL_CHIP:
-    case Y_UR_CHIP:
-      vec[0].elements[N] = image[j].NX;
-      break;
-
-    case X_LL_FP:
-    case Y_LL_FP:
-      XY_to_LM (&x, &y, 0.0, 0.0, &image[j].coords);
-      vec[0].elements[N] = (mode == X_LL_FP) ? x : y;
-      break;
-    case X_LR_FP:
-    case Y_LR_FP:
-      XY_to_LM (&x, &y, image[j].NX, 0.0, &image[j].coords);
-      vec[0].elements[N] = (mode == X_LR_FP) ? x : y;
-      break;
-    case X_UL_FP:
-    case Y_UL_FP:
-      XY_to_LM (&x, &y, 0.0, image[j].NY, &image[j].coords);
-      vec[0].elements[N] = (mode == X_UL_FP) ? x : y;
-      break;
-    case X_UR_FP:
-    case Y_UR_FP:
-      XY_to_LM (&x, &y, image[j].NX, image[j].NY, &image[j].coords);
-      vec[0].elements[N] = (mode == X_UR_FP) ? x : y;
-      break;
-    }
-    N++;
-  }
-  
-  vec[0].Nelements = N;
-  REALLOCATE (vec[0].elements, float, N);
-
-  free (subset);
-  free (image);
-  return (TRUE);
-  
+  gprint (GP_ERR, " imextract --help fields : for a complete listing of allowed fields\n");
+  return (FALSE);
 }
   
Index: /trunk/Ohana/src/opihi/dvo/imrough.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/imrough.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/dvo/imrough.c	(revision 20936)
@@ -13,9 +13,11 @@
   char DataBase[256], *Filter;
   double trange;
-  float *Vec;
+  opihi_flt *Vec;
   time_t tzero, tend, TimeReference;
   RegImage *image;
   Vector *vec;
 
+  // XXX this function is only valid for the Elixir db system, not the IPP db system
+  // this function should exit gracefully if the REGISTRATION_DATABASE is missing
   VarConfig ("REGISTRATION_DATABASE", "%s", DataBase);
 
@@ -132,6 +134,6 @@
   N = 0;
   NVEC = 1000;
-  REALLOCATE (vec[0].elements, float, NVEC);
-  Vec = vec[0].elements;
+  ResetVector (vec, OPIHI_FLT, NVEC);
+  Vec = vec[0].elements.Flt;
 
   GetTimeFormat (&TimeReference, &TimeFormat);
@@ -216,10 +218,10 @@
     if (N >= NVEC - 1) {
       NVEC += 1000;
-      REALLOCATE (vec[0].elements, float, NVEC);
-      Vec = vec[0].elements;
-    }
-  }
-
-  REALLOCATE (vec[0].elements, float, MAX (1,N));
+      REALLOCATE (vec[0].elements.Flt, opihi_flt, NVEC);
+      Vec = vec[0].elements.Flt;
+    }
+  }
+
+  REALLOCATE (vec[0].elements.Flt, opihi_flt, MAX (1,N));
   vec[0].Nelements = N;
 
Index: /trunk/Ohana/src/opihi/dvo/imstats.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/imstats.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/dvo/imstats.c	(revision 20936)
@@ -33,19 +33,18 @@
 
   /* assign vector values */
-  Xvec.Nelements = Nimage;
-  Yvec.Nelements = Nimage;
-  ALLOCATE (Xvec.elements, float, Xvec.Nelements);
-  ALLOCATE (Yvec.elements, float, Yvec.Nelements);
+  SetVector (&Xvec, OPIHI_FLT, Nimage);
+  SetVector (&Yvec, OPIHI_FLT, Nimage);
+
   gprint (GP_LOG, "seq  ra (J2000) dec    time (s)   Nstars\n");
   for (i = 0; i < Nimage; i++) {
-    Xvec.elements[i] = image[i].secz;
+    Xvec.elements.Flt[i] = image[i].secz;
     if (Mcal) 
-      Yvec.elements[i] = image[i].Mcal;
+      Yvec.elements.Flt[i] = image[i].Mcal;
     else 
-      Yvec.elements[i] = image[i].dMcal;
+      Yvec.elements.Flt[i] = image[i].dMcal;
     if (!FindMosaicForImage (image, Nimage, i)) continue;
     XY_to_RD (&r, &d, 0.5*image[i].NX, 0.5*image[i].NY, &image[i].coords);
     gprint (GP_ERR, "%d %8.4f %8.4f %10d %6d  %5.3f %6.3f %6.3f\n", 
-	     i, r, d, image[i].tzero, image[i].nstar, Xvec.elements[i], 
+	     i, r, d, image[i].tzero, image[i].nstar, Xvec.elements.Flt[i], 
 	     image[i].Mcal, image[i].dMcal);
   } 
@@ -54,8 +53,8 @@
   graphmode.style = 2;
   graphmode.etype = 0;
-  PlotVectorPair (kapa, Nimage, Xvec.elements, Yvec.elements, &graphmode);
+  PlotVectorPair (kapa, &Xvec, &Yvec, &graphmode);
   
-  free (Xvec.elements);
-  free (Yvec.elements);
+  free (Xvec.elements.Flt);
+  free (Yvec.elements.Flt);
   return (TRUE);
 }
Index: /trunk/Ohana/src/opihi/dvo/lcurve.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/lcurve.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/dvo/lcurve.c	(revision 20936)
@@ -102,10 +102,12 @@
      catalog.average[N1[i]].R = RA[i] */
 
+  N = 0;
   NPTS = 100;
-  ALLOCATE (Xvec.elements, float, NPTS);
-  ALLOCATE (Yvec.elements, float, NPTS);
-  dYvec.elements = NULL;
-  if (ErrorBars) { ALLOCATE (dYvec.elements, float, NPTS); }
-  N = 0;
+  SetVector (&Xvec, OPIHI_FLT, NPTS);
+  SetVector (&Yvec, OPIHI_FLT, NPTS);
+  dYvec.elements.Flt = NULL;
+  if (ErrorBars) {   
+    SetVector (&dYvec, OPIHI_FLT, NPTS);
+  }
 
   GetTimeFormat (&TimeReference, &TimeFormat);
@@ -124,14 +126,14 @@
       m = catalog.average[N1[i]].measureOffset;
       for (j = 0; j < catalog.average[N1[i]].Nmeasure; j++, m++) {
-	if (ErrorBars) dYvec.elements[N] = catalog.measure[m].dM;
-	Xvec.elements[N] = TimeValue (catalog.measure[m].t, TimeReference, TimeFormat);
-	Yvec.elements[N] = PhotCat (&catalog.measure[m]);
+	if (ErrorBars) dYvec.elements.Flt[N] = catalog.measure[m].dM;
+	Xvec.elements.Flt[N] = TimeValue (catalog.measure[m].t, TimeReference, TimeFormat);
+	Yvec.elements.Flt[N] = PhotCat (&catalog.measure[m]);
 	/**** need to use PhotRel optionally here ****/
 	N++; 
 	if (N == NPTS) {
 	  NPTS += 100;
-	  REALLOCATE (Xvec.elements, float, NPTS);
-	  REALLOCATE (Yvec.elements, float, NPTS);
-	  if (ErrorBars) { REALLOCATE (dYvec.elements, float, NPTS); }
+	  REALLOCATE (Xvec.elements.Flt, opihi_flt, NPTS);
+	  REALLOCATE (Yvec.elements.Flt, opihi_flt, NPTS);
+	  if (ErrorBars) { REALLOCATE (dYvec.elements.Flt, opihi_flt, NPTS); }
 	}
       }      
@@ -142,7 +144,7 @@
   
   if (ErrorBars)
-    fsortthree (Xvec.elements, Yvec.elements, dYvec.elements, N);
+    dsortthree (Xvec.elements.Flt, Yvec.elements.Flt, dYvec.elements.Flt, N);
   else
-    fsortpair (Xvec.elements, Yvec.elements, N);
+    dsortpair (Xvec.elements.Flt, Yvec.elements.Flt, N);
 
   /* autoscale the plot */
@@ -154,10 +156,8 @@
     graphmode.etype = 0;  
 
-  KapaPrepPlot (kapa, N, &graphmode);
-  KapaPlotVector (kapa, N, Xvec.elements, "x");
-  KapaPlotVector (kapa, N, Yvec.elements, "y");
   if (ErrorBars) {
-    KapaPlotVector (kapa, N, dYvec.elements, "dym");
-    KapaPlotVector (kapa, N, dYvec.elements, "dyp");
+    PlotVectorPairErrors (kapa, &Xvec, &Yvec, &dYvec, &graphmode);
+  } else {
+    PlotVectorPair (kapa, &Xvec, &Yvec, &graphmode);
   }
 
@@ -175,15 +175,17 @@
 
   if (SaveVectors) {
-    free (xvec[0].elements);
-    free (yvec[0].elements);
-    xvec[0].elements = Xvec.elements;
-    yvec[0].elements = Yvec.elements;
+    xvec->type = OPIHI_FLT;
+    yvec->type = OPIHI_FLT;
+    free (xvec[0].elements.Flt);
+    free (yvec[0].elements.Flt);
+    xvec[0].elements.Flt = Xvec.elements.Flt;
+    yvec[0].elements.Flt = Yvec.elements.Flt;
     xvec[0].Nelements = yvec[0].Nelements = Xvec.Nelements;
   } else {
-    free (Xvec.elements);
-    free (Yvec.elements);
+    free (Xvec.elements.Flt);
+    free (Yvec.elements.Flt);
   }
 
-  if (ErrorBars) free (dYvec.elements);
+  if (ErrorBars) free (dYvec.elements.Flt);
   dvo_catalog_free (&catalog);
 
Index: /trunk/Ohana/src/opihi/dvo/lightcurve.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/lightcurve.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/dvo/lightcurve.c	(revision 20936)
@@ -87,7 +87,7 @@
   N = 0;
   NPTS = 100;
-  REALLOCATE (tvec[0].elements, float, NPTS);
-  REALLOCATE (mvec[0].elements, float, NPTS);
-  REALLOCATE (dmvec[0].elements, float, NPTS);
+  ResetVector (tvec, OPIHI_FLT, NPTS);
+  ResetVector (mvec, OPIHI_FLT, NPTS);
+  ResetVector (dmvec, OPIHI_FLT, NPTS);
   
   GetTimeFormat (&TimeReference, &TimeFormat);
@@ -117,22 +117,22 @@
 	}      
 
-	tvec[0].elements[N] = TimeValue (catalog.measure[m].t, TimeReference, TimeFormat);
-	dmvec[0].elements[N] = catalog.measure[m].dM;
+	tvec[0].elements.Flt[N] = TimeValue (catalog.measure[m].t, TimeReference, TimeFormat);
+	dmvec[0].elements.Flt[N] = catalog.measure[m].dM;
 	if (RELPHOT) {
-	  mvec[0].elements[N] = PhotCat (&catalog.measure[m]);
+	  mvec[0].elements.Flt[N] = PhotCat (&catalog.measure[m]);
 	} else {
-	  mvec[0].elements[N] = PhotRel (&catalog.measure[m], &catalog.average[k], &catalog.secfilt[k*Nsecfilt]);
+	  mvec[0].elements.Flt[N] = PhotRel (&catalog.measure[m], &catalog.average[k], &catalog.secfilt[k*Nsecfilt]);
 	}
 	N++; 
 	if (N == NPTS) {
 	  NPTS += 100;
-	  REALLOCATE (tvec[0].elements, float, NPTS);
-	  REALLOCATE (mvec[0].elements, float, NPTS);
-	  REALLOCATE (dmvec[0].elements, float, NPTS);
+	  REALLOCATE (tvec[0].elements.Flt, opihi_flt, NPTS);
+	  REALLOCATE (mvec[0].elements.Flt, opihi_flt, NPTS);
+	  REALLOCATE (dmvec[0].elements.Flt, opihi_flt, NPTS);
 	}
       }      
     }
   }
-  fsortthree (tvec[0].elements, mvec[0].elements, dmvec[0].elements, N);
+  dsortthree (tvec[0].elements.Flt, mvec[0].elements.Flt, dmvec[0].elements.Flt, N);
   tvec[0].Nelements = mvec[0].Nelements = dmvec[0].Nelements = N;
 
Index: /trunk/Ohana/src/opihi/dvo/mextract.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/mextract.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/dvo/mextract.c	(revision 20936)
@@ -6,10 +6,9 @@
   int Nsecfilt, VERBOSE, loadImages, mosaicMode;
   char **cstack, name[1024];
-  float *values;
+  dbValue *values;
   void *Signal;
 
   Catalog catalog;
   SkyList *skylist;
-  PhotCode *code;
   Vector **vec;
   dbField *fields;
@@ -18,8 +17,10 @@
 
   /* defaults */
+  vec = NULL;
+  stack = NULL;
+  fields = NULL;
+  values = NULL;
   skylist = NULL;
-  code = NULL;
-  fields = NULL;
-  stack = NULL;
+  selection = NULL;
 
   if ((N = get_argument (argc, argv, "-h"))) goto help;
@@ -49,4 +50,10 @@
   fields = dbCmdlineFields (argc, argv, DVO_TABLE_MEASURE, &last, &Nfields);
   if (fields == NULL) return (FALSE);
+  if (Nfields == 0) {
+    FreeSkyRegionSelection (selection);
+    dbFreeFields (fields, Nfields);
+    dvo_catalog_free (&catalog);
+    goto help;
+  }
 
   // examine line for 'where' or 'match to'.  'match to' is forbidden
@@ -88,5 +95,7 @@
 
   /* create storage vector */
-  ALLOCATE (values, float, Nfields);
+  Npts = 0;
+  NPTS = 1000;
+  ALLOCATE (values, dbValue, Nfields);
   ALLOCATE (vec, Vector *, Nreturn);
   for (i = 0; i < Nreturn; i++) {
@@ -97,8 +106,6 @@
     }
     if ((vec[i] = SelectVector (name, ANYVECTOR, TRUE)) == NULL) goto escape;
-  }
-
-  Npts = 0;
-  NPTS = 1;
+    ResetVector (vec[i], fields[i].type, NPTS);
+  }
 
   // grab data from all selected sky regions
@@ -139,5 +146,9 @@
 	if (!dbBooleanCond (stack, Nstack, values)) continue;
 	for (n = 0; n < Nreturn; n++) {
-	  vec[n][0].elements[Npts] = values[n];
+	  if (vec[n][0].type == OPIHI_FLT) {
+	    vec[n][0].elements.Flt[Npts] = values[n].Flt;
+	  } else {
+	    vec[n][0].elements.Int[Npts] = values[n].Int;
+	  }
 	  // fprintf (stderr, "keep : field: %s, value: %f\n", fields[n].name, values[n]);
 	}
@@ -146,5 +157,5 @@
 	  NPTS += 2000;
 	  for (n = 0; n < Nreturn; n++) {
-	    REALLOCATE (vec[n][0].elements, float, NPTS);
+	    REALLOCATE (vec[n][0].elements.Flt, opihi_flt, NPTS);
 	  }
 	}
@@ -161,8 +172,9 @@
 
   for (n = 0; n < Nreturn; n++) {
-    vec[n][0].Nelements = Npts;
-    REALLOCATE (vec[n][0].elements, float, MAX(1,Npts));
-  }
-
+    ResetVector (vec[n], fields[n].type, MAX(1,Npts));
+  }
+
+  if (vec) free (vec);
+  if (values) free (values);
   dbFreeFields (fields, Nfields);
   dbFreeStack (stack, Nstack);
@@ -174,4 +186,6 @@
 
 escape:
+  if (vec) free (vec);
+  free (values);
   dbFreeFields (fields, Nfields);
   dbFreeStack (stack, Nstack);
Index: /trunk/Ohana/src/opihi/dvo/mmextract.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/mmextract.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/dvo/mmextract.c	(revision 20936)
@@ -8,10 +8,9 @@
   int Nsecfilt, VERBOSE, loadImages, mosaicMode;
   char **cstack1, **cstack2, name1[1024], name2[1024];
-  float *values, **table1, **table2;
+  dbValue *values, **table1, **table2;
   void *Signal;
 
   Catalog catalog;
   SkyList *skylist;
-  PhotCode *code;
   Vector **vec;
   dbField *fields;
@@ -21,9 +20,11 @@
 
   /* defaults */
-  skylist = NULL;
-  code = NULL;
-  fields = NULL;
+  vec = NULL;
   stack1 = NULL;
   stack2 = NULL;
+  fields = NULL;
+  values = NULL;
+  skylist = NULL;
+  selection = NULL;
 
   if ((N = get_argument (argc, argv, "-h"))) goto help;
@@ -57,5 +58,11 @@
   // parse the fields to be extracted and returned : last points to end, or first 'where' or 'matched'
   fields = dbCmdlineFields (argc, argv, DVO_TABLE_MEASURE, &last, &Nfields);
-  if (fields == NULL) return (FALSE);
+  if (fields == NULL) goto escape;
+  if (Nfields == 0) {
+    FreeSkyRegionSelection (selection);
+    dbFreeFields (fields, Nfields);
+    dvo_catalog_free (&catalog);
+    goto help;
+  }
 
   // examine line for 'where' and 'match to'.  neither is required, but order is fixed
@@ -139,5 +146,5 @@
 
   /* create storage vector */
-  ALLOCATE (values, float, Nfields);
+  ALLOCATE (values, dbValue, Nfields);
   ALLOCATE (vec, Vector *, Nreturn);
 
@@ -152,4 +159,6 @@
     if ((vec[2*i+0] = SelectVector (name1, ANYVECTOR, TRUE)) == NULL) goto escape;
     if ((vec[2*i+1] = SelectVector (name2, ANYVECTOR, TRUE)) == NULL) goto escape;
+    ResetVector (vec[2*i+0], fields[i].type, fields[i].type);
+    ResetVector (vec[2*i+1], fields[i].type, fields[i].type);
   }
 
@@ -158,10 +167,11 @@
 
   // we save the selected measures for each average to temporary tables 1 and 2
+  // XXX need to deal with the INT / DBL difference here...
   NTABLE = 100;
-  ALLOCATE (table1, float *, Nreturn_base);
-  ALLOCATE (table2, float *, Nreturn_base);
+  ALLOCATE (table1, dbValue *, Nreturn_base);
+  ALLOCATE (table2, dbValue *, Nreturn_base);
   for (i = 0; i < Nreturn_base; i++) {
-    ALLOCATE (table1[i], float, NTABLE);
-    ALLOCATE (table2[i], float, NTABLE);
+    ALLOCATE (table1[i], dbValue, NTABLE);
+    ALLOCATE (table2[i], dbValue, NTABLE);
   }
 
@@ -194,6 +204,6 @@
 	NTABLE = catalog.average[j].Nmeasure;
 	for (n = 0; n < Nreturn_base; n++) {
-	  REALLOCATE (table1[n], float, NTABLE);
-	  REALLOCATE (table2[n], float, NTABLE);
+	  REALLOCATE (table1[n], dbValue, NTABLE);
+	  REALLOCATE (table2[n], dbValue, NTABLE);
 	}
       }
@@ -206,4 +216,5 @@
 	dbExtractMeasuresInitMeas (); // reset counters for saved fields 
 	for (n = 0; n < Nfields; n++) {
+	  // values needs to be a pointer to a type with FLT and INT (with a union, we would save a bit of memory...)
 	  values[n] = dbExtractMeasures (&catalog.average[j], &catalog.secfilt[j*Nsecfilt], &catalog.measure[m], &fields[n]);
 	}
@@ -232,6 +243,11 @@
 	for (n2 = 0; n2 < Nt2; n2++) {
 	  for (n = 0; n < Nreturn_base; n++) {
-	    vec[2*n+0][0].elements[Npts] = table1[n][n1];
-	    vec[2*n+1][0].elements[Npts] = table2[n][n2];
+	    if (vec[2*n+0][0].type == OPIHI_FLT) {
+	      vec[2*n+0][0].elements.Flt[Npts] = table1[n][n1].Flt;
+	      vec[2*n+1][0].elements.Flt[Npts] = table2[n][n2].Flt;
+	    } else {
+	      vec[2*n+0][0].elements.Int[Npts] = table1[n][n1].Int;
+	      vec[2*n+1][0].elements.Int[Npts] = table2[n][n2].Int;
+	    }
 	  }
 	  Npts++;
@@ -239,5 +255,9 @@
 	    NPTS += 2000;
 	    for (n = 0; n < Nreturn; n++) {
-	      REALLOCATE (vec[n][0].elements, float, NPTS);
+	      if (vec[n][0].type == OPIHI_FLT) {
+		REALLOCATE (vec[n][0].elements.Flt, opihi_flt, NPTS);
+	      } else {
+		REALLOCATE (vec[n][0].elements.Int, opihi_int, NPTS);
+	      }
 	    }
 	  }
@@ -255,7 +275,12 @@
   interrupt = FALSE;
 
+  // free excess memory
   for (n = 0; n < Nreturn; n++) {
     vec[n][0].Nelements = Npts;
-    REALLOCATE (vec[n][0].elements, float, MAX(1,Npts));
+    if (vec[n][0].type == OPIHI_FLT) {
+      REALLOCATE (vec[n][0].elements.Flt, opihi_flt, MAX(1,Npts));
+    } else {
+      REALLOCATE (vec[n][0].elements.Int, opihi_int, MAX(1,Npts));
+    }
   }
 
@@ -280,4 +305,6 @@
 
 escape:
+  if (vec) free (vec);
+  if (values) free (values);
   dbFreeFields (fields, Nfields);
   dbFreeStack (stack1, Nstack1);
@@ -292,5 +319,6 @@
 
  help:
-  gprint (GP_ERR, "USAGE: mextract field[,field,field...] where (expression)\n");
+  gprint (GP_ERR, "USAGE: mmextract field[,field,field...] where (expression) match to (expression)\n");
+  gprint (GP_ERR, "  pairs of fields are returned: the first set are restricted by the 'where' expression, the second by the 'match to' expression\n");
 
   if ((argc > N + 1) && !strcasecmp (argv[N+1], "fields")) {
@@ -344,5 +372,5 @@
     return (FALSE);
   }
-  gprint (GP_ERR, " mextract --help fields : for a complete listing of allowed fields\n");
+  gprint (GP_ERR, " mmextract --help fields : for a complete listing of allowed fields\n");
   return (FALSE);
 }
Index: /trunk/Ohana/src/opihi/dvo/paverage.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/paverage.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/dvo/paverage.c	(revision 20936)
@@ -38,12 +38,12 @@
     photcode = GetPhotcodebyName (argv[Narg]);
     if (!photcode) {
-	fprintf (stderr, "unknown photcode %s\n", argv[Narg]);
-	return (FALSE);
+      fprintf (stderr, "unknown photcode %s\n", argv[Narg]);
+      return (FALSE);
     }
     remove_argument (Narg, &argc, argv);
     Nsec = GetPhotcodeNsec (photcode[0].code);
     if (Nsec == -1) {
-	fprintf (stderr, "photcode %s is not an AVERAGE photcode\n", argv[Narg]);
-	return (FALSE);
+      fprintf (stderr, "photcode %s is not an AVERAGE photcode\n", argv[Narg]);
+      return (FALSE);
     }
   }
@@ -138,13 +138,16 @@
 
       if (Npts == NPTS - 1) {
-	  NPTS += 1000;
-	  REALLOCATE (Xvec, float, NPTS);
-	  REALLOCATE (Yvec, float, NPTS);
-	  REALLOCATE (Zvec, float, NPTS);
+	NPTS += 1000;
+	REALLOCATE (Xvec, float, NPTS);
+	REALLOCATE (Yvec, float, NPTS);
+	REALLOCATE (Zvec, float, NPTS);
       }
       if ((Npts > NCHUNK) || (Nloaded >= 25)) {
-	  PlotVectorTriplet (kapa, Npts, Xvec, Yvec, Zvec, &graphmode);
-	  Npts = 0;
-	  Nloaded = 0;
+	KapaPrepPlot (kapa, Npts, &graphmode);
+	KapaPlotVector (kapa, Npts, Xvec, "x");
+	KapaPlotVector (kapa, Npts, Yvec, "y");
+	KapaPlotVector (kapa, Npts, Zvec, "z");
+	Npts = 0;
+	Nloaded = 0;
       }
     }
@@ -152,5 +155,10 @@
     dvo_catalog_free (&catalog);
   }
-  if (Npts > 0) PlotVectorTriplet (kapa, Npts, Xvec, Yvec, Zvec, &graphmode);
+  if (Npts > 0) {
+    KapaPrepPlot (kapa, Npts, &graphmode);
+    KapaPlotVector (kapa, Npts, Xvec, "x");
+    KapaPlotVector (kapa, Npts, Yvec, "y");
+    KapaPlotVector (kapa, Npts, Zvec, "z");
+  }
 
   free (Xvec);
Index: /trunk/Ohana/src/opihi/dvo/pmeasure.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/pmeasure.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/dvo/pmeasure.c	(revision 20936)
@@ -223,13 +223,16 @@
 
 	if (Npts == NPTS - 1) {
-	    NPTS += 1000;
-	    REALLOCATE (Xvec, float, NPTS);
-	    REALLOCATE (Yvec, float, NPTS);
-	    REALLOCATE (Zvec, float, NPTS);
+	  NPTS += 1000;
+	  REALLOCATE (Xvec, float, NPTS);
+	  REALLOCATE (Yvec, float, NPTS);
+	  REALLOCATE (Zvec, float, NPTS);
 	}
 	if ((Npts > NCHUNK) || (Nloaded >= 25)) {
-	    PlotVectorTriplet (kapa, Npts, Xvec, Yvec, Zvec, &graphmode);
-	    Npts = 0;
-	    Nloaded = 0;
+	  KapaPrepPlot (kapa, Npts, &graphmode);
+	  KapaPlotVector (kapa, Npts, Xvec, "x");
+	  KapaPlotVector (kapa, Npts, Yvec, "y");
+	  KapaPlotVector (kapa, Npts, Zvec, "z");
+	  Npts = 0;
+	  Nloaded = 0;
 	}
       }
@@ -238,6 +241,10 @@
     dvo_catalog_free (&catalog);
   }
-  if (Npts > 0) PlotVectorTriplet (kapa, Npts, Xvec, Yvec, Zvec, &graphmode);
-
+  if (Npts > 0) {
+    KapaPrepPlot (kapa, Npts, &graphmode);
+    KapaPlotVector (kapa, Npts, Xvec, "x");
+    KapaPlotVector (kapa, Npts, Yvec, "y");
+    KapaPlotVector (kapa, Npts, Zvec, "z");
+  }
   free (Xvec);
   free (Yvec);
Index: /trunk/Ohana/src/opihi/dvo/procks.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/procks.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/dvo/procks.c	(revision 20936)
@@ -95,7 +95,6 @@
 
   /* data has been loaded, get ready to plot it */
-  Yvec.Nelements = Xvec.Nelements = 3*Nrocks;
-  ALLOCATE (Xvec.elements, float, Xvec.Nelements);
-  ALLOCATE (Yvec.elements, float, Yvec.Nelements);
+  SetVector (&Xvec, OPIHI_FLT, 3*Nrocks);
+  SetVector (&Yvec, OPIHI_FLT, 3*Nrocks);
   
   /* project stars to screen display coords */
@@ -106,5 +105,5 @@
       while (rocks[i].ra[j] < Rmin) rocks[i].ra[j] += 360.0;
       while (rocks[i].ra[j] > Rmax) rocks[i].ra[j] -= 360.0;
-      fRD_to_XY (&Xvec.elements[N], &Yvec.elements[N], rocks[i].ra[j], rocks[i].dec[j], &graphmode.coords);
+      RD_to_XY (&Xvec.elements.Flt[N], &Yvec.elements.Flt[N], rocks[i].ra[j], rocks[i].dec[j], &graphmode.coords);
       N ++;
     }
@@ -114,10 +113,10 @@
   graphmode.style = 2; /* set style to points */
   graphmode.etype = 0; /* no errorbars */
-  PlotVectorPair (kapa, N, Xvec.elements, Yvec.elements, &graphmode);
+  PlotVectorPair (kapa, &Xvec, &Yvec, &graphmode);
 
   /* now plot vectors between two extrema */
   Yvec.Nelements = Xvec.Nelements = 2*Nrocks;
-  REALLOCATE (Xvec.elements, float, Xvec.Nelements);
-  REALLOCATE (Yvec.elements, float, Yvec.Nelements);
+  REALLOCATE (Xvec.elements.Flt, opihi_flt, Xvec.Nelements);
+  REALLOCATE (Yvec.elements.Flt, opihi_flt, Yvec.Nelements);
   
   /* project stars to screen display coords */
@@ -136,7 +135,7 @@
     while (rocks[i].ra[N1] < Rmin) rocks[i].ra[N1] += 360.0;
     while (rocks[i].ra[N1] > Rmax) rocks[i].ra[N1] -= 360.0;
-    fRD_to_XY (&Xvec.elements[N], &Yvec.elements[N], rocks[i].ra[N0], rocks[i].dec[N0], &graphmode.coords);
+    RD_to_XY (&Xvec.elements.Flt[N], &Yvec.elements.Flt[N], rocks[i].ra[N0], rocks[i].dec[N0], &graphmode.coords);
     N ++;
-    fRD_to_XY (&Xvec.elements[N], &Yvec.elements[N], rocks[i].ra[N1], rocks[i].dec[N1], &graphmode.coords);
+    RD_to_XY (&Xvec.elements.Flt[N], &Yvec.elements.Flt[N], rocks[i].ra[N1], rocks[i].dec[N1], &graphmode.coords);
     N ++;
   }
@@ -147,8 +146,8 @@
   graphmode.etype = 0; /* no errorbars */
 
-  PlotVectorPair (kapa, N, Xvec.elements, Yvec.elements, &graphmode);
+  PlotVectorPair (kapa, &Xvec, &Yvec, &graphmode);
 
-  free (Xvec.elements);
-  free (Yvec.elements);
+  free (Xvec.elements.Flt);
+  free (Yvec.elements.Flt);
   return (TRUE);
 
Index: /trunk/Ohana/src/opihi/dvo/showtile.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/showtile.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/dvo/showtile.c	(revision 20936)
@@ -22,6 +22,6 @@
   N = 0;
   NPTS = 200;
-  ALLOCATE (Xvec.elements, float, NPTS);
-  ALLOCATE (Yvec.elements, float, NPTS);
+  SetVector (&Xvec, OPIHI_FLT, NPTS);
+  SetVector (&Yvec, OPIHI_FLT, NPTS);
 
   /* starting position */
@@ -49,8 +49,8 @@
       for (i = 0; i < 4; i++) {
 	fXY_to_RD (&R, &D, dr[i], dd[i], &coords);
-	status |= fRD_to_XY (&Xvec.elements[N+2*i], &Yvec.elements[N+2*i], R, D, &graphmode.coords);
+	status |= RD_to_XY (&Xvec.elements.Flt[N+2*i], &Yvec.elements.Flt[N+2*i], R, D, &graphmode.coords);
 	if (i > 0) {
-	  Xvec.elements[N+2*i - 1] = Xvec.elements[N+2*i];
-	  Yvec.elements[N+2*i - 1] = Yvec.elements[N+2*i];
+	  Xvec.elements.Flt[N+2*i - 1] = Xvec.elements.Flt[N+2*i];
+	  Yvec.elements.Flt[N+2*i - 1] = Yvec.elements.Flt[N+2*i];
 	}
 	if (i == 1) {
@@ -59,14 +59,14 @@
 	}
       }
-      Xvec.elements[N+7] = Xvec.elements[N];
-      Yvec.elements[N+7] = Yvec.elements[N];
+      Xvec.elements.Flt[N+7] = Xvec.elements.Flt[N];
+      Yvec.elements.Flt[N+7] = Yvec.elements.Flt[N];
 
       /* check if any corner is in plotting region */
       InPic = FALSE;
       for (i = 0; i < 8; i+=2) {
-	if ((Xvec.elements[N+i] >= graphmode.xmin) && 
-	    (Xvec.elements[N+i] <= graphmode.xmax) && 
-	    (Yvec.elements[N+i] >= graphmode.ymin) && 
-	    (Yvec.elements[N+i] <= graphmode.ymax))
+	if ((Xvec.elements.Flt[N+i] >= graphmode.xmin) && 
+	    (Xvec.elements.Flt[N+i] <= graphmode.xmax) && 
+	    (Yvec.elements.Flt[N+i] >= graphmode.ymin) && 
+	    (Yvec.elements.Flt[N+i] <= graphmode.ymax))
 	  InPic = TRUE;
       }
@@ -75,20 +75,20 @@
       if (N > NPTS - 1) {  /* this is OK because NPTS is made always a multiple of 8 */
 	NPTS += 200;
-	REALLOCATE (Xvec.elements, float, NPTS);
-	REALLOCATE (Yvec.elements, float, NPTS);
+	REALLOCATE (Xvec.elements.Flt, opihi_flt, NPTS);
+	REALLOCATE (Yvec.elements.Flt, opihi_flt, NPTS);
       }
     }
   }
   
-  Xvec.Nelements = Xvec.Nelements = N;
+  Xvec.Nelements = Yvec.Nelements = N;
   if (N > 0) {
     graphmode.style = 2; /* points */
     graphmode.ptype = 100; /* connect pairs of points */
     graphmode.etype = 0;
-    PlotVectorPair (kapa, N, Xvec.elements, Yvec.elements, &graphmode);
+    PlotVectorPair (kapa, &Xvec, &Yvec, &graphmode);
   }
 
-  free (Xvec.elements);
-  free (Yvec.elements);
+  free (Xvec.elements.Flt);
+  free (Yvec.elements.Flt);
   return (TRUE);
 
Index: /trunk/Ohana/src/opihi/dvo/simage.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/simage.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/dvo/simage.c	(revision 20936)
@@ -92,10 +92,7 @@
 
   /* set up storage buffers */
-  Xvec.Nelements = Nstars;
-  Yvec.Nelements = Nstars;
-  Zvec.Nelements = Nstars;
-  ALLOCATE (Xvec.elements, float, Xvec.Nelements);
-  ALLOCATE (Yvec.elements, float, Yvec.Nelements);
-  ALLOCATE (Zvec.elements, float, Zvec.Nelements);
+  SetVector (&Xvec, OPIHI_FLT, Nstars);
+  SetVector (&Yvec, OPIHI_FLT, Nstars);
+  SetVector (&Zvec, OPIHI_FLT, Nstars);
   ALLOCATE (buffer, char, (BLOCK*BYTES_STAR));
 
@@ -107,7 +104,7 @@
     if (nbytes != BLOCK*BYTES_STAR) {
       gprint (GP_ERR, "failed to read in stars (1)\n");
-      free (Xvec.elements);
-      free (Yvec.elements);
-      free (Zvec.elements);
+      free (Xvec.elements.Flt);
+      free (Yvec.elements.Flt);
+      free (Zvec.elements.Flt);
       free (buffer);
       return (FALSE);
@@ -118,6 +115,6 @@
       dparse (&M,  3, &buffer[j*BYTES_STAR]);
       XY_to_RD (&R, &D, X, Y, &coords);
-      fRD_to_XY (&Xvec.elements[nstars], &Yvec.elements[nstars], R, D, &graphmode.coords);
-      Zvec.elements[nstars] = MIN (1.0, MAX (0.01, (M - zero) / range));
+      RD_to_XY (&Xvec.elements.Flt[nstars], &Yvec.elements.Flt[nstars], R, D, &graphmode.coords);
+      Zvec.elements.Flt[nstars] = MIN (1.0, MAX (0.01, (M - zero) / range));
     }
   }
@@ -126,7 +123,7 @@
   if (nbytes != (Nbytes % (BLOCK*BYTES_STAR))) {
     gprint (GP_ERR, "ERROR: failed to read in stars (2)\n");
-    free (Xvec.elements);
-    free (Yvec.elements);
-    free (Zvec.elements);
+    free (Xvec.elements.Flt);
+    free (Yvec.elements.Flt);
+    free (Zvec.elements.Flt);
     free (buffer);
     return (FALSE);
@@ -137,13 +134,13 @@
     dparse (&M,  3, &buffer[j*BYTES_STAR]);
     XY_to_RD (&R, &D, X, Y, &coords);
-    fRD_to_XY (&Xvec.elements[nstars], &Yvec.elements[nstars], R, D, &graphmode.coords);
-    Zvec.elements[nstars] = MIN (1.0, MAX (0.01, (M - zero) / range));
+    RD_to_XY (&Xvec.elements.Flt[nstars], &Yvec.elements.Flt[nstars], R, D, &graphmode.coords);
+    Zvec.elements.Flt[nstars] = MIN (1.0, MAX (0.01, (M - zero) / range));
   }
   
   if (nstars != Nstars) {
     gprint (GP_ERR, "ERROR: failed to read in all stars (%d of %d)\n", nstars, Nstars);
-    free (Xvec.elements);
-    free (Yvec.elements);
-    free (Zvec.elements);
+    free (Xvec.elements.Flt);
+    free (Yvec.elements.Flt);
+    free (Zvec.elements.Flt);
     free (buffer);
     return (FALSE);
@@ -155,9 +152,9 @@
   Npts = Xvec.Nelements;
 
-  PlotVectorTriplet (kapa, Npts, Xvec.elements, Yvec.elements, Zvec.elements, &graphmode);
+  PlotVectorTriplet (kapa, &Xvec, &Yvec, &Zvec, &graphmode);
 
-  free (Xvec.elements);
-  free (Yvec.elements);
-  free (Zvec.elements);
+  free (Xvec.elements.Flt);
+  free (Yvec.elements.Flt);
+  free (Zvec.elements.Flt);
   free (buffer);
 
Index: /trunk/Ohana/src/opihi/dvo/skycat.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/skycat.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/dvo/skycat.c	(revision 20936)
@@ -53,8 +53,8 @@
   Rmid = 0.5*(Rmin + Rmax);
 
+  Npts = 0;
   NPTS = 200;
-  ALLOCATE (Xvec.elements, float, NPTS);
-  ALLOCATE (Yvec.elements, float, NPTS);
-  Npts = 0;
+  SetVector (&Xvec, OPIHI_FLT, NPTS);
+  SetVector (&Yvec, OPIHI_FLT, NPTS);
    
   regions = skylist[0].regions;
@@ -76,19 +76,19 @@
       RD_to_XYpic (&X[3], &Y[3], regions[i][0].Rmax, regions[i][0].Dmin, &graphmode.coords, Rmin, Rmax, Rmid, &leftside);
 
-      Xvec.elements[Npts] = X[0];
-      Yvec.elements[Npts] = Y[0];
+      Xvec.elements.Flt[Npts] = X[0];
+      Yvec.elements.Flt[Npts] = Y[0];
       for (j = 1; j < 4; j++) {
-	Xvec.elements[Npts + j*2 - 0] = X[j];
-	Yvec.elements[Npts + j*2 - 0] = Y[j];
-	Xvec.elements[Npts + j*2 - 1] = X[j];
-	Yvec.elements[Npts + j*2 - 1] = Y[j];
+	Xvec.elements.Flt[Npts + j*2 - 0] = X[j];
+	Yvec.elements.Flt[Npts + j*2 - 0] = Y[j];
+	Xvec.elements.Flt[Npts + j*2 - 1] = X[j];
+	Yvec.elements.Flt[Npts + j*2 - 1] = Y[j];
       }
-      Xvec.elements[Npts+7] = Xvec.elements[Npts];
-      Yvec.elements[Npts+7] = Yvec.elements[Npts];
+      Xvec.elements.Flt[Npts+7] = Xvec.elements.Flt[Npts];
+      Yvec.elements.Flt[Npts+7] = Yvec.elements.Flt[Npts];
       Npts += 8;
       if (Npts > NPTS - 1) {  /* this is OK because NPTS is made always a multiple of 8 */
 	NPTS += 200;
-	REALLOCATE (Xvec.elements, float, NPTS);
-	REALLOCATE (Yvec.elements, float, NPTS);
+	REALLOCATE (Xvec.elements.Flt, opihi_flt, NPTS);
+	REALLOCATE (Yvec.elements.Flt, opihi_flt, NPTS);
       }
     }
@@ -96,14 +96,14 @@
 
   gprint (GP_ERR, "plotting %d catalogs\n", Npts/8);
-  Xvec.Nelements = Xvec.Nelements = Npts;
+  Xvec.Nelements = Yvec.Nelements = Npts;
   if (Npts > 0) {
     graphmode.style = 2; /* points */
     graphmode.ptype = 100; /* connect pairs of points */
     graphmode.etype = 0;
-    PlotVectorPair (kapa, Npts, Xvec.elements, Yvec.elements, &graphmode);
+    PlotVectorPair (kapa, &Xvec, &Yvec, &graphmode);
   }
 
-  free (Xvec.elements);
-  free (Yvec.elements);
+  free (Xvec.elements.Ptr);
+  free (Yvec.elements.Ptr);
   free (regions);
 
Index: /trunk/Ohana/src/opihi/include/data.h
===================================================================
--- /trunk/Ohana/src/opihi/include/data.h	(revision 20935)
+++ /trunk/Ohana/src/opihi/include/data.h	(revision 20936)
@@ -78,4 +78,6 @@
 void fft1D (float *dataRe, float *dataIm, int N, int Nbit, int forward);
 int fftND (float *dataRe, float *dataIm, int Ndim, int *Nsize, int forward);
+void dfft1D (double *dataRe, double *dataIm, int N, int Nbit, int forward);
+int dfftND (double *dataRe, double *dataIm, int Ndim, int *Nsize, int forward);
 int IsBinary (int N, int *Nbit);
 
@@ -85,43 +87,43 @@
 
 /* in svdcmp.c */
-int svdcmp (float *a, float *w, float *v, int Nx, int Ny);
+int svdcmp (float *a, opihi_flt *w, float *v, int Nx, int Ny);
 
 /* mrqmin.c */
-float mrqcof (float *x, float *y, float *dy, int Npts, 
-	      float *par, int Npar, float **ta, float **tb, 
-	      float (funcs)(float, float *, int, float *));
+opihi_flt mrqcof (opihi_flt *x, opihi_flt *y, opihi_flt *dy, int Npts, 
+	      opihi_flt *par, int Npar, opihi_flt **ta, opihi_flt **tb, 
+	      opihi_flt (funcs)(opihi_flt, opihi_flt *, int, opihi_flt *));
 
-float mrqmin (float *x, float *y, float *dy, int Npts, 
-	      float *par, int Npar, 
-	      float (funcs)(float, float *, int, float *), int VERBOSE);
+opihi_flt mrqmin (opihi_flt *x, opihi_flt *y, opihi_flt *dy, int Npts, 
+	      opihi_flt *par, int Npar, 
+	      opihi_flt (funcs)(opihi_flt, opihi_flt *, int, opihi_flt *), int VERBOSE);
 
-float mrqinit (float *x, float *y, float *dy, int Npts, 
-	       float *par, int Npar, 
-	       float (funcs)(float, float *, int, float *), int VERBOSE);
+opihi_flt mrqinit (opihi_flt *x, opihi_flt *y, opihi_flt *dy, int Npts, 
+	       opihi_flt *par, int Npar, 
+	       opihi_flt (funcs)(opihi_flt, opihi_flt *, int, opihi_flt *), int VERBOSE);
 
-float **mrqcovar (int Npar);
+opihi_flt **mrqcovar (int Npar);
 
 void mrqfree (int Npar);
 
 /* mrq2dmin.c */
-float mrq2dcof (float *x, float *t, float *y, float *dy, int Npts, 
-		float *par, int Npar, float **ta, float **tb, 
-		float (funcs)(float, float, float *, int, float *));
+opihi_flt mrq2dcof (opihi_flt *x, opihi_flt *t, opihi_flt *y, opihi_flt *dy, int Npts, 
+		opihi_flt *par, int Npar, opihi_flt **ta, opihi_flt **tb, 
+		opihi_flt (funcs)(opihi_flt, opihi_flt, opihi_flt *, int, opihi_flt *));
 
-float mrq2dmin (float *x, float *t, float *y, float *dy, int Npts, 
-		float *par, int Npar, 
-		float (funcs)(float, float, float *, int, float *), int VERBOSE);
+opihi_flt mrq2dmin (opihi_flt *x, opihi_flt *t, opihi_flt *y, opihi_flt *dy, int Npts, 
+		opihi_flt *par, int Npar, 
+		opihi_flt (funcs)(opihi_flt, opihi_flt, opihi_flt *, int, opihi_flt *), int VERBOSE);
 
-float mrq2dinit (float *x, float *t, float *y, float *dy, int Npts, 
-		 float *par, int Npar, 
-		 float (funcs)(float, float, float *, int, float *), int VERBOSE);
+opihi_flt mrq2dinit (opihi_flt *x, opihi_flt *t, opihi_flt *y, opihi_flt *dy, int Npts, 
+		 opihi_flt *par, int Npar, 
+		 opihi_flt (funcs)(opihi_flt, opihi_flt, opihi_flt *, int, opihi_flt *), int VERBOSE);
 
-float mrq2dchi (float *x, float *t, float *y, float *dy, int Npts, 
-		float *par, int Npar, 
-		float (funcs)(float, float, float *, int, float *));
+opihi_flt mrq2dchi (opihi_flt *x, opihi_flt *t, opihi_flt *y, opihi_flt *dy, int Npts, 
+		opihi_flt *par, int Npar, 
+		opihi_flt (funcs)(opihi_flt, opihi_flt, opihi_flt *, int, opihi_flt *));
 
-int mrq2dlimits (float *pmin, float *pmax, int Npar);
+int mrq2dlimits (opihi_flt *pmin, opihi_flt *pmax, int Npar);
 
-float **mrq2dcovar (int Npar);
+opihi_flt **mrq2dcovar (int Npar);
 
 void mrq2dfree (int Npar);
@@ -135,5 +137,5 @@
 double get_aperture_stats (Matrix *matrix, int X, int Y, int Npix, int Nborder, double max);
 int set_rough_radii (double Ra, double Ri, double Ro);
-int get_rough_star (float *data, int Nx, int Ny, int x, int y, float *xc, float *yc, float *sx, float *sy, float *sxy, float *zs, float *zp, float *sk);
+int get_rough_star (float *data, int Nx, int Ny, int x, int y, opihi_flt *xc, opihi_flt *yc, opihi_flt *sx, opihi_flt *sy, opihi_flt *sxy, opihi_flt *zs, opihi_flt *zp, opihi_flt *sk);
 
 /* precess.c */
Index: /trunk/Ohana/src/opihi/include/display.h
===================================================================
--- /trunk/Ohana/src/opihi/include/display.h	(revision 20935)
+++ /trunk/Ohana/src/opihi/include/display.h	(revision 20936)
@@ -1,4 +1,5 @@
 # include "external.h"
 # include "kapa.h"
+# include "dvomath.h"
 
 # ifndef DISPLAY_H
@@ -6,6 +7,8 @@
 
 /*** kapa graph functions ***/
-int           PlotVectorPair        PROTO((int kapa, int Npts, float *xValues, float *yValues, Graphdata *graphmode));
-int           PlotVectorTriplet     PROTO((int kapa, int Npts, float *xValues, float *yValues, float *zValues, Graphdata *graphmode));
+int           PlotVectorSingle      PROTO((int kapa, Vector *vec, char *mode));
+int           PlotVectorPair        PROTO((int kapa, Vector *xVec, Vector *yVec, Graphdata *graphmode));
+int           PlotVectorPairErrors  PROTO((int kapa, Vector *xVec, Vector *yVec, Vector *dyValues, Graphdata *graphmode));
+int           PlotVectorTriplet     PROTO((int kapa, Vector *xVec, Vector *yVec, Vector *zValues, Graphdata *graphmode));
 int           GetGraphData          PROTO((Graphdata *data, int *kapa, char *name));
 int           GetGraph              PROTO((Graphdata *data, int *kapa, char *name));
Index: /trunk/Ohana/src/opihi/include/dvomath.h
===================================================================
--- /trunk/Ohana/src/opihi/include/dvomath.h	(revision 20935)
+++ /trunk/Ohana/src/opihi/include/dvomath.h	(revision 20936)
@@ -4,8 +4,27 @@
 # define DVOMATH_H
 
+# define OPIHI_NAME_SIZE 1024
+
 # define NCHARS 256
+# 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)
+
+# define REQUIRE_VECTOR_FLT(VECT,RVAL) { \
+  if (VECT->type != OPIHI_FLT) { \
+    gprint (GP_ERR, "function requires vector of type FLT\n"); \
+    return (RVAL); \
+  } }
+
+# define REQUIRE_VECTOR_INT(VECT,RVAL) {	\
+  if (VECT->type != OPIHI_INT) { \
+    gprint (GP_ERR, "function requires vector of type INT\n"); \
+    return (RVAL); \
+  } }
 
 enum {ANYVECTOR, NEWVECTOR, OLDVECTOR};
 enum {ANYBUFFER, NEWBUFFER, OLDBUFFER};
+enum {OPIHI_FLT, OPIHI_INT};
 
 typedef struct {			/* representation of a variable (0-D) */
@@ -15,12 +34,17 @@
 
 typedef struct {			/* representation of a vector (1-D) */
-  char name[1024];
-  float *elements;
+  char name[OPIHI_NAME_SIZE];
+  char type;
+  union {
+    void      *Ptr;
+    opihi_flt *Flt;
+    opihi_int *Int;
+  } elements;
   int Nelements;
 } Vector;
 
 typedef struct {			/* representation of buffer (image) */
-  char name[1024];
-  char file[1024];
+  char name[OPIHI_NAME_SIZE];
+  char file[OPIHI_NAME_SIZE];
   Header header;
   Matrix matrix;
@@ -32,8 +56,8 @@
   char   *name;
   char    type;
-  float  *ptr;
   Buffer *buffer;
   Vector *vector;
-  float   Float;
+  opihi_flt FltValue;
+  opihi_int IntValue;
 } StackVar;
 
@@ -87,4 +111,8 @@
 void          InitVectors           PROTO((void));
 int           CopyVector            PROTO((Vector *out, Vector *in));
+int           ResetVector           PROTO((Vector *vec, char type, int Nelements));
+int           SetVector             PROTO((Vector *vec, char type, int Nelements));
+int           CastVector            PROTO((Vector *vec, char type));
+int           MatchVector           PROTO((Vector *out, Vector *in, char type));
 int           MoveVector            PROTO((Vector *out, Vector *in));
 int           DeleteVector          PROTO((Vector *vec));
Index: /trunk/Ohana/src/opihi/include/dvoshell.h
===================================================================
--- /trunk/Ohana/src/opihi/include/dvoshell.h	(revision 20935)
+++ /trunk/Ohana/src/opihi/include/dvoshell.h	(revision 20936)
@@ -5,4 +5,21 @@
 # ifndef DVOSHELL_H
 # define DVOSHELL_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 */
@@ -74,4 +91,6 @@
       MEAS_XCCD, 
       MEAS_YCCD, 
+      MEAS_XCCD_ERR, 
+      MEAS_YCCD_ERR, 
       MEAS_XMOSAIC, 
       MEAS_YMOSAIC, 
@@ -115,8 +134,67 @@
       AVE_TYPE, 
       AVE_TYPEFRAC,
-      AVE_OBJID
+      AVE_OBJID,
+      AVE_CATID
 };
 
-enum {DVO_TABLE_AVERAGE, DVO_TABLE_MEASURE};
+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_EXPTIME, 
+      IMAGE_NSTAR, 
+      IMAGE_NCAL, 
+      IMAGE_SKY, 
+      IMAGE_FLAG, 
+      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_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,
+};
+
+
+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}; 
 
@@ -136,4 +214,5 @@
   int ID;
   int magMode;
+  char type;
   PhotCode *photcode;
 } dbField;
@@ -144,6 +223,12 @@
   char    type;
   int     field;
-  float   Float;
+  opihi_flt FltValue;
+  opihi_int IntValue;
 } dbStack;
+
+typedef struct {
+  opihi_flt Flt;
+  opihi_int Int;
+} dbValue;
 
 typedef struct {
@@ -225,7 +310,8 @@
 // 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, float *fields));
+int          dbBooleanCond          PROTO((dbStack *inStack, int NinStack, dbValue *fields));
 void         dbInitStack            PROTO((dbStack *stack));
 void 	     dbFreeStack            PROTO((dbStack *stack, int Nstack));
@@ -233,6 +319,6 @@
 void         dbFreeTempEntry        PROTO((dbStack *stack));
 
-dbStack     *dbBinary               PROTO((dbStack *V1, dbStack *V2, char *op, float *fields));
-dbStack     *dbUnary                PROTO((dbStack *V1, char *op, float *fields));
+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));
@@ -240,8 +326,9 @@
 int          ParseMeasureField      PROTO((dbField *field, char *fieldName));
 int          ParseAverageField      PROTO((dbField *field, char *fieldName));
-
-double       dbExtractAverages      PROTO((Average *average, SecFilt *secfilt, Measure *measure, dbField *field));
-double       dbExtractMeasures      PROTO((Average *average, SecFilt *secfilt, Measure *measure, dbField *field));
-void         dbExtractMeasuresInit  PROTO(());
+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, int Nimage, int N, dbField *field));
 
 void 	     dbInitField            PROTO((dbField *field));
@@ -257,13 +344,15 @@
 int wordhash (char *word);
 
-int dbExtractAverageInitTransform (CoordTransformSystem target);
-int dbExtractAverageInit ();
-
 int dbExtractMeasuresInitTransform (CoordTransformSystem target);
 int dbExtractMeasuresInitAve ();
 int dbExtractMeasuresInitMeas ();
+int dbExtractMeasuresInit ();
 
 int dbExtractAveragesInitTransform (CoordTransformSystem target);
 int dbExtractAveragesInit ();
 
+int dbExtractImagesInitTransform (CoordTransformSystem target);
+int dbExtractImagesInit ();
+int dbExtractImagesReset ();
+
 # endif
Index: /trunk/Ohana/src/opihi/include/imfit.h
===================================================================
--- /trunk/Ohana/src/opihi/include/imfit.h	(revision 20935)
+++ /trunk/Ohana/src/opihi/include/imfit.h	(revision 20936)
@@ -3,9 +3,9 @@
 int Npar;
 int Nfpar;
-float *par;
-float *fpar;
-float *sky;
+opihi_flt *par;
+opihi_flt *fpar;
+opihi_flt *sky;
 
-float (*fitfunc)(float, float, float *, int, float *);
+opihi_flt (*fitfunc)(opihi_flt, opihi_flt, opihi_flt *, int, opihi_flt *);
 void (*imfit_cleanup)();
 
Index: /trunk/Ohana/src/opihi/include/pantasks.h
===================================================================
--- /trunk/Ohana/src/opihi/include/pantasks.h	(revision 20935)
+++ /trunk/Ohana/src/opihi/include/pantasks.h	(revision 20936)
@@ -245,4 +245,8 @@
 int PrintControllerOutput ();
 
+int AddHost (char *hostname, int max_threads);
+int DeleteHost (char *hostname);
+
+int FlushControllerOutput ();
 int KillControllerJob (Job *job);
 int CheckControllerStatus ();
Index: /trunk/Ohana/src/opihi/lib.data/PlotVectors.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.data/PlotVectors.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/lib.data/PlotVectors.c	(revision 20936)
@@ -1,20 +1,186 @@
 # include "display.h"
 
-int PlotVectorPair (int kapa, int Npts, float *xValues, float *yValues, Graphdata *graphmode) {
+int PlotVectorSingle (int kapa, Vector *vec, char *mode) {
 
-  KapaPrepPlot (kapa, Npts, graphmode);
-  KapaPlotVector (kapa, Npts, xValues, "x");
-  KapaPlotVector (kapa, Npts, yValues, "y");
+  int i, Npts;
+  float *temp;
+
+  Npts = vec->Nelements;
+  ALLOCATE (temp, float, Npts);
+
+  if (vec->type == OPIHI_FLT) {
+    opihi_flt *value = vec->elements.Flt;
+    for (i = 0; i < Npts; i++) {
+      temp[i] = value[i];
+    }
+  } else {
+    opihi_int *value = vec->elements.Int;
+    for (i = 0; i < Npts; i++) {
+      temp[i] = value[i];
+    }
+  }
+  KapaPlotVector (kapa, Npts, temp, mode);
+
+  free (temp);
 
   return (TRUE);
 }
 
-int PlotVectorTriplet (int kapa, int Npts, float *xValues, float *yValues, float *zValues, Graphdata *graphmode) {
+int PlotVectorPair (int kapa, Vector *xVec, Vector *yVec, Graphdata *graphmode) {
 
-  KapaPrepPlot   (kapa, Npts, graphmode);
-  KapaPlotVector (kapa, Npts, xValues, "x");
-  KapaPlotVector (kapa, Npts, yValues, "y");
-  KapaPlotVector (kapa, Npts, zValues, "z");
+  int i, Npts;
+  float *temp;
+
+  if (xVec->Nelements != yVec->Nelements) return (FALSE);
+  Npts = xVec->Nelements;
+
+  ALLOCATE (temp, float, Npts);
+
+  KapaPrepPlot (kapa, Npts, graphmode);
+
+  if (xVec->type == OPIHI_FLT) {
+    opihi_flt *value = xVec->elements.Flt;
+    for (i = 0; i < Npts; i++) {
+      temp[i] = value[i];
+    }
+  } else {
+    opihi_int *value = xVec->elements.Int;
+    for (i = 0; i < Npts; i++) {
+      temp[i] = value[i];
+    }
+  }
+  KapaPlotVector (kapa, Npts, temp, "x");
+
+  if (yVec->type == OPIHI_FLT) {
+    opihi_flt *value = yVec->elements.Flt;
+    for (i = 0; i < Npts; i++) {
+      temp[i] = value[i];
+    }
+  } else {
+    opihi_int *value = yVec->elements.Int;
+    for (i = 0; i < Npts; i++) {
+      temp[i] = value[i];
+    }
+  }
+  KapaPlotVector (kapa, Npts, temp, "y");
+
+  free (temp);
 
   return (TRUE);
 }
+
+int PlotVectorTriplet (int kapa, Vector *xVec, Vector *yVec, Vector *zVec, Graphdata *graphmode) {
+
+  int i, Npts;
+  float *temp;
+
+  if (xVec->Nelements != yVec->Nelements) return (FALSE);
+  if (xVec->Nelements != zVec->Nelements) return (FALSE);
+  Npts = xVec->Nelements;
+
+  ALLOCATE (temp, float, Npts);
+
+  KapaPrepPlot (kapa, Npts, graphmode);
+
+  if (xVec->type == OPIHI_FLT) {
+    opihi_flt *value = xVec->elements.Flt;
+    for (i = 0; i < Npts; i++) {
+      temp[i] = value[i];
+    }
+  } else {
+    opihi_int *value = xVec->elements.Int;
+    for (i = 0; i < Npts; i++) {
+      temp[i] = value[i];
+    }
+  }
+  KapaPlotVector (kapa, Npts, temp, "x");
+
+  if (yVec->type == OPIHI_FLT) {
+    opihi_flt *value = yVec->elements.Flt;
+    for (i = 0; i < Npts; i++) {
+      temp[i] = value[i];
+    }
+  } else {
+    opihi_int *value = yVec->elements.Int;
+    for (i = 0; i < Npts; i++) {
+      temp[i] = value[i];
+    }
+  }
+  KapaPlotVector (kapa, Npts, temp, "y");
+
+  if (zVec->type == OPIHI_FLT) {
+    opihi_flt *value = zVec->elements.Flt;
+    for (i = 0; i < Npts; i++) {
+      temp[i] = value[i];
+    }
+  } else {
+    opihi_int *value = zVec->elements.Int;
+    for (i = 0; i < Npts; i++) {
+      temp[i] = value[i];
+    }
+  }
+  KapaPlotVector (kapa, Npts, temp, "z");
+
+  free (temp);
+
+  return (TRUE);
+}
+
+int PlotVectorPairErrors (int kapa, Vector *xVec, Vector *yVec, Vector *dyVec, Graphdata *graphmode) {
+
+  int i, Npts;
+  float *temp;
+
+  if (xVec->Nelements != yVec->Nelements) return (FALSE);
+  if (xVec->Nelements != dyVec->Nelements) return (FALSE);
+  Npts = xVec->Nelements;
+
+  ALLOCATE (temp, float, Npts);
+
+  KapaPrepPlot (kapa, Npts, graphmode);
+
+  if (xVec->type == OPIHI_FLT) {
+    opihi_flt *value = xVec->elements.Flt;
+    for (i = 0; i < Npts; i++) {
+      temp[i] = value[i];
+    }
+  } else {
+    opihi_int *value = xVec->elements.Int;
+    for (i = 0; i < Npts; i++) {
+      temp[i] = value[i];
+    }
+  }
+  KapaPlotVector (kapa, Npts, temp, "x");
+
+  if (yVec->type == OPIHI_FLT) {
+    opihi_flt *value = yVec->elements.Flt;
+    for (i = 0; i < Npts; i++) {
+      temp[i] = value[i];
+    }
+  } else {
+    opihi_int *value = yVec->elements.Int;
+    for (i = 0; i < Npts; i++) {
+      temp[i] = value[i];
+    }
+  }
+  KapaPlotVector (kapa, Npts, temp, "y");
+
+  if (dyVec->type == OPIHI_FLT) {
+    opihi_flt *value = dyVec->elements.Flt;
+    for (i = 0; i < Npts; i++) {
+      temp[i] = value[i];
+    }
+  } else {
+    opihi_int *value = dyVec->elements.Int;
+    for (i = 0; i < Npts; i++) {
+      temp[i] = value[i];
+    }
+  }
+  KapaPlotVector (kapa, Npts, temp, "dym");
+  KapaPlotVector (kapa, Npts, temp, "dyp");
+
+  free (temp);
+
+  return (TRUE);
+}
+
Index: /trunk/Ohana/src/opihi/lib.data/fft.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.data/fft.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/lib.data/fft.c	(revision 20936)
@@ -133,4 +133,136 @@
 }
 
+// fft based on code by Douglas L. Jones (see note at EOF). modified for Ohana C style
+void dfft1D (double *x, double *y, int n, int Nbit, int forward) {
+
+  int i,j,k,n1,n2;
+  double c,s,e,a,t1,t2;        
+  double factor;
+         
+  // bit-reverse
+  j = 0; 
+  n2 = n/2;
+  for (i = 1; i < n - 1; i++) {
+    n1 = n2;
+    while ( j >= n1 ) {
+      j -= n1;
+      n1 /= 2;
+    }
+    j += n1;
+               
+    if (i < j) {
+      t1 = x[i];
+      x[i] = x[j];
+      x[j] = t1;
+      t1 = y[i];
+      y[i] = y[j];
+      y[j] = t1;
+    }
+  }
+                                          
+  n1 = 0; /* FFT */
+  n2 = 1;
+                                             
+  if (forward) {
+    factor = +2.0*M_PI;
+  } else {
+    factor = -2.0*M_PI;
+  }
+
+  for (i=0; i < Nbit; i++) {
+    n1 = n2;
+    n2 = n2 + n2;
+    e = factor/n2;
+    a = 0.0;
+                                             
+    for (j=0; j < n1; j++) {
+      c = cos(a);
+      s = sin(a);
+      a = a + e;
+                                            
+      for (k=j; k < n; k=k+n2) {
+	t1 = c*x[k+n1] - s*y[k+n1];
+	t2 = s*x[k+n1] + c*y[k+n1];
+	x[k+n1] = x[k] - t1;
+	y[k+n1] = y[k] - t2;
+	x[k] = x[k] + t1;
+	y[k] = y[k] + t2;
+      }
+    }
+  }
+                                      
+  // re-normalize
+  for (i = 0; i < n; i++) {
+    x[i] /= n;
+    y[i] /= n;
+  }
+
+  return;
+}                          
+
+// This implementation uses the 1-D fft above for each of the vectors in each dimension.
+// This requires 2(Nx*Ny*...) mem copies, but the fft operations are likely to happen in
+// cache.
+int dfftND (double *x, double *y, int Ndim, int *Nsize, int forward) {
+
+  int i, nIndex, minor, major, iDim;
+  int step, Nmajor, Nminor, Nmax, Ntotal;
+  int *Nbit;
+  double *tmpX, *tmpY;
+
+  ALLOCATE (Nbit, int, Ndim);
+
+  // find the longest axis and allocate storage for that length
+  Nmax = 0;
+  Ntotal = 1;
+  for (i = 0; i < Ndim; i++) {
+    Nmax = MAX(Nmax, Nsize[i]);
+    Ntotal *= Nsize[i];
+    if (!IsBinary (Nsize[i], &Nbit[i])) {
+      free (Nbit);
+      return (FALSE);
+    }
+  }
+  ALLOCATE (tmpX, double, Nmax);
+  ALLOCATE (tmpY, double, Nmax);
+  
+  step = 1;
+  Nminor = 1;
+  Nmajor = Ntotal;
+  for (iDim = 0; iDim < Ndim; iDim++) {
+    step *= Nsize[iDim];
+    Nmajor /= Nsize[iDim];
+
+    // we perform the FFT along all other dimensions 
+    for (major = 0; major < Nmajor; major++) {
+      for (minor = 0; minor < Nminor; minor++) {
+	// nIndex = minor + i*Nminor + major*step;
+	// extract the data values to the temp vector
+	nIndex = minor + major*step;
+	for (i = 0; i < Nsize[iDim]; i++) {
+	  tmpX[i] = x[nIndex];
+	  tmpY[i] = y[nIndex];
+	  nIndex += Nminor;
+	}
+
+	dfft1D (tmpX, tmpY, Nsize[iDim], Nbit[iDim], forward);
+
+	// replace the result vectors
+	nIndex = minor + major*step;
+	for (i = 0; i < Nsize[iDim]; i++) {
+	  x[nIndex] = tmpX[i];
+	  y[nIndex] = tmpY[i];
+	  nIndex += Nminor;
+	}
+      }
+    }
+    Nminor *= Nsize[iDim];
+  }
+  free (Nbit);
+  free (tmpX);
+  free (tmpY);
+  return (TRUE);
+}
+
 // check that a number is binary (2^Nbit).  returns int(log_2(N)) in Nbit
 int IsBinary (int N, int *Nbit) {
Index: /trunk/Ohana/src/opihi/lib.data/graphtools.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.data/graphtools.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/lib.data/graphtools.c	(revision 20936)
@@ -1,4 +1,6 @@
 # include "data.h"
 
+// XXX need to select the active vector for the range analysis
+// this function accepts either FLT or INT vectors
 void SetLimits (Vector *xvec, Vector *yvec, Graphdata *graphmode) {
 
@@ -7,9 +9,18 @@
 
   if (xvec != NULL) {
-    maxX = minX = xvec[0].elements[0];
-    for (i = 1; i < xvec[0].Nelements; i++) {
-      if (!finite(xvec[0].elements[i])) continue;
-      maxX = MAX (maxX, xvec[0].elements[i]);
-      minX = MIN (minX, xvec[0].elements[i]);
+    if (xvec->type == OPIHI_FLT) {
+      maxX = minX = xvec[0].elements.Flt[0];
+      for (i = 1; i < xvec[0].Nelements; i++) {
+	if (!finite(xvec[0].elements.Flt[i])) continue;
+	maxX = MAX (maxX, xvec[0].elements.Flt[i]);
+	minX = MIN (minX, xvec[0].elements.Flt[i]);
+      }
+    } else {
+      maxX = minX = xvec[0].elements.Int[0];
+      for (i = 1; i < xvec[0].Nelements; i++) {
+	if (!finite(xvec[0].elements.Int[i])) continue;
+	maxX = MAX (maxX, xvec[0].elements.Int[i]);
+	minX = MIN (minX, xvec[0].elements.Int[i]);
+      }
     }
     range = maxX - minX;
@@ -21,9 +32,18 @@
 
   if (yvec != NULL) {
-    maxY = minY = yvec[0].elements[0];
-    for (i = 1; i < yvec[0].Nelements; i++) {
-      if (!finite(yvec[0].elements[i])) continue;
-      maxY = MAX (maxY, yvec[0].elements[i]);
-      minY = MIN (minY, yvec[0].elements[i]);
+    if (yvec->type == OPIHI_FLT) {
+      maxY = minY = yvec[0].elements.Flt[0];
+      for (i = 1; i < yvec[0].Nelements; i++) {
+	if (!finite(yvec[0].elements.Flt[i])) continue;
+	maxY = MAX (maxY, yvec[0].elements.Flt[i]);
+	minY = MIN (minY, yvec[0].elements.Flt[i]);
+      }
+    } else {
+      maxY = minY = yvec[0].elements.Int[0];
+      for (i = 1; i < yvec[0].Nelements; i++) {
+	if (!finite(yvec[0].elements.Int[i])) continue;
+	maxY = MAX (maxY, yvec[0].elements.Int[i]);
+	minY = MIN (minY, yvec[0].elements.Int[i]);
+      }
     }
     range = maxY - minY;
Index: /trunk/Ohana/src/opihi/lib.data/mrq2dmin.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.data/mrq2dmin.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/lib.data/mrq2dmin.c	(revision 20936)
@@ -9,18 +9,18 @@
 # define VERY_VERBOSE 0
 
-static float **alpha, **talpha;
-static float **beta, **tbeta;
-static float *partry, *dyda;
-static float ochisq, lambda;
-
-static float *parmin = NULL;
-static float *parmax = NULL;
-
-float mrq2dcof (float *x, float *t, float *y, float *dy, int Npts, 
-	      float *par, int Npar, float **ta, float **tb, 
-	      float (funcs)(float, float, float *, int, float *)) {
+static opihi_flt **alpha, **talpha;
+static opihi_flt **beta, **tbeta;
+static opihi_flt *partry, *dyda;
+static opihi_flt ochisq, lambda;
+
+static opihi_flt *parmin = NULL;
+static opihi_flt *parmax = NULL;
+
+opihi_flt mrq2dcof (opihi_flt *x, opihi_flt *t, opihi_flt *y, opihi_flt *dy, int Npts, 
+	      opihi_flt *par, int Npar, opihi_flt **ta, opihi_flt **tb, 
+	      opihi_flt (funcs)(opihi_flt, opihi_flt, opihi_flt *, int, opihi_flt *)) {
 
   int k, j, i;
-  float ydiff, wt, chisq;
+  opihi_flt ydiff, wt, chisq;
 
   for (j = 0; j < Npar; j++) {
@@ -60,10 +60,10 @@
 }
 
-float mrq2dchi (float *x, float *t, float *y, float *dy, int Npts, 
-		float *par, int Npar, 
-		float (funcs)(float, float, float *, int, float *)) {
-
-  int i;
-  float ydiff, chisq;
+opihi_flt mrq2dchi (opihi_flt *x, opihi_flt *t, opihi_flt *y, opihi_flt *dy, int Npts, 
+		opihi_flt *par, int Npar, 
+		opihi_flt (funcs)(opihi_flt, opihi_flt, opihi_flt *, int, opihi_flt *)) {
+
+  int i;
+  opihi_flt ydiff, chisq;
 
   chisq = 0.0;
@@ -75,10 +75,10 @@
 }
 
-float mrq2dmin (float *x, float *t, float *y, float *dy, int Npts, 
-	      float *par, int Npar, 
-	      float (funcs)(float, float, float *, int, float *), int VERBOSE) {
+opihi_flt mrq2dmin (opihi_flt *x, opihi_flt *t, opihi_flt *y, opihi_flt *dy, int Npts, 
+	      opihi_flt *par, int Npar, 
+	      opihi_flt (funcs)(opihi_flt, opihi_flt, opihi_flt *, int, opihi_flt *), int VERBOSE) {
 
   int j, k;
-  float chisq;
+  opihi_flt chisq;
 
   /* set up test matrixes for this run */
@@ -90,5 +90,5 @@
 
   /* keep this test in here? */
-  if (!fgaussjordan (talpha, tbeta, Npar, 1)) {
+  if (!dgaussjordan (talpha, tbeta, Npar, 1)) {
     lambda *= 10.0;
     return (ochisq);
@@ -131,10 +131,10 @@
 }
 
-int mrq2dlimits (float *pmin, float *pmax, int Npar) {
-
-  int i;
-
-  ALLOCATE (parmin, float, Npar);
-  ALLOCATE (parmax, float, Npar);
+int mrq2dlimits (opihi_flt *pmin, opihi_flt *pmax, int Npar) {
+
+  int i;
+
+  ALLOCATE (parmin, opihi_flt, Npar);
+  ALLOCATE (parmax, opihi_flt, Npar);
   for (i = 0; i < Npar; i++) {
     parmin[i] = pmin[i];
@@ -144,21 +144,21 @@
 }
 
-float mrq2dinit (float *x, float *t, float *y, float *dy, int Npts, 
-	      float *par, int Npar, 
-	      float (funcs)(float, float, float *, int, float *), int VERBOSE) {
-
-  int i;
-
-  ALLOCATE (dyda, float, Npar);
-  ALLOCATE (partry, float, Npar);
-  ALLOCATE (alpha, float *, Npar);
-  ALLOCATE (beta, float *, Npar);
-  ALLOCATE (talpha, float *, Npar);
-  ALLOCATE (tbeta, float *, Npar);
+opihi_flt mrq2dinit (opihi_flt *x, opihi_flt *t, opihi_flt *y, opihi_flt *dy, int Npts, 
+	      opihi_flt *par, int Npar, 
+	      opihi_flt (funcs)(opihi_flt, opihi_flt, opihi_flt *, int, opihi_flt *), int VERBOSE) {
+
+  int i;
+
+  ALLOCATE (dyda, opihi_flt, Npar);
+  ALLOCATE (partry, opihi_flt, Npar);
+  ALLOCATE (alpha, opihi_flt *, Npar);
+  ALLOCATE (beta, opihi_flt *, Npar);
+  ALLOCATE (talpha, opihi_flt *, Npar);
+  ALLOCATE (tbeta, opihi_flt *, Npar);
   for (i = 0; i < Npar; i++) {
-    ALLOCATE (alpha[i], float, Npar);
-    ALLOCATE (beta[i], float, Npar);
-    ALLOCATE (talpha[i], float, Npar);
-    ALLOCATE (tbeta[i], float, Npar);
+    ALLOCATE (alpha[i], opihi_flt, Npar);
+    ALLOCATE (beta[i], opihi_flt, Npar);
+    ALLOCATE (talpha[i], opihi_flt, Npar);
+    ALLOCATE (tbeta[i], opihi_flt, Npar);
   }
 
@@ -181,7 +181,7 @@
 
 /* don't invoke this in the middle of a run, only near the end */ 
-float **mrq2dcovar (int Npar) {
-
-  fgaussjordan (alpha, beta, Npar, 1);
+opihi_flt **mrq2dcovar (int Npar) {
+
+  dgaussjordan (alpha, beta, Npar, 1);
   return (alpha);
 
Index: /trunk/Ohana/src/opihi/lib.data/mrqmin.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.data/mrqmin.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/lib.data/mrqmin.c	(revision 20936)
@@ -7,15 +7,15 @@
 */
 
-static float **alpha, **talpha;
-static float **beta, **tbeta;
-static float *partry, *dyda;
-static float ochisq, lambda;
+static opihi_flt **alpha, **talpha;
+static opihi_flt **beta, **tbeta;
+static opihi_flt *partry, *dyda;
+static opihi_flt ochisq, lambda;
 
-float mrqcof (float *x, float *y, float *dy, int Npts, 
-	      float *par, int Npar, float **ta, float **tb, 
-	      float (funcs)(float, float *, int, float *)) {
+opihi_flt mrqcof (opihi_flt *x, opihi_flt *y, opihi_flt *dy, int Npts, 
+	      opihi_flt *par, int Npar, opihi_flt **ta, opihi_flt **tb, 
+	      opihi_flt (funcs)(opihi_flt, opihi_flt *, int, opihi_flt *)) {
 
   int k, j, i;
-  float ydiff, wt, chisq;
+  opihi_flt ydiff, wt, chisq;
 
   for (j = 0; j < Npar; j++) {
@@ -45,11 +45,11 @@
 }
 
-float mrqmin (float *x, float *y, float *dy, int Npts, 
-	      float *par, int Npar, 
-	      float (funcs)(float, float *, int, float *), int VERBOSE) {
+opihi_flt mrqmin (opihi_flt *x, opihi_flt *y, opihi_flt *dy, int Npts, 
+	      opihi_flt *par, int Npar, 
+	      opihi_flt (funcs)(opihi_flt, opihi_flt *, int, opihi_flt *), int VERBOSE) {
 
   int j, k;
-  float chisq;
-  float rho, dX, dL;
+  opihi_flt chisq;
+  opihi_flt rho, dX, dL;
 
   /* set up test matrixes for this run */
@@ -60,5 +60,5 @@
   }
 
-  fgaussjordan (talpha, tbeta, Npar, 1);
+  dgaussjordan (talpha, tbeta, Npar, 1);
 
   for (j = 0; j < Npar; j++) partry[j] = par[j] - tbeta[j][0];
@@ -102,21 +102,21 @@
 }
 
-float mrqinit (float *x, float *y, float *dy, int Npts, 
-	      float *par, int Npar, 
-	      float (funcs)(float, float *, int, float *), int VERBOSE) {
+opihi_flt mrqinit (opihi_flt *x, opihi_flt *y, opihi_flt *dy, int Npts, 
+	      opihi_flt *par, int Npar, 
+	      opihi_flt (funcs)(opihi_flt, opihi_flt *, int, opihi_flt *), int VERBOSE) {
 
   int i;
 
-  ALLOCATE (dyda, float, Npar);
-  ALLOCATE (partry, float, Npar);
-  ALLOCATE (alpha, float *, Npar);
-  ALLOCATE (beta, float *, Npar);
-  ALLOCATE (talpha, float *, Npar);
-  ALLOCATE (tbeta, float *, Npar);
+  ALLOCATE (dyda, opihi_flt, Npar);
+  ALLOCATE (partry, opihi_flt, Npar);
+  ALLOCATE (alpha, opihi_flt *, Npar);
+  ALLOCATE (beta, opihi_flt *, Npar);
+  ALLOCATE (talpha, opihi_flt *, Npar);
+  ALLOCATE (tbeta, opihi_flt *, Npar);
   for (i = 0; i < Npar; i++) {
-    ALLOCATE (alpha[i], float, Npar);
-    ALLOCATE (beta[i], float, Npar);
-    ALLOCATE (talpha[i], float, Npar);
-    ALLOCATE (tbeta[i], float, Npar);
+    ALLOCATE (alpha[i], opihi_flt, Npar);
+    ALLOCATE (beta[i], opihi_flt, Npar);
+    ALLOCATE (talpha[i], opihi_flt, Npar);
+    ALLOCATE (tbeta[i], opihi_flt, Npar);
   }
   
@@ -136,6 +136,6 @@
 
 /* don't invoke this in the middle of a run, only near the end */ 
-float **mrqcovar (int Npar) {
-  fgaussjordan (alpha, beta, Npar, 1);
+opihi_flt **mrqcovar (int Npar) {
+  dgaussjordan (alpha, beta, Npar, 1);
   return (alpha);
 } 
Index: /trunk/Ohana/src/opihi/lib.data/starfuncs.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.data/starfuncs.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/lib.data/starfuncs.c	(revision 20936)
@@ -119,7 +119,7 @@
 /* use a circular aperture */
 int get_rough_star (float *data, int Nx, int Ny, int x, int y,
-		    float *xc, float *yc, 
-		    float *sx, float *sy, float *sxy,
-		    float *zs, float *zp, float *sk) {
+		    opihi_flt *xc, opihi_flt *yc, 
+		    opihi_flt *sx, opihi_flt *sy, opihi_flt *sxy,
+		    opihi_flt *zs, opihi_flt *zp, opihi_flt *sk) {
 
   double Ra2, Ri2, Ro2, rad2;
Index: /trunk/Ohana/src/opihi/lib.data/svdcmp.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.data/svdcmp.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/lib.data/svdcmp.c	(revision 20936)
@@ -12,5 +12,5 @@
 
 /* n == Nx, m == Ny */
-int svdcmp (float *a, float *w, float *v, int Nx, int Ny) {
+int svdcmp (float *a, opihi_flt *w, float *v, int Nx, int Ny) {
 
   int flag, i, its, j, jj, k, l, nm, status;
Index: /trunk/Ohana/src/opihi/lib.shell/VectorOps.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.shell/VectorOps.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/lib.shell/VectorOps.c	(revision 20936)
@@ -1,3 +1,5 @@
 # include "opihi.h"
+
+// NOTE: we refer to elements.Ptr if we do not care about the actual type
 
 static Vector **vectors;
@@ -18,5 +20,7 @@
 
   for (i = 0; i < Nvectors; i++) {
-    free (vectors[i][0].elements);
+    if (vectors[i][0].elements.Int) {
+      free (vectors[i][0].elements.Int);
+    }
     free (vectors[i]);
   }
@@ -28,6 +32,9 @@
 
   ALLOCATE (vec, Vector, 1);
-  ALLOCATE (vec[0].elements, float, 1);
-  bzero (vec[0].name, 1024);
+
+  vec[0].type = OPIHI_FLT;    // is a float unless specified otherwise
+  ALLOCATE (vec[0].elements.Flt, opihi_flt, 1);
+
+  bzero (vec[0].name, OPIHI_NAME_SIZE);
   vec[0].Nelements = 0;
   return (vec);
@@ -56,4 +63,5 @@
 }
 
+// XXX add TYPE to arguments?
 Vector *SelectVector (char *name, int mode, int verbose) {
 
@@ -95,5 +103,5 @@
   if (i == Nvectors) return (FALSE);
 
-  free (vectors[i][0].elements);
+  if (vectors[i][0].elements.Ptr) free (vectors[i][0].elements.Ptr);
   free (vectors[i]);
 
@@ -115,5 +123,5 @@
   if (i == Nvectors) return (FALSE);
 
-  free (vectors[i][0].elements);
+  if (vectors[i][0].elements.Ptr) free (vectors[i][0].elements.Ptr);
   free (vectors[i]);
 
@@ -134,10 +142,95 @@
   return (TRUE);
 }
+
 int CopyVector (Vector *out, Vector *in) {
-  free (out[0].elements);
+  if (out[0].elements.Ptr) free (out[0].elements.Ptr);
   out[0].Nelements = in[0].Nelements;
-  ALLOCATE (out[0].elements, float, out[0].Nelements);
-  memcpy (out[0].elements, in[0].elements, out[0].Nelements*sizeof(float));
-  return (TRUE);
+  if (in[0].elements.Ptr) {
+    if (in[0].type == OPIHI_FLT) {
+      ALLOCATE (out[0].elements.Flt, opihi_flt, out[0].Nelements);
+      memcpy (out[0].elements.Flt, in[0].elements.Flt, out[0].Nelements*sizeof(opihi_flt));
+      out[0].type = OPIHI_FLT;
+    } else {
+      ALLOCATE (out[0].elements.Int, opihi_int, out[0].Nelements);
+      memcpy (out[0].elements.Int, in[0].elements.Int, out[0].Nelements*sizeof(opihi_int));
+      out[0].type = OPIHI_INT;
+    }
+  }
+  return (TRUE);
+}
+
+int MatchVector(Vector *out, Vector *in, char type) {
+  if (out[0].elements.Ptr) free (out[0].elements.Ptr);
+  out[0].Nelements = in[0].Nelements;
+  if (type == OPIHI_FLT) {
+    ALLOCATE (out[0].elements.Flt, opihi_flt, out[0].Nelements);
+    out[0].type = OPIHI_FLT;
+  } else {
+    ALLOCATE (out[0].elements.Int, opihi_int, out[0].Nelements);
+    out[0].type = OPIHI_INT;
+  }
+  return (TRUE);
+}
+
+// ResetVector (vecx, OPIHI_FLT, MAX (Npts, 1));
+int ResetVector (Vector *vec, char type, int Nelements) {
+
+  vec[0].Nelements = Nelements;
+  if (type == OPIHI_FLT) {
+    REALLOCATE (vec[0].elements.Flt, opihi_flt, Nelements);
+    vec[0].type = OPIHI_FLT;
+  } else {
+    REALLOCATE (vec[0].elements.Int, opihi_int, Nelements);
+    vec[0].type = OPIHI_INT;
+  }
+  return TRUE;
+}
+
+// SetVector (vecx, OPIHI_FLT, MAX (Npts, 1));
+int SetVector (Vector *vec, char type, int Nelements) {
+
+  vec[0].Nelements = Nelements;
+  if (type == OPIHI_FLT) {
+    ALLOCATE (vec[0].elements.Flt, opihi_flt, Nelements);
+    vec[0].type = OPIHI_FLT;
+  } else {
+    ALLOCATE (vec[0].elements.Int, opihi_int, Nelements);
+    vec[0].type = OPIHI_INT;
+  }
+  return TRUE;
+}
+
+// recast the vector to the specified type
+int CastVector (Vector *vec, char type) {
+
+  int i;
+
+  // the trivial case
+  if (vec[0].type == type) return TRUE;
+
+  if (type == OPIHI_FLT) {
+    opihi_flt *temp;
+    ALLOCATE (temp, opihi_flt, vec[0].Nelements);
+    opihi_flt *vo = temp;
+    opihi_int *vi = vec[0].elements.Int;
+    for (i = 0; i < vec[0].Nelements; i++, vo++, vi++) {
+      *vo = *vi;
+    }
+    free (vec[0].elements.Int);
+    vec[0].elements.Flt = vo;
+    vec[0].type = OPIHI_FLT;
+  } else {
+    opihi_int *temp;
+    ALLOCATE (temp, opihi_int, vec[0].Nelements);
+    opihi_int *vo = temp;
+    opihi_flt *vi = vec[0].elements.Flt;
+    for (i = 0; i < vec[0].Nelements; i++, vo++, vi++) {
+      *vo = *vi;
+    }
+    free (vec[0].elements.Flt);
+    vec[0].elements.Int = vo;
+    vec[0].type = OPIHI_INT;
+  }
+  return TRUE;
 }
 
@@ -150,10 +243,12 @@
   return (TRUE);
 }
+
 int MoveVector (Vector *out, Vector *in) {
   int i, j;
 
-  free (out[0].elements);
-  out[0].Nelements = in[0].Nelements;
-  out[0].elements =  in[0].elements;
+  if (out[0].elements.Ptr) free (out[0].elements.Ptr);
+  out[0].Nelements    = in[0].Nelements;
+  out[0].elements.Ptr = in[0].elements.Ptr;
+  out[0].type         = in[0].type;
 
   /* delete vector entry from vector list, if it exists */
@@ -184,8 +279,11 @@
   gprint (GP_LOG, "    N       name      size\n");
   for (i = 0; i < Nvectors; i++) {
-    gprint (GP_LOG, "%5d %10s %10d\n",
-	     i, vectors[i][0].name, vectors[i][0].Nelements);
-  }
-  return (TRUE);
-}
-  
+    if (vectors[i][0].type == OPIHI_FLT) {
+      gprint (GP_LOG, "%5d %10s %10d (FLT)\n", i, vectors[i][0].name, vectors[i][0].Nelements);
+    } else {
+      gprint (GP_LOG, "%5d %10s %10d (INT)\n", i, vectors[i][0].name, vectors[i][0].Nelements);
+    }
+  }
+  return (TRUE);
+}
+  
Index: /trunk/Ohana/src/opihi/lib.shell/check_stack.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.shell/check_stack.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/lib.shell/check_stack.c	(revision 20936)
@@ -4,5 +4,5 @@
 
   int i, Nx, Ny, Nv, size;
-  char *c;
+  char *c1, *c2;
 
   Nv = Nx = Ny = -1;
@@ -11,9 +11,14 @@
     if (stack[i].type == 'X') {
 
-      /** if this is a number, put it on the list of scalers and move on **/
-      stack[i].Float = strtod (stack[i].name, &c);
-      if (c == stack[i].name + strlen (stack[i].name)) {
-	stack[i].ptr   = &(stack[i].Float);
-	stack[i].type  = 'S';
+      /** 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  = 's'; // 's' == (int)
+	continue;
+      } 
+      if (c1 == stack[i].name + strlen (stack[i].name)) {
+	stack[i].type  = 'S'; // 'S' == (float)
 	continue;
       } 
@@ -22,5 +27,4 @@
       if (IsBuffer (stack[i].name)) {
 	stack[i].buffer = SelectBuffer (stack[i].name, OLDBUFFER, TRUE);
-	stack[i].ptr    = (float *) stack[i].buffer[0].matrix.buffer;
 	stack[i].type   = 'M';
 	if (Nx == -1) {
@@ -44,5 +48,4 @@
       if (IsVector (stack[i].name)) {
 	stack[i].vector = SelectVector (stack[i].name, OLDVECTOR, FALSE);
-	stack[i].ptr    = (float *) stack[i].vector[0].elements;
 	stack[i].type   = 'V';
 
Index: /trunk/Ohana/src/opihi/lib.shell/dvomath.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.shell/dvomath.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/lib.shell/dvomath.c	(revision 20936)
@@ -76,8 +76,12 @@
     case 0:
       if (Ncstack == 1) {
-	  /* use exact input work */
-	  sprintf (outname, "%s", stack[0].name);
+	/* use exact input word */
+	sprintf (outname, "%s", stack[0].name);
       } else {
-	  sprintf (outname, "%.12g", stack[0].Float);
+	if (stack[0].type == 's') {
+	  sprintf (outname, "%d", stack[0].IntValue);
+	} else {
+	  sprintf (outname, "%.12g", stack[0].FltValue);
+	}
       }
       break;
Index: /trunk/Ohana/src/opihi/lib.shell/evaluate_stack.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.shell/evaluate_stack.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/lib.shell/evaluate_stack.c	(revision 20936)
@@ -21,5 +21,5 @@
 
   if (*Nstack == 1) {
-    if (stack[0].type == 'S') {
+    if ((stack[0].type == 'S') || (stack[0].type == 's')) {
       clear_stack (&tmp_stack);
       return (TRUE);
@@ -140,13 +140,10 @@
 /* copy data to new stack variable */
 void copy_stack (StackVar *stack1, StackVar *stack2) {
-  stack1[0].name   = stack2[0].name  ;
-  stack1[0].type   = stack2[0].type  ;
-  stack1[0].ptr    = stack2[0].ptr   ;
-  stack1[0].buffer = stack2[0].buffer;
-  stack1[0].vector = stack2[0].vector;
-  stack1[0].Float  = stack2[0].Float ;
-  if (!strncasecmp (&stack1[0].type, "S", 1)) {
-    stack1[0].ptr    = &stack1[0].Float;
-  }
+  stack1[0].name     = stack2[0].name  ;
+  stack1[0].type     = stack2[0].type  ;
+  stack1[0].buffer   = stack2[0].buffer;
+  stack1[0].vector   = stack2[0].vector;
+  stack1[0].FltValue = stack2[0].FltValue;
+  stack1[0].IntValue = stack2[0].IntValue;
 }
 
@@ -173,5 +170,5 @@
     if (IsVectorPtr (stack[i].vector) && (stack[i].type == 'v')) {
       if (VERBOSE) gprint (GP_ERR, "free %s (vect) (%lx)\n", stack[i].name, (long) stack[i].vector);
-      free (stack[i].vector[0].elements);
+      free (stack[i].vector[0].elements.Ptr);
       free (stack[i].vector);
       stack[i].vector = NULL;
Index: /trunk/Ohana/src/opihi/lib.shell/expand_vectors.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.shell/expand_vectors.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/lib.shell/expand_vectors.c	(revision 20936)
@@ -126,5 +126,5 @@
 	}
 	if (I < 0) I += vec[0].Nelements;
-	f1 = vec[0].elements[I];
+	f1 = (vec[0].type == OPIHI_FLT) ? vec[0].elements.Flt[I] : vec[0].elements.Int[I];
       }
     }
@@ -132,7 +132,7 @@
     free (tmpline);
     if ((int)f1 == f1) 
-      snprintf (strValue, 128, "%.0f", f1);
+      snprintf (strValue, 128, "%.0f", f1); 
     else
-      snprintf (strValue, 128, "%.9g", f1);
+      snprintf (strValue, 128, "%.12g", f1);
 
     /* interpolate vector element into newline (being accumulated) */
Index: /trunk/Ohana/src/opihi/lib.shell/parse.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.shell/parse.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/lib.shell/parse.c	(revision 20936)
@@ -190,5 +190,9 @@
       }
       if (Nx < 0) Nx += vec[0].Nelements;
-      vec[0].elements[Nx] = atof (val);
+      if (vec[0].type == OPIHI_FLT) {
+	vec[0].elements.Flt[Nx] = atof (val);
+      } else {
+	vec[0].elements.Int[Nx] = atol (val);
+      }
     }
 
Index: /trunk/Ohana/src/opihi/lib.shell/stack_math.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.shell/stack_math.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/lib.shell/stack_math.c	(revision 20936)
@@ -4,377 +4,343 @@
    labeled by "m". if one of the input matrices is already a temp variable, we 
    can continue using it this round 
-   */
+*/
+
+// XXX we temporarily drop the concept of using one of the temporary input vectors for 
+// the output vector (thus saving an ALLOC): we have to juggle the size of the input vectors 
+// as well as their temporary state
 
 int VV_binary (StackVar *OUT, StackVar *V1, StackVar *V2, char *op) {
 
   int i, Nx;
-  float *out, *M1, *M2;
+  char line[512]; // this is only used to report an error 
+  
+  // the vectors have to match in length
+  if (V1[0].vector[0].Nelements != V2[0].vector[0].Nelements) {
+    return (FALSE);
+  }
+
+  Nx = V1[0].vector[0].Nelements;
+
+  // create the output vector guaranteed to be temporary until the very end
+  OUT[0].vector = InitVector ();
+  OUT[0].type = 'v';
+
+  // set up the possible operations : int OP int -> int, all else yield float
+  // OP is the operation performed on *M1 and *M2
+# define VV_FUNC(FTYPE,OP) {						\
+    if ((V1->vector->type == OPIHI_FLT) && (V2->vector->type == OPIHI_FLT)) { \
+      CopyVector (OUT[0].vector, V1[0].vector);				\
+      opihi_flt *M1  =  V1[0].vector[0].elements.Flt;			\
+      opihi_flt *M2  =  V2[0].vector[0].elements.Flt;			\
+      opihi_flt *out = OUT[0].vector[0].elements.Flt;			\
+      for (i = 0; i < Nx; i++, out++, M1++, M2++) {			\
+  	*out = OP;							\
+      }									\
+      break;								\
+    }									\
+    if ((V1->vector->type == OPIHI_FLT) && (V2->vector->type != OPIHI_FLT)) { \
+      CopyVector (OUT[0].vector, V1[0].vector);				\
+      opihi_flt *M1  =  V1[0].vector[0].elements.Flt;			\
+      opihi_int *M2  =  V2[0].vector[0].elements.Int;			\
+      opihi_flt *out = OUT[0].vector[0].elements.Flt;			\
+      for (i = 0; i < Nx; i++, out++, M1++, M2++) {			\
+  	*out = OP;							\
+      }									\
+      break;								\
+    }									\
+    if ((V1->vector->type != OPIHI_FLT) && (V2->vector->type == OPIHI_FLT)) { \
+      CopyVector (OUT[0].vector, V2[0].vector);				\
+      opihi_int *M1  =  V1[0].vector[0].elements.Int;			\
+      opihi_flt *M2  =  V2[0].vector[0].elements.Flt;			\
+      opihi_flt *out = OUT[0].vector[0].elements.Flt;			\
+      for (i = 0; i < Nx; i++, out++, M1++, M2++) {			\
+  	*out = OP;							\
+      }									\
+      break;								\
+    }									\
+    if ((FTYPE == 'S') && (V1->vector->type != OPIHI_FLT) && (V2->vector->type != OPIHI_FLT)) { \
+      MatchVector (OUT[0].vector, V1[0].vector, OPIHI_FLT);		\
+      opihi_int *M1  =  V1[0].vector[0].elements.Int;			\
+      opihi_int *M2  =  V2[0].vector[0].elements.Int;			\
+      opihi_flt *out = OUT[0].vector[0].elements.Flt;			\
+      for (i = 0; i < Nx; i++, out++, M1++, M2++) {			\
+	*out = OP;							\
+      }									\
+      break;								\
+    }									\
+    if ((V1->vector->type != OPIHI_FLT) && (V2->vector->type != OPIHI_FLT)) { \
+      CopyVector (OUT[0].vector, V1[0].vector);				\
+      opihi_int *M1  =  V1[0].vector[0].elements.Int;			\
+      opihi_int *M2  =  V2[0].vector[0].elements.Int;			\
+      opihi_int *out = OUT[0].vector[0].elements.Int;			\
+      for (i = 0; i < Nx; i++, out++, M1++, M2++) {			\
+	*out = OP;							\
+      }									\
+      break;								\
+    }									\
+  }
+
+  switch (op[0]) {
+    case '+': VV_FUNC('s', *M1 + *M2);
+    case '-': VV_FUNC('s', *M1 - *M2);
+    case '*': VV_FUNC('s', *M1 * *M2);
+    case '/': VV_FUNC('S', *M1 / (opihi_flt) *M2);
+    case '%': VV_FUNC('s', (int)*M1 % (int)*M2);
+    case '^': VV_FUNC('S', pow (*M1, *M2));
+    case '@': VV_FUNC('S', DEG_RAD*atan2 (*M1, *M2));
+    case 'D': VV_FUNC('s', MIN (*M1, *M2));
+    case 'U': VV_FUNC('s', MAX (*M1, *M2));
+    case '<': VV_FUNC('s', (*M1 < *M2) ? 1 : 0);
+    case '>': VV_FUNC('s', (*M1 > *M2) ? 1 : 0);
+    case '&': VV_FUNC('s', ((int)*M1 & (int)*M2));
+    case '|': VV_FUNC('s', ((int)*M1 | (int)*M2));
+    case 'E': VV_FUNC('s', (*M1 == *M2) ? 1 : 0);
+    case 'N': VV_FUNC('s', (*M1 != *M2) ? 1 : 0);
+    case 'L': VV_FUNC('s', (*M1 <= *M2) ? 1 : 0);
+    case 'G': VV_FUNC('s', (*M1 >= *M2) ? 1 : 0);
+    case 'A': VV_FUNC('s', (*M1 && *M2) ? 1 : 0);
+    case 'O': VV_FUNC('s', (*M1 || *M2) ? 1 : 0);
+    default:
+      sprintf (line, "error: op %c not defined!", op[0]);
+      push_error (line);
+      return (FALSE);
+  }
+# undef VV_FUNC
+
+  /** free up any temporary buffers: **/
+
+  if (V1[0].type == 'v') {
+    free (V1[0].vector[0].elements.Ptr);
+    free (V1[0].vector);
+  }
+  if (V2[0].type == 'v') {
+    free (V2[0].vector[0].elements.Ptr);
+    free (V2[0].vector);
+  }
+  /* at the end, V1 and V2 are deleted only if they were temporary */
+
+  clear_stack (V1);
+  clear_stack (V2);
+  return (TRUE);
+
+}
+
+int SV_binary (StackVar *OUT, StackVar *V1, StackVar *V2, char *op) {
+
+  int i, Nx;
+  char line[512]; // this is only used to report an error 
+  
+  Nx = V2[0].vector[0].Nelements;
+
+  OUT[0].vector = InitVector ();
+  OUT[0].type = 'v';   /*** <<--- says this is a temporary matrix ***/
+
+  // set up the possible operations : int OP int -> int, all else yield float
+  // OP is the operation performed on *M1 and *M2
+# define SV_FUNC(FTYPE,OP) {						\
+    if ((V1->type == 'S') && (V2->vector->type == OPIHI_FLT)) {		\
+      CopyVector (OUT[0].vector, V2[0].vector);				\
+      opihi_flt  M1  =  V1[0].FltValue;					\
+      opihi_flt *M2  =  V2[0].vector[0].elements.Flt;			\
+      opihi_flt *out = OUT[0].vector[0].elements.Flt;			\
+      for (i = 0; i < Nx; i++, out++, M2++) {				\
+	*out = OP;							\
+      }									\
+      break;								\
+    }									\
+    if ((V1->type == 'S') && (V2->vector->type != OPIHI_FLT)) {		\
+      MatchVector (OUT[0].vector, V2[0].vector, OPIHI_FLT);		\
+      opihi_flt  M1  =  V1[0].FltValue;					\
+      opihi_int *M2  =  V2[0].vector[0].elements.Int;			\
+      opihi_flt *out = OUT[0].vector[0].elements.Flt;			\
+      for (i = 0; i < Nx; i++, out++, M2++) {				\
+	*out = OP;							\
+      }									\
+      break;								\
+    }									\
+    if ((V1->type == 's') && (V2->vector->type == OPIHI_FLT)) {		\
+      CopyVector (OUT[0].vector, V2[0].vector);				\
+      opihi_int  M1  =  V1[0].IntValue;					\
+      opihi_flt *M2  =  V2[0].vector[0].elements.Flt;			\
+      opihi_flt *out = OUT[0].vector[0].elements.Flt;			\
+      for (i = 0; i < Nx; i++, out++, M2++) {				\
+	*out = OP;							\
+      }									\
+      break;								\
+    }									\
+    if ((FTYPE == 'S') && (V1->type == 's') && (V2->vector->type != OPIHI_FLT)) { \
+      MatchVector (OUT[0].vector, V2[0].vector, OPIHI_FLT);		\
+      opihi_int  M1  =  V1[0].IntValue;					\
+      opihi_int *M2  =  V2[0].vector[0].elements.Int;			\
+      opihi_flt *out = OUT[0].vector[0].elements.Flt;			\
+      for (i = 0; i < Nx; i++, out++, M2++) {				\
+	*out = OP;							\
+      }									\
+      break;								\
+    }									\
+    if ((V1->type == 's') && (V2->vector->type != OPIHI_FLT)) {		\
+      CopyVector (OUT[0].vector, V2[0].vector);				\
+      opihi_int  M1  =  V1[0].IntValue;					\
+      opihi_int *M2  =  V2[0].vector[0].elements.Int;			\
+      opihi_int *out = OUT[0].vector[0].elements.Int;			\
+      for (i = 0; i < Nx; i++, out++, M2++) {				\
+	*out = OP;							\
+      }									\
+      break;								\
+    }									\
+  }
+
+  switch (op[0]) { 
+    case '+': SV_FUNC('s', M1 + *M2);
+    case '-': SV_FUNC('s', M1 - *M2);
+    case '*': SV_FUNC('s', M1 * *M2);
+    case '/': SV_FUNC('S', M1 / (opihi_flt) *M2);
+    case '%': SV_FUNC('s', (int) M1 % (int) *M2);
+    case '^': SV_FUNC('S', pow (M1, *M2));
+    case '@': SV_FUNC('S', DEG_RAD*atan2 (M1, *M2));
+    case 'D': SV_FUNC('s', MIN (M1, *M2));
+    case 'U': SV_FUNC('s', MAX (M1, *M2));
+    case '<': SV_FUNC('s', (M1 < *M2) ? 1 : 0);
+    case '>': SV_FUNC('s', (M1 > *M2) ? 1 : 0);
+    case '&': SV_FUNC('s', ((int)M1 & (int)*M2));
+    case '|': SV_FUNC('s', ((int)M1 | (int)*M2));
+    case 'E': SV_FUNC('s', (M1 == *M2) ? 1 : 0);
+    case 'N': SV_FUNC('s', (M1 != *M2) ? 1 : 0);
+    case 'L': SV_FUNC('s', (M1 <= *M2) ? 1 : 0);
+    case 'G': SV_FUNC('s', (M1 >= *M2) ? 1 : 0);
+    case 'A': SV_FUNC('s', (M1 && *M2) ? 1 : 0);
+    case 'O': SV_FUNC('s', (M1 || *M2) ? 1 : 0);
+    default:
+      sprintf (line, "error: op %c not defined!", op[0]);
+      push_error (line);
+      return (FALSE);
+  }
+# undef SV_FUNC
+
+  /** free up any temporary buffers: **/
+  if (V2[0].type == 'v') {
+    free (V2[0].vector[0].elements.Ptr);
+    free (V2[0].vector);
+  }
+
+  clear_stack (V1);
+  clear_stack (V2);
+
+  /* at the end, V1 and V2 are deleted only if they were temporary */
+  return (TRUE);
+
+}
+
+int VS_binary (StackVar *OUT, StackVar *V1, StackVar *V2, char *op) {
+
+  int i, Nx;
   char line[512]; // this is only used to report an error 
   
   Nx = V1[0].vector[0].Nelements;
-  if (Nx != V2[0].vector[0].Nelements) {
-    return (FALSE);
-  }
-
-  if (V1[0].type == 'v') {  /** use V1 as temp buffer **/
-    OUT[0].vector = V1[0].vector;
-    V1[0].type = 'V'; /* prevent it from being freed below */
-  } else {
-    if (V2[0].type == 'v') { /** use V2 as temp buffer, but header of V1 **/
-      OUT[0].vector = V2[0].vector;
-      V2[0].type = 'V'; /* prevent it from being freed below */
-    } else {  /* no spare temp buffer */
-      OUT[0].vector = InitVector ();
-      CopyVector (OUT[0].vector, V1[0].vector);
-    }
-  }
-  OUT[0].type = 'v'; /*** <<--- says this is a temporary matrix ***/
-
-  M1  = V1[0].ptr;
-  M2  = V2[0].ptr;
-  out = OUT[0].ptr = (float *)OUT[0].vector[0].elements;
+
+  OUT[0].vector = InitVector ();
+  OUT[0].type = 'v';   /*** <<--- says this is a temporary matrix ***/
+
+  // set up the possible operations : int OP int -> int, all else yield float
+  // OP is the operation performed on *M1 and *M2
+# define VS_FUNC(FTYPE,OP) {						\
+    if ((V2->type == 'S') && (V1->vector->type == OPIHI_FLT)) {		\
+      CopyVector (OUT[0].vector, V1[0].vector);				\
+      opihi_flt *M1  =  V1[0].vector[0].elements.Flt;			\
+      opihi_flt  M2  =  V2[0].FltValue;					\
+      opihi_flt *out = OUT[0].vector[0].elements.Flt;			\
+      for (i = 0; i < Nx; i++, out++, M1++) {				\
+	*out = OP;							\
+      }									\
+      break;								\
+    }									\
+    if ((V2->type == 'S') && (V1->vector->type != OPIHI_FLT)) {		\
+      MatchVector (OUT[0].vector, V1[0].vector, OPIHI_FLT);		\
+      opihi_int *M1  =  V1[0].vector[0].elements.Int;			\
+      opihi_flt  M2  =  V2[0].FltValue;					\
+      opihi_flt *out = OUT[0].vector[0].elements.Flt;			\
+      for (i = 0; i < Nx; i++, out++, M1++) {				\
+	*out = OP;							\
+      }									\
+      break;								\
+    }									\
+    if ((V2->type == 's') && (V1->vector->type == OPIHI_FLT)) {		\
+      CopyVector (OUT[0].vector, V1[0].vector);				\
+      opihi_flt *M1  =  V1[0].vector[0].elements.Flt;			\
+      opihi_int  M2  =  V2[0].IntValue;					\
+      opihi_flt *out = OUT[0].vector[0].elements.Flt;			\
+      for (i = 0; i < Nx; i++, out++, M1++) {				\
+	*out = OP;							\
+      }									\
+      break;								\
+    }									\
+    if ((FTYPE == 'S') && (V2->type == 's') && (V1->vector->type != OPIHI_FLT)) { \
+      CopyVector (OUT[0].vector, V1[0].vector);				\
+      opihi_int *M1  =  V1[0].vector[0].elements.Int;			\
+      opihi_int  M2  =  V2[0].IntValue;					\
+      opihi_int *out = OUT[0].vector[0].elements.Int;			\
+      for (i = 0; i < Nx; i++, out++, M1++) {				\
+	*out = OP;							\
+      }									\
+      break;								\
+    }									\
+    if ((V2->type == 's') && (V1->vector->type != OPIHI_FLT)) {		\
+      CopyVector (OUT[0].vector, V1[0].vector);				\
+      opihi_int *M1  =  V1[0].vector[0].elements.Int;			\
+      opihi_int  M2  =  V2[0].IntValue;					\
+      opihi_int *out = OUT[0].vector[0].elements.Int;			\
+      for (i = 0; i < Nx; i++, out++, M1++) {				\
+	*out = OP;							\
+      }									\
+      break;								\
+    }									\
+  }
 
   switch (op[0]) { 
-  case '+': 
-    for (i = 0; i < Nx; i++, out++, M1++, M2++)
-      *out = *M1 + *M2;
-    break; 
-  case '-': 
-    for (i = 0; i < Nx; i++, out++, M1++, M2++)
-      *out = *M1 - *M2;
-    break; 
-  case '*': 
-    for (i = 0; i < Nx; i++, out++, M1++, M2++)
-      *out = *M1 * *M2;
-    break; 
-  case '/': 
-    for (i = 0; i < Nx; i++, out++, M1++, M2++)
-      *out = *M1 / *M2;
-    break; 
-  case '%': 
-    for (i = 0; i < Nx; i++, out++, M1++, M2++)
-      *out = (int) *M1 % (int) *M2;
-    break; 
-  case 0x5e: 
-    for (i = 0; i < Nx; i++, out++, M1++, M2++) 
-      *out = pow (*M1, *M2);
-    break; 
-  case '@': 
-    for (i = 0; i < Nx; i++, out++, M1++, M2++) 
-      *out = DEG_RAD*atan2 (*M1, *M2);
-    break; 
-  case 'D': 
-    for (i = 0; i < Nx; i++, out++, M1++, M2++) 
-      *out = MIN (*M1, *M2);
-    break; 
-  case 'U': 
-    for (i = 0; i < Nx; i++, out++, M1++, M2++) 
-      *out = MAX (*M1, *M2);
-    break; 
-  case '<': 
-    for (i = 0; i < Nx; i++, out++, M1++, M2++) 
-      *out = (*M1 < *M2) ? 1 : 0;
-    break; 
-  case '>': 
-    for (i = 0; i < Nx; i++, out++, M1++, M2++) 
-      *out = (*M1 > *M2) ? 1 : 0;
-    break; 
-  case '&': 
-    for (i = 0; i < Nx; i++, out++, M1++, M2++) 
-      *out = ((int)*M1 & (int)*M2);
-    break; 
-  case '|': 
-    for (i = 0; i < Nx; i++, out++, M1++, M2++) 
-      *out = ((int)*M1 | (int)*M2);
-    break; 
-  case 'E': 
-    for (i = 0; i < Nx; i++, out++, M1++, M2++) 
-      *out = (*M1 == *M2) ? 1 : 0;
-    break; 
-  case 'N': 
-    for (i = 0; i < Nx; i++, out++, M1++, M2++) 
-      *out = (*M1 != *M2) ? 1 : 0;
-    break; 
-  case 'L': 
-    for (i = 0; i < Nx; i++, out++, M1++, M2++) 
-      *out = (*M1 <= *M2) ? 1 : 0;
-    break; 
-  case 'G': 
-    for (i = 0; i < Nx; i++, out++, M1++, M2++) 
-      *out = (*M1 >= *M2) ? 1 : 0;
-    break; 
-  case 'A': 
-    for (i = 0; i < Nx; i++, out++, M1++, M2++) 
-      *out = (*M1 && *M2) ? 1 : 0;
-    break; 
-  case 'O': 
-    for (i = 0; i < Nx; i++, out++, M1++, M2++) 
-      *out = (*M1 || *M2) ? 1 : 0;
-    break; 
-  default:
-    sprintf (line, "error: op %c not defined!", op[0]);
-    push_error (line);
-    return (FALSE);
-  }
+    case '+': VS_FUNC('s', *M1 + M2);
+    case '-': VS_FUNC('s', *M1 - M2);
+    case '*': VS_FUNC('s', *M1 * M2);
+    case '/': VS_FUNC('S', *M1 / (opihi_flt) M2);
+    case '%': VS_FUNC('s', (int) *M1 % (int) M2);
+    case '^': VS_FUNC('S', pow (*M1, M2));
+    case '@': VS_FUNC('S', DEG_RAD*atan2 (*M1, M2));
+    case 'D': VS_FUNC('s', MIN (*M1, M2));
+    case 'U': VS_FUNC('s', MAX (*M1, M2));
+    case '<': VS_FUNC('s', (*M1 < M2) ? 1 : 0);
+    case '>': VS_FUNC('s', (*M1 > M2) ? 1 : 0);
+    case '&': VS_FUNC('s', ((int)*M1 & (int)M2));
+    case '|': VS_FUNC('s', ((int)*M1 | (int)M2));
+    case 'E': VS_FUNC('s', (*M1 == M2) ? 1 : 0);
+    case 'N': VS_FUNC('s', (*M1 != M2) ? 1 : 0);
+    case 'L': VS_FUNC('s', (*M1 <= M2) ? 1 : 0);
+    case 'G': VS_FUNC('s', (*M1 >= M2) ? 1 : 0);
+    case 'A': VS_FUNC('s', (*M1 && M2) ? 1 : 0);
+    case 'O': VS_FUNC('s', (*M1 || M2) ? 1 : 0);
+    default:
+      sprintf (line, "error: op %c not defined!", op[0]);
+      push_error (line);
+      return (FALSE);
+  }
+# undef VS_FUNC
 
   /** free up any temporary buffers: **/
 
   if (V1[0].type == 'v') {
-    free (V1[0].vector[0].elements);
+    free (V1[0].vector[0].elements.Ptr);
     free (V1[0].vector);
   }
-  if (V2[0].type == 'v') {
-    free (V2[0].vector[0].elements);
-    free (V2[0].vector);
-  }
+
+  clear_stack (V1);
+  clear_stack (V2);
+
   /* at the end, V1 and V2 are deleted only if they were temporary */
-
-  clear_stack (V1);
-  clear_stack (V2);
-  return (TRUE);
-
-}
-
-int SV_binary (StackVar *OUT, StackVar *V1, StackVar *V2, char *op) {
-
-  int i, Nx;
-  float *out, *M1, *M2;
-  char line[512]; // this is only used to report an error 
-  
-  Nx = V2[0].vector[0].Nelements;
-
-  if (V2[0].type == 'v') { /** use V2 as temp buffer, but header of V1 **/
-    OUT[0].vector = V2[0].vector;
-    V2[0].type = 'V'; /* prevent it from being freed below */
-  } else {  /* no spare temp buffer */
-    OUT[0].vector = InitVector ();
-    CopyVector (OUT[0].vector, V2[0].vector);
-  }
-  OUT[0].type = 'v';   /*** <<--- says this is a temporary matrix ***/
-
-  M1  = V1[0].ptr;
-  M2  = V2[0].ptr;
-  out = OUT[0].ptr = (float *)OUT[0].vector[0].elements;
-
-  switch (op[0]) { 
-  case '+': 
-    for (i = 0; i < Nx; i++, out++, M2++)
-      *out = *M1 + *M2;
-    break; 
-  case '-': 
-    for (i = 0; i < Nx; i++, out++, M2++)
-      *out = *M1 - *M2;
-    break; 
-  case '*': 
-    for (i = 0; i < Nx; i++, out++, M2++)
-      *out = *M1 * *M2;
-    break; 
-  case '/': 
-    for (i = 0; i < Nx; i++, out++, M2++)
-      *out = *M1 / *M2;
-    break; 
-  case '%': 
-    for (i = 0; i < Nx; i++, out++, M2++)
-      *out = (int) *M1 % (int) *M2;
-    break; 
-  case 0x5e: 
-    for (i = 0; i < Nx; i++, out++, M2++) 
-      *out = pow (*M1, *M2);
-    break; 
-  case '@': 
-    for (i = 0; i < Nx; i++, out++, M2++) 
-      *out = DEG_RAD*atan2 (*M1, *M2);
-    break; 
-  case 'D': 
-    for (i = 0; i < Nx; i++, out++, M2++) 
-      *out = MIN (*M1, *M2);
-    break; 
-  case 'U': 
-    for (i = 0; i < Nx; i++, out++, M2++) 
-      *out = MAX (*M1, *M2);
-    break; 
-  case '<': 
-    for (i = 0; i < Nx; i++, out++, M2++) 
-      *out = (*M1 < *M2) ? 1 : 0;
-    break; 
-  case '>': 
-    for (i = 0; i < Nx; i++, out++, M2++) 
-      *out = (*M1 > *M2) ? 1 : 0;
-    break; 
-  case '&': 
-    for (i = 0; i < Nx; i++, out++, M2++) 
-      *out = ((int)*M1 & (int)*M2);
-    break; 
-  case '|': 
-    for (i = 0; i < Nx; i++, out++, M2++) 
-      *out = ((int)*M1 | (int)*M2);
-    break; 
-  case 'E': 
-    for (i = 0; i < Nx; i++, out++, M2++) 
-      *out = (*M1 == *M2) ? 1 : 0;
-    break; 
-  case 'N': 
-    for (i = 0; i < Nx; i++, out++, M2++) 
-      *out = (*M1 != *M2) ? 1 : 0;
-    break; 
-  case 'L': 
-    for (i = 0; i < Nx; i++, out++, M2++) 
-      *out = (*M1 <= *M2) ? 1 : 0;
-    break; 
-  case 'G': 
-    for (i = 0; i < Nx; i++, out++, M2++) 
-      *out = (*M1 >= *M2) ? 1 : 0;
-    break; 
-  case 'A': 
-    for (i = 0; i < Nx; i++, out++, M2++) 
-      *out = (*M1 && *M2) ? 1 : 0;
-    break; 
-  case 'O': 
-    for (i = 0; i < Nx; i++, out++, M2++) 
-      *out = (*M1 || *M2) ? 1 : 0;
-    break; 
-  default:
-    sprintf (line, "error: op %c not defined!", op[0]);
-    push_error (line);
-    return (FALSE);
-  }
-
-  /** free up any temporary buffers: **/
-  if (V2[0].type == 'v') {
-    free (V2[0].vector[0].elements);
-    free (V2[0].vector);
-  }
-
-  clear_stack (V1);
-  clear_stack (V2);
-
-  /* at the end, V1 and V2 are deleted only if they were temporary */
-  return (TRUE);
-
-}
-
-int VS_binary (StackVar *OUT, StackVar *V1, StackVar *V2, char *op) {
-
-  int i, Nx;
-  float *out, *M1, *M2;
-  char line[512]; // this is only used to report an error 
-  
-  Nx = V1[0].vector[0].Nelements;
-
-  if (V1[0].type == 'v') { /** use V1 as temp buffer **/
-    OUT[0].vector = V1[0].vector;
-    V1[0].type = 'V'; /* prevent it from being freed below */
-  } else {  /* no spare temp buffer */
-    OUT[0].vector = InitVector ();
-    CopyVector (OUT[0].vector, V1[0].vector);
-  }
-  OUT[0].type = 'v';   /*** <<--- says this is a temporary matrix ***/
-
-  M1  = V1[0].ptr;
-  M2  = V2[0].ptr;
-  out = OUT[0].ptr = (float *)OUT[0].vector[0].elements;
-
-  switch (op[0]) { 
-  case '+': 
-    for (i = 0; i < Nx; i++, out++, M1++)
-      *out = *M1 + *M2;
-    break; 
-  case '-': 
-    for (i = 0; i < Nx; i++, out++, M1++)
-      *out = *M1 - *M2;
-    break; 
-  case '*': 
-    for (i = 0; i < Nx; i++, out++, M1++)
-      *out = *M1 * *M2;
-    break; 
-  case '/': 
-    for (i = 0; i < Nx; i++, out++, M1++)
-      *out = *M1 / *M2;
-    break; 
-  case '%': 
-    for (i = 0; i < Nx; i++, out++, M1++)
-      *out = (int) *M1 % (int) *M2;
-    break; 
-  case 0x5e: 
-    for (i = 0; i < Nx; i++, out++, M1++) 
-      *out = pow (*M1, *M2);
-    break; 
-  case '@': 
-    for (i = 0; i < Nx; i++, out++, M1++) 
-      *out = DEG_RAD*atan2 (*M1, *M2);
-    break; 
-  case 'D': 
-    for (i = 0; i < Nx; i++, out++, M1++) 
-      *out = MIN (*M1, *M2);
-    break; 
-  case 'U': 
-    for (i = 0; i < Nx; i++, out++, M1++) 
-      *out = MAX (*M1, *M2);
-    break; 
-  case '<': 
-    for (i = 0; i < Nx; i++, out++, M1++) 
-      *out = (*M1 < *M2) ? 1 : 0;
-    break; 
-  case '>': 
-    for (i = 0; i < Nx; i++, out++, M1++) 
-      *out = (*M1 > *M2) ? 1 : 0;
-    break; 
-  case '&': 
-    for (i = 0; i < Nx; i++, out++, M1++) 
-      *out = ((int)*M1 & (int)*M2);
-    break; 
-  case '|': 
-    for (i = 0; i < Nx; i++, out++, M1++) 
-      *out = ((int)*M1 | (int)*M2);
-    break; 
-  case 'E': 
-    for (i = 0; i < Nx; i++, out++, M1++) 
-      *out = (*M1 == *M2) ? 1 : 0;
-    break; 
-  case 'N': 
-    for (i = 0; i < Nx; i++, out++, M1++) 
-      *out = (*M1 != *M2) ? 1 : 0;
-    break; 
-  case 'L': 
-    for (i = 0; i < Nx; i++, out++, M1++) 
-      *out = (*M1 <= *M2) ? 1 : 0;
-    break; 
-  case 'G': 
-    for (i = 0; i < Nx; i++, out++, M1++) 
-      *out = (*M1 >= *M2) ? 1 : 0;
-    break; 
-  case 'A': 
-    for (i = 0; i < Nx; i++, out++, M1++) 
-      *out = (*M1 && *M2) ? 1 : 0;
-    break; 
-  case 'O': 
-    for (i = 0; i < Nx; i++, out++, M1++) 
-      *out = (*M1 || *M2) ? 1 : 0;
-    break; 
-  default:
-    sprintf (line, "error: op %c not defined!", op[0]);
-    push_error (line);
-    return (FALSE);
-  }
-
-  /** free up any temporary buffers: **/
-
-  if (V1[0].type == 'v') {
-    free (V1[0].vector[0].elements);
-    free (V1[0].vector);
-  }
-
-  clear_stack (V1);
-  clear_stack (V2);
-
-  /* at the end, V1 and V2 are deleted only if they were temporary */
-  return (TRUE);
-
-}
-
+  return (TRUE);
+
+}
+
+// the vector is applied to each column
 int MV_binary (StackVar *OUT, StackVar *V1, StackVar *V2, char *op) {
 
   int i, j, Nx, Ny;
-  float *out, *M1, *M2;
   char line[512]; // this is only used to report an error 
  
@@ -397,128 +363,54 @@
   OUT[0].type = 'm'; /*** <<--- says this is a temporary matrix ***/
 
-  M1  = V1[0].ptr;
-  M2  = V2[0].ptr;
-  out = OUT[0].ptr = (float *)OUT[0].buffer[0].matrix.buffer;
+  float     *M1  = (float *) V1[0].buffer[0].matrix.buffer;
+  float     *out = (float *)OUT[0].buffer[0].matrix.buffer;
+
+# define MV_FUNC(OP) {					\
+    if (V2->vector->type == OPIHI_FLT) {		\
+      opihi_flt *M2  =  V2[0].vector[0].elements.Flt;	\
+      for (i = 0; i < Ny; i++, M2++) {			\
+	for (j = 0; j < Nx; j++, out++, M1++) {		\
+	  *out = OP;					\
+	}						\
+      }							\
+      break;						\
+    }							\
+    if (V2->vector->type != OPIHI_FLT) {		\
+      opihi_int *M2  =  V2[0].vector[0].elements.Int;	\
+      for (i = 0; i < Ny; i++, M2++) {			\
+	for (j = 0; j < Nx; j++, out++, M1++) {		\
+	  *out = OP;					\
+	}						\
+      }							\
+      break;						\
+    }							\
+  }
 
   switch (op[0]) { 
-  case '+': 
-    for (i = 0; i < Ny; i++, M2++) {
-      for (j = 0; j < Nx; j++, out++, M1++)
-        *out = *M1 + *M2;
-    }
-    break; 
-  case '-': 
-    for (i = 0; i < Ny; i++, M2++) {
-      for (j = 0; j < Nx; j++, out++, M1++)
-        *out = *M1 - *M2;
-    }
-    break; 
-  case '*': 
-    for (i = 0; i < Ny; i++, M2++) {
-      for (j = 0; j < Nx; j++, out++, M1++)
-        *out = *M1 * *M2;
-    }
-    break; 
-  case '/': 
-    for (i = 0; i < Ny; i++, M2++) {
-      for (j = 0; j < Nx; j++, out++, M1++)
-        *out = *M1 / *M2;
-    }
-    break; 
-  case '%': 
-    for (i = 0; i < Ny; i++, M2++) {
-      for (j = 0; j < Nx; j++, out++, M1++)
-        *out = (int) *M1 % (int) *M2;
-    }
-    break; 
-  case 0x5e: 
-    for (i = 0; i < Ny; i++, M2++) {
-      for (j = 0; j < Nx; j++, out++, M1++) 
-        *out = pow (*M1, *M2);
-    }
-    break; 
-  case '@': 
-    for (i = 0; i < Ny; i++, M2++) {
-      for (j = 0; j < Nx; j++, out++, M1++) 
-        *out = DEG_RAD*atan2 (*M1, *M2);
-    }
-    break; 
-  case 'D': 
-    for (i = 0; i < Ny; i++, M2++) {
-      for (j = 0; j < Nx; j++, out++, M1++) 
-        *out = MIN (*M1, *M2);
-    }
-    break; 
-  case 'U': 
-    for (i = 0; i < Ny; i++, M2++) {
-      for (j = 0; j < Nx; j++, out++, M1++) 
-        *out = MAX (*M1, *M2);
-    }
-    break; 
-  case '<': 
-    for (i = 0; i < Ny; i++, M2++) {
-      for (j = 0; j < Nx; j++, out++, M1++) 
-        *out = (*M1 < *M2) ? 1 : 0;
-    }
-    break; 
-  case '>': 
-    for (i = 0; i < Ny; i++, M2++) {
-      for (j = 0; j < Nx; j++, out++, M1++) 
-        *out = (*M1 > *M2) ? 1 : 0;
-    }
-    break; 
-  case '&': 
-    for (i = 0; i < Ny; i++, M2++) {
-      for (j = 0; j < Nx; j++, out++, M1++) 
-        *out = ((int)*M1 & (int)*M2);
-    }
-    break; 
-  case '|': 
-    for (i = 0; i < Ny; i++, M2++) {
-      for (j = 0; j < Nx; j++, out++, M1++) 
-        *out = ((int)*M1 | (int)*M2);
-    }
-    break; 
-  case 'E': 
-    for (i = 0; i < Ny; i++, M2++) {
-      for (j = 0; j < Nx; j++, out++, M1++) 
-        *out = (*M1 == *M2) ? 1 : 0;
-    }
-    break; 
-  case 'N': 
-    for (i = 0; i < Ny; i++, M2++) {
-      for (j = 0; j < Nx; j++, out++, M1++) 
-        *out = (*M1 != *M2) ? 1 : 0;
-    }
-    break; 
-  case 'L': 
-    for (i = 0; i < Ny; i++, M2++) {
-      for (j = 0; j < Nx; j++, out++, M1++) 
-        *out = (*M1 <= *M2) ? 1 : 0;
-    }
-    break; 
-  case 'G': 
-    for (i = 0; i < Ny; i++, M2++) {
-      for (j = 0; j < Nx; j++, out++, M1++) 
-        *out = (*M1 >= *M2) ? 1 : 0;
-    }
-    break; 
-  case 'A': 
-    for (i = 0; i < Ny; i++, M2++) {
-      for (j = 0; j < Nx; j++, out++, M1++) 
-        *out = (*M1 && *M2) ? 1 : 0;
-    }
-    break; 
-  case 'O': 
-    for (i = 0; i < Ny; i++, M2++) {
-      for (j = 0; j < Nx; j++, out++, M1++) 
-        *out = (*M1 || *M2) ? 1 : 0;
-    }
-    break; 
-  default:
-    sprintf (line, "error: op %c not defined!", op[0]);
-    push_error (line);
-    return (FALSE);
-  }
+    case '+': MV_FUNC(*M1 + *M2);
+    case '-': MV_FUNC(*M1 - *M2);
+    case '*': MV_FUNC(*M1 * *M2);
+    case '/': MV_FUNC(*M1 / (opihi_flt) *M2);
+    case '%': MV_FUNC((int) *M1 % (int) *M2);
+    case '^': MV_FUNC(pow (*M1, *M2));
+    case '@': MV_FUNC(DEG_RAD*atan2 (*M1, *M2));
+    case 'D': MV_FUNC(MIN (*M1, *M2));
+    case 'U': MV_FUNC(MAX (*M1, *M2));
+    case '<': MV_FUNC((*M1 < *M2) ? 1 : 0);
+    case '>': MV_FUNC((*M1 > *M2) ? 1 : 0);
+    case '&': MV_FUNC(((int)*M1 & (int)*M2));
+    case '|': MV_FUNC(((int)*M1 | (int)*M2));
+    case 'E': MV_FUNC((*M1 == *M2) ? 1 : 0);
+    case 'N': MV_FUNC((*M1 != *M2) ? 1 : 0);
+    case 'L': MV_FUNC((*M1 <= *M2) ? 1 : 0);
+    case 'G': MV_FUNC((*M1 >= *M2) ? 1 : 0);
+    case 'A': MV_FUNC((*M1 && *M2) ? 1 : 0);
+    case 'O': MV_FUNC((*M1 || *M2) ? 1 : 0);
+    default:
+      sprintf (line, "error: op %c not defined!", op[0]);
+      push_error (line);
+      return (FALSE);
+  }
+# undef MV_FUNC
 
   /** free up any temporary buffers: **/
@@ -530,5 +422,5 @@
   }
   if (V2[0].type == 'v') {
-    free (V2[0].vector[0].elements);
+    free (V2[0].vector[0].elements.Ptr);
     free (V2[0].vector);
   }
@@ -539,12 +431,10 @@
   /* at the end, V1 and V2 are deleted only if they were temporary */
   return (TRUE);
-
-}
-
-
+}
+
+// the vector is applied to each row
 int VM_binary (StackVar *OUT, StackVar *V1, StackVar *V2, char *op) {
 
   int i, j, Nx, Ny;
-  float *out, *M1, *M2;
   char line[512]; // this is only used to report an error 
   
@@ -565,152 +455,59 @@
   OUT[0].type = 'm'; /*** <<--- says this is a temporary matrix ***/
 
-  M1  = V1[0].ptr;
-  M2  = V2[0].ptr;
-  out = OUT[0].ptr = (float *)OUT[0].buffer[0].matrix.buffer;
+  float     *M2  = (float *) V2[0].buffer[0].matrix.buffer;
+  float     *out = (float *)OUT[0].buffer[0].matrix.buffer;
+
+# define VM_FUNC(OP) {					\
+    if (V1->vector->type == OPIHI_FLT) {		\
+      for (i = 0; i < Ny; i++) {			\
+	opihi_flt *M1  = V1[0].vector[0].elements.Flt;	\
+	for (j = 0; j < Nx; j++, out++, M1++, M2++) {	\
+	  *out = OP;					\
+	}						\
+      }							\
+      break;						\
+    }							\
+    if (V1->vector->type != OPIHI_FLT) {		\
+      for (i = 0; i < Ny; i++) {			\
+	opihi_int *M1  =  V1[0].vector[0].elements.Int;	\
+	for (j = 0; j < Nx; j++, out++, M1++, M2++) {	\
+	  *out = OP;					\
+	}						\
+      }							\
+      break;						\
+    }							\
+  }
 
   switch (op[0]) { 
-  case '+': 
-    for (i = 0; i < Ny; i++) {
-      M1 = V1[0].ptr;
-      for (j = 0; j < Nx; j++, out++, M1++, M2++)
-        *out = *M1 + *M2;
-    }
-    break; 
-  case '-': 
-    for (i = 0; i < Ny; i++) {
-      M1 = V1[0].ptr;
-      for (j = 0; j < Nx; j++, out++, M1++, M2++)
-        *out = *M1 - *M2;
-    }
-    break; 
-  case '*': 
-    for (i = 0; i < Ny; i++) {
-      M1 = V1[0].ptr;
-      for (j = 0; j < Nx; j++, out++, M1++, M2++)
-        *out = *M1 * *M2;
-    }
-    break; 
-  case '/': 
-    for (i = 0; i < Ny; i++) {
-      M1 = V1[0].ptr;
-      for (j = 0; j < Nx; j++, out++, M1++, M2++)
-        *out = *M1 / *M2;
-    }
-    break; 
-  case '%': 
-    for (i = 0; i < Ny; i++) {
-      M1 = V1[0].ptr;
-      for (j = 0; j < Nx; j++, out++, M1++, M2++)
-        *out = (int) *M1 % (int) *M2;
-    }
-    break; 
-  case 0x5e: 
-    for (i = 0; i < Ny; i++) {
-      M1 = V1[0].ptr;
-      for (j = 0; j < Nx; j++, out++, M1++, M2++) 
-        *out = pow (*M1, *M2);
-    }
-    break; 
-  case '@': 
-    for (i = 0; i < Ny; i++) {
-      M1 = V1[0].ptr;
-      for (j = 0; j < Nx; j++, out++, M1++, M2++) 
-        *out = DEG_RAD*atan2 (*M1, *M2);
-    }
-    break; 
-  case 'D': 
-    for (i = 0; i < Ny; i++) {
-      M1 = V1[0].ptr;
-      for (j = 0; j < Nx; j++, out++, M1++, M2++) 
-        *out = MIN (*M1, *M2);
-    }
-    break; 
-  case 'U': 
-    for (i = 0; i < Ny; i++) {
-      M1 = V1[0].ptr;
-      for (j = 0; j < Nx; j++, out++, M1++, M2++) 
-        *out = MAX (*M1, *M2);
-    }
-    break; 
-  case '<': 
-    for (i = 0; i < Ny; i++) {
-      M1 = V1[0].ptr;
-      for (j = 0; j < Nx; j++, out++, M1++, M2++) 
-        *out = (*M1 < *M2) ? 1 : 0;
-    }
-    break; 
-  case '>': 
-    for (i = 0; i < Ny; i++) {
-      M1 = V1[0].ptr;
-      for (j = 0; j < Nx; j++, out++, M1++, M2++) 
-        *out = (*M1 > *M2) ? 1 : 0;
-    }
-    break; 
-  case '&': 
-    for (i = 0; i < Ny; i++) {
-      M1 = V1[0].ptr;
-      for (j = 0; j < Nx; j++, out++, M1++, M2++) 
-        *out = ((int)*M1 & (int)*M2);
-    }
-    break; 
-  case '|': 
-    for (i = 0; i < Ny; i++) {
-      M1 = V1[0].ptr;
-      for (j = 0; j < Nx; j++, out++, M1++, M2++) 
-        *out = ((int)*M1 | (int)*M2);
-    }
-    break; 
-  case 'E': 
-    for (i = 0; i < Ny; i++) {
-      M1 = V1[0].ptr;
-      for (j = 0; j < Nx; j++, out++, M1++, M2++) 
-        *out = (*M1 == *M2) ? 1 : 0;
-    }
-    break; 
-  case 'N': 
-    for (i = 0; i < Ny; i++) {
-      M1 = V1[0].ptr;
-      for (j = 0; j < Nx; j++, out++, M1++, M2++) 
-        *out = (*M1 != *M2) ? 1 : 0;
-    }
-    break; 
-  case 'L': 
-    for (i = 0; i < Ny; i++) {
-      M1 = V1[0].ptr;
-      for (j = 0; j < Nx; j++, out++, M1++, M2++) 
-        *out = (*M1 <= *M2) ? 1 : 0;
-    }
-    break; 
-  case 'G': 
-    for (i = 0; i < Ny; i++) {
-      M1 = V1[0].ptr;
-      for (j = 0; j < Nx; j++, out++, M1++, M2++) 
-        *out = (*M1 >= *M2) ? 1 : 0;
-    }
-    break; 
-  case 'A': 
-    for (i = 0; i < Ny; i++) {
-      M1 = V1[0].ptr;
-      for (j = 0; j < Nx; j++, out++, M1++, M2++) 
-        *out = (*M1 && *M2) ? 1 : 0;
-    }
-    break; 
-  case 'O': 
-    for (i = 0; i < Ny; i++) {
-      M1 = V1[0].ptr;
-      for (j = 0; j < Nx; j++, out++, M1++, M2++) 
-        *out = (*M1 || *M2) ? 1 : 0;
-    }
-    break; 
-  default:
-    sprintf (line, "error: op %c not defined!", op[0]);
-    push_error (line);
-    return (FALSE);
-  }
+    case '+': VM_FUNC(*M1 + *M2);
+    case '-': VM_FUNC(*M1 - *M2);
+    case '*': VM_FUNC(*M1 * *M2);
+    case '/': VM_FUNC(*M1 / (opihi_flt) *M2);
+    case '%': VM_FUNC((int) *M1 % (int) *M2);
+    case '^': VM_FUNC(pow (*M1, *M2));
+    case '@': VM_FUNC(DEG_RAD*atan2 (*M1, *M2));
+    case 'D': VM_FUNC(MIN (*M1, *M2));
+    case 'U': VM_FUNC(MAX (*M1, *M2));
+    case '<': VM_FUNC((*M1 < *M2) ? 1 : 0);
+    case '>': VM_FUNC((*M1 > *M2) ? 1 : 0);
+    case '&': VM_FUNC(((int)*M1 & (int)*M2));
+    case '|': VM_FUNC(((int)*M1 | (int)*M2));
+    case 'E': VM_FUNC((*M1 == *M2) ? 1 : 0);
+    case 'N': VM_FUNC((*M1 != *M2) ? 1 : 0);
+    case 'L': VM_FUNC((*M1 <= *M2) ? 1 : 0);
+    case 'G': VM_FUNC((*M1 >= *M2) ? 1 : 0);
+    case 'A': VM_FUNC((*M1 && *M2) ? 1 : 0);
+    case 'O': VM_FUNC((*M1 || *M2) ? 1 : 0);
+    default:
+      sprintf (line, "error: op %c not defined!", op[0]);
+      push_error (line);
+      return (FALSE);
+  }
+# undef VM_FUNC
 
   /** free up any temporary buffers: **/
 
   if (V1[0].type == 'v') {
-    free (V1[0].vector[0].elements);
+    free (V1[0].vector[0].elements.Ptr);
     free (V1[0].vector);
   }
@@ -752,90 +549,40 @@
   OUT[0].type = 'm'; /*** <<--- says this is a temporary matrix ***/
 
-  M1  = V1[0].ptr;
-  M2  = V2[0].ptr;
-  out = OUT[0].ptr = (float *)OUT[0].buffer[0].matrix.buffer;
+  M1  = (float *)V1[0].buffer[0].matrix.buffer;
+  M2  = (float *)V2[0].buffer[0].matrix.buffer;
+  out = (float *)OUT[0].buffer[0].matrix.buffer;
+
+# define MM_FUNC(OP)					\
+  for (i = 0; i < Nx*Ny; i++, out++, M1++, M2++) {	\
+    *out = OP;						\
+  }							\
+  break; 
 
   switch (op[0]) { 
-  case '+': 
-    for (i = 0; i < Nx*Ny; i++, out++, M1++, M2++)
-      *out = *M1 + *M2;
-    break; 
-  case '-': 
-    for (i = 0; i < Nx*Ny; i++, out++, M1++, M2++)
-      *out = *M1 - *M2;
-    break; 
-  case '*': 
-    for (i = 0; i < Nx*Ny; i++, out++, M1++, M2++)
-      *out = *M1 * *M2;
-    break; 
-  case '/': 
-    for (i = 0; i < Nx*Ny; i++, out++, M1++, M2++)
-      *out = *M1 / *M2;
-    break; 
-  case '%': 
-    for (i = 0; i < Nx*Ny; i++, out++, M1++, M2++)
-      *out = (int) *M1 % (int) *M2;
-    break; 
-  case 0x5e: 
-    for (i = 0; i < Nx*Ny; i++, out++, M1++, M2++) 
-      *out = pow (*M1, *M2);
-    break; 
-  case '@': 
-    for (i = 0; i < Nx*Ny; i++, out++, M1++, M2++) 
-      *out = DEG_RAD*atan2 (*M1, *M2);
-    break; 
-  case 'D': 
-    for (i = 0; i < Nx*Ny; i++, out++, M1++, M2++) 
-      *out = MIN (*M1, *M2);
-    break; 
-  case 'U': 
-    for (i = 0; i < Nx*Ny; i++, out++, M1++, M2++) 
-      *out = MAX (*M1, *M2);
-    break; 
-  case '<': 
-    for (i = 0; i < Nx*Ny; i++, out++, M1++, M2++) 
-      *out = (*M1 < *M2) ? 1 : 0;
-    break; 
-  case '>': 
-    for (i = 0; i < Nx*Ny; i++, out++, M1++, M2++) 
-      *out = (*M1 > *M2) ? 1 : 0;
-    break; 
-  case '&': 
-    for (i = 0; i < Nx*Ny; i++, out++, M1++, M2++) 
-      *out = ((int)*M1 & (int)*M2);
-    break; 
-  case '|': 
-    for (i = 0; i < Nx*Ny; i++, out++, M1++, M2++) 
-      *out = ((int)*M1 | (int)*M2);
-    break; 
-  case 'E': 
-    for (i = 0; i < Nx*Ny; i++, out++, M1++, M2++) 
-      *out = (*M1 == *M2) ? 1 : 0;
-    break; 
-  case 'N': 
-    for (i = 0; i < Nx*Ny; i++, out++, M1++, M2++) 
-      *out = (*M1 != *M2) ? 1 : 0;
-    break; 
-  case 'L': 
-    for (i = 0; i < Nx*Ny; i++, out++, M1++, M2++) 
-      *out = (*M1 <= *M2) ? 1 : 0;
-    break; 
-  case 'G': 
-    for (i = 0; i < Nx*Ny; i++, out++, M1++, M2++) 
-      *out = (*M1 >= *M2) ? 1 : 0;
-    break; 
-  case 'A': 
-    for (i = 0; i < Nx*Ny; i++, out++, M1++, M2++) 
-      *out = (*M1 && *M2) ? 1 : 0;
-    break; 
-  case 'O': 
-    for (i = 0; i < Nx*Ny; i++, out++, M1++, M2++) 
-      *out = (*M1 || *M2) ? 1 : 0;
-    break; 
-  default:
-    sprintf (line, "error: op %c not defined!", op[0]);
-    push_error (line);
-    return (FALSE);
-  }
+    case '+': MM_FUNC(*M1 + *M2);
+    case '-': MM_FUNC(*M1 - *M2);
+    case '*': MM_FUNC(*M1 * *M2);
+    case '/': MM_FUNC(*M1 / (float) *M2);
+    case '%': MM_FUNC((int) *M1 % (int) *M2);
+    case '^': MM_FUNC(pow (*M1, *M2));
+    case '@': MM_FUNC(DEG_RAD*atan2 (*M1, *M2));
+    case 'D': MM_FUNC(MIN (*M1, *M2));
+    case 'U': MM_FUNC(MAX (*M1, *M2));
+    case '<': MM_FUNC((*M1 < *M2) ? 1 : 0);
+    case '>': MM_FUNC((*M1 > *M2) ? 1 : 0);
+    case '&': MM_FUNC(((int)*M1 & (int)*M2));
+    case '|': MM_FUNC(((int)*M1 | (int)*M2));
+    case 'E': MM_FUNC((*M1 == *M2) ? 1 : 0);
+    case 'N': MM_FUNC((*M1 != *M2) ? 1 : 0);
+    case 'L': MM_FUNC((*M1 <= *M2) ? 1 : 0);
+    case 'G': MM_FUNC((*M1 >= *M2) ? 1 : 0);
+    case 'A': MM_FUNC((*M1 && *M2) ? 1 : 0);
+    case 'O': MM_FUNC((*M1 || *M2) ? 1 : 0);
+    default:
+      sprintf (line, "error: op %c not defined!", op[0]);
+      push_error (line);
+      return (FALSE);
+  }
+# undef MM_FUNC
 
   /** free up any temporary buffers: **/
@@ -857,12 +604,9 @@
   /* at the end, V1 and V2 are deleted only if they were temporary */
   return (TRUE);
-
-}
-
+}
 
 int MS_binary (StackVar *OUT, StackVar *V1, StackVar *V2, char *op) {
 
   int i, Nx, Ny;
-  float *out, *M1, *M2;
   char line[512]; // this is only used to report an error 
   
@@ -880,90 +624,50 @@
   OUT[0].type = 'm';      /*** <<--- says this is a temporary matrix ***/
 
-  M1  = V1[0].ptr;
-  M2  = V2[0].ptr;
-  out = OUT[0].ptr = (float *)OUT[0].buffer[0].matrix.buffer;
+  float *M1    = (float *)V1[0].buffer[0].matrix.buffer;
+  float *out   = (float *)OUT[0].buffer[0].matrix.buffer;
+
+# define MS_FUNC(OP) {					\
+    if (V2->type == 's')  {				\
+      opihi_flt M2 = V2[0].FltValue;			\
+      for (i = 0; i < Nx*Ny; i++, out++, M1++) {	\
+	*out = OP;					\
+      }							\
+      break;						\
+    }							\
+    if (V2->type == 'S')  {				\
+      opihi_int M2 = V2[0].IntValue;			\
+      for (i = 0; i < Nx*Ny; i++, out++, M1++) {	\
+	*out = OP;					\
+      }							\
+      break;						\
+    }							\
+  }
 
   switch (op[0]) { 
-  case '+': 
-    for (i = 0; i < Nx*Ny; i++, out++, M1++)
-      *out = *M1 + *M2;
-    break; 
-  case '-': 
-    for (i = 0; i < Nx*Ny; i++, out++, M1++)
-      *out = *M1 - *M2;
-    break; 
-  case '*': 
-    for (i = 0; i < Nx*Ny; i++, out++, M1++)
-      *out = *M1 * *M2;
-    break; 
-  case '/': 
-    for (i = 0; i < Nx*Ny; i++, out++, M1++)
-      *out = *M1 / *M2;
-    break; 
-  case '%': 
-    for (i = 0; i < Nx*Ny; i++, out++, M1++)
-      *out = (int) *M1 % (int) *M2;
-    break; 
-  case 0x5e: 
-    for (i = 0; i < Nx*Ny; i++, out++, M1++) 
-      *out = pow (*M1, *M2);
-    break; 
-  case '@': 
-    for (i = 0; i < Nx*Ny; i++, out++, M1++) 
-      *out = DEG_RAD*atan2 (*M1, *M2);
-    break; 
-  case 'D': 
-    for (i = 0; i < Nx*Ny; i++, out++, M1++) 
-      *out = MIN (*M1, *M2);
-    break; 
-  case 'U': 
-    for (i = 0; i < Nx*Ny; i++, out++, M1++) 
-      *out = MAX (*M1, *M2);
-    break; 
-  case '<': 
-    for (i = 0; i < Nx*Ny; i++, out++, M1++) 
-      *out = (*M1 < *M2) ? 1 : 0;
-    break; 
-  case '>': 
-    for (i = 0; i < Nx*Ny; i++, out++, M1++) 
-      *out = (*M1 > *M2) ? 1 : 0;
-    break; 
-  case '&': 
-    for (i = 0; i < Nx*Ny; i++, out++, M1++) 
-      *out = ((int)*M1 & (int)*M2);
-    break; 
-  case '|': 
-    for (i = 0; i < Nx*Ny; i++, out++, M1++) 
-      *out = ((int)*M1 | (int)*M2);
-    break; 
-  case 'E': 
-    for (i = 0; i < Nx*Ny; i++, out++, M1++) 
-      *out = (*M1 == *M2) ? 1 : 0;
-    break; 
-  case 'N': 
-    for (i = 0; i < Nx*Ny; i++, out++, M1++) 
-      *out = (*M1 != *M2) ? 1 : 0;
-    break; 
-  case 'L': 
-    for (i = 0; i < Nx*Ny; i++, out++, M1++) 
-      *out = (*M1 <= *M2) ? 1 : 0;
-    break; 
-  case 'G': 
-    for (i = 0; i < Nx*Ny; i++, out++, M1++) 
-      *out = (*M1 >= *M2) ? 1 : 0;
-    break; 
-  case 'A': 
-    for (i = 0; i < Nx*Ny; i++, out++, M1++) 
-      *out = (*M1 && *M2) ? 1 : 0;
-    break; 
-  case 'O': 
-    for (i = 0; i < Nx*Ny; i++, out++, M1++) 
-      *out = (*M1 || *M2) ? 1 : 0;
-    break; 
-  default:
-    sprintf (line, "error: op %c not defined!", op[0]);
-    push_error (line);
-    return (FALSE);
-  }
+    case '+': MS_FUNC(*M1 + M2);
+    case '-': MS_FUNC(*M1 - M2);
+    case '*': MS_FUNC(*M1 * M2);
+    case '/': MS_FUNC(*M1 / (float) M2);
+    case '%': MS_FUNC((int) *M1 % (int) M2);
+    case '^': MS_FUNC(pow (*M1, M2));
+    case '@': MS_FUNC(DEG_RAD*atan2 (*M1, M2));
+    case 'D': MS_FUNC(MIN (*M1, M2));
+    case 'U': MS_FUNC(MAX (*M1, M2));
+    case '<': MS_FUNC((*M1 < M2) ? 1 : 0);
+    case '>': MS_FUNC((*M1 > M2) ? 1 : 0);
+    case '&': MS_FUNC(((int)*M1 & (int)M2));
+    case '|': MS_FUNC(((int)*M1 | (int)M2));
+    case 'E': MS_FUNC((*M1 == M2) ? 1 : 0);
+    case 'N': MS_FUNC((*M1 != M2) ? 1 : 0);
+    case 'L': MS_FUNC((*M1 <= M2) ? 1 : 0);
+    case 'G': MS_FUNC((*M1 >= M2) ? 1 : 0);
+    case 'A': MS_FUNC((*M1 && M2) ? 1 : 0);
+    case 'O': MS_FUNC((*M1 || M2) ? 1 : 0);
+    default:
+      sprintf (line, "error: op %c not defined!", op[0]);
+      push_error (line);
+      return (FALSE);
+  }
+# undef MS_FUNC
 
   if (V1[0].type == 'm') {
@@ -976,5 +680,4 @@
 
   return (TRUE);
-
 }
 
@@ -983,5 +686,4 @@
 
   int i, Nx, Ny;
-  float *out, *M1, *M2;
   char line[512]; // this is only used to report an error 
   
@@ -998,90 +700,50 @@
   OUT[0].type = 'm'; /*** <<--- says this is a temporary matrix ***/
 
-  M1  = V1[0].ptr;
-  M2  = V2[0].ptr;
-  out = OUT[0].ptr = (float *)OUT[0].buffer[0].matrix.buffer;
+  float *M2    = (float *)V2[0].buffer[0].matrix.buffer;
+  float *out   = (float *)OUT[0].buffer[0].matrix.buffer;
+
+# define SM_FUNC(OP) {					\
+    if (V1->type == 's')  {				\
+      opihi_flt M1 = V1[0].FltValue;			\
+      for (i = 0; i < Nx*Ny; i++, out++, M2++) {	\
+	*out = OP;					\
+      }							\
+      break;						\
+    }							\
+    if (V1->type == 'S')  {				\
+      opihi_int M1 = V1[0].IntValue;			\
+      for (i = 0; i < Nx*Ny; i++, out++, M2++) {	\
+	*out = OP;					\
+      }							\
+      break;						\
+    }							\
+  }
 
   switch (op[0]) { 
-  case '+': 
-    for (i = 0; i < Nx*Ny; i++, out++, M2++)
-      *out = *M1 + *M2;
-    break; 
-  case '-': 
-    for (i = 0; i < Nx*Ny; i++, out++, M2++)
-      *out = *M1 - *M2;
-    break; 
-  case '*': 
-    for (i = 0; i < Nx*Ny; i++, out++, M2++)
-      *out = *M1 * *M2;
-    break; 
-  case '/': 
-    for (i = 0; i < Nx*Ny; i++, out++, M2++)
-      *out = *M1 / *M2;
-    break; 
-  case '%': 
-    for (i = 0; i < Nx*Ny; i++, out++, M2++)
-      *out = (int) *M1 % (int) *M2;
-    break; 
-  case 0x5e: 
-    for (i = 0; i < Nx*Ny; i++, out++, M2++)
-      *out = pow (*M1, *M2);
-    break; 
-  case '@': 
-    for (i = 0; i < Nx*Ny; i++, out++, M2++) 
-      *out = DEG_RAD*atan2 (*M1, *M2);
-    break; 
-  case 'D': 
-    for (i = 0; i < Nx*Ny; i++, out++, M2++) 
-      *out = MIN (*M1, *M2);
-    break; 
-  case 'U': 
-    for (i = 0; i < Nx*Ny; i++, out++, M2++) 
-      *out = MAX (*M1, *M2);
-    break; 
-  case '<': 
-    for (i = 0; i < Nx*Ny; i++, out++, M2++) 
-      *out = (*M1 < *M2) ? 1 : 0;
-    break; 
-  case '>': 
-    for (i = 0; i < Nx*Ny; i++, out++, M2++) 
-      *out = (*M1 > *M2) ? 1 : 0;
-    break; 
-  case '&': 
-    for (i = 0; i < Nx*Ny; i++, out++, M2++) 
-      *out = ((int)*M1 & (int)*M2);
-    break; 
-  case '|': 
-    for (i = 0; i < Nx*Ny; i++, out++, M2++) 
-      *out = ((int)*M1 | (int)*M2);
-    break; 
-  case 'E': 
-    for (i = 0; i < Nx*Ny; i++, out++, M2++) 
-      *out = (*M1 == *M2) ? 1 : 0;
-    break; 
-  case 'N': 
-    for (i = 0; i < Nx*Ny; i++, out++, M2++) 
-      *out = (*M1 != *M2) ? 1 : 0;
-    break; 
-  case 'L': 
-    for (i = 0; i < Nx*Ny; i++, out++, M2++) 
-      *out = (*M1 <= *M2) ? 1 : 0;
-    break; 
-  case 'G': 
-    for (i = 0; i < Nx*Ny; i++, out++, M2++) 
-      *out = (*M1 >= *M2) ? 1 : 0;
-    break; 
-  case 'A': 
-    for (i = 0; i < Nx*Ny; i++, out++, M2++) 
-      *out = (*M1 && *M2) ? 1 : 0;
-    break; 
-  case 'O': 
-    for (i = 0; i < Nx*Ny; i++, out++, M2++) 
-      *out = (*M1 || *M2) ? 1 : 0;
-    break; 
-  default:
-    sprintf (line, "error: op %c not defined!", op[0]);
-    push_error (line);
-    return (FALSE);
-  }
+    case '+': SM_FUNC(M1 + *M2);
+    case '-': SM_FUNC(M1 - *M2);
+    case '*': SM_FUNC(M1 * *M2);
+    case '/': SM_FUNC(M1 / (float) *M2);
+    case '%': SM_FUNC((int) M1 % (int) *M2);
+    case '^': SM_FUNC(pow (M1, *M2));
+    case '@': SM_FUNC(DEG_RAD*atan2 (M1, *M2));
+    case 'D': SM_FUNC(MIN (M1, *M2));
+    case 'U': SM_FUNC(MAX (M1, *M2));
+    case '<': SM_FUNC((M1 < *M2) ? 1 : 0);
+    case '>': SM_FUNC((M1 > *M2) ? 1 : 0);
+    case '&': SM_FUNC(((int)M1 & (int)*M2));
+    case '|': SM_FUNC(((int)M1 | (int)*M2));
+    case 'E': SM_FUNC((M1 == *M2) ? 1 : 0);
+    case 'N': SM_FUNC((M1 != *M2) ? 1 : 0);
+    case 'L': SM_FUNC((M1 <= *M2) ? 1 : 0);
+    case 'G': SM_FUNC((M1 >= *M2) ? 1 : 0);
+    case 'A': SM_FUNC((M1 && *M2) ? 1 : 0);
+    case 'O': SM_FUNC((M1 || *M2) ? 1 : 0);
+    default:
+      sprintf (line, "error: op %c not defined!", op[0]);
+      push_error (line);
+      return (FALSE);
+  }
+# undef SM_FUNC
 
   if (V2[0].type == 'm') {
@@ -1097,81 +759,72 @@
 }
 
-
 int SS_binary (StackVar *OUT, StackVar *V1, StackVar *V2, char *op) {
 
-  float *M1, *M2, *out;
   char line[512]; // this is only used to report an error 
 
-  M1  = V1[0].ptr;
-  M2  = V2[0].ptr;
-  OUT[0].ptr = V1[0].ptr;
-  out = OUT[0].ptr;
-
+# define SS_FUNC(FTYPE,OP) {						\
+    if ((V1->type == 'S') && (V2->type == 'S')) {			\
+      opihi_flt M1 = V1[0].FltValue;					\
+      opihi_flt M2 = V2[0].FltValue;					\
+      OUT[0].type = 'S';						\
+      OUT[0].FltValue = OP;						\
+      break;								\
+    }									\
+    if ((V1->type == 'S') && (V2->type == 's')) {			\
+      opihi_flt M1 = V1[0].FltValue;					\
+      opihi_int M2 = V2[0].IntValue;					\
+      OUT[0].type = 'S';						\
+      OUT[0].FltValue = OP;						\
+      break;								\
+    }									\
+    if ((V1->type == 's') && (V2->type == 'S')) {			\
+      opihi_int M1 = V1[0].IntValue;					\
+      opihi_flt M2 = V2[0].FltValue;					\
+      OUT[0].type = 'S';						\
+      OUT[0].FltValue = OP;						\
+      break;								\
+    }									\
+    if ((FTYPE == 'S') && (V1->type == 's') && (V2->type == 's')) {	\
+      opihi_int M1 = V1[0].IntValue;					\
+      opihi_int M2 = V2[0].IntValue;					\
+      OUT[0].type = 'S';						\
+      OUT[0].FltValue = OP;						\
+      break;								\
+    }									\
+    if ((V1->type == 's') && (V2->type == 's')) {			\
+      opihi_int M1 = V1[0].IntValue;					\
+      opihi_int M2 = V2[0].IntValue;					\
+      OUT[0].type = 's';						\
+      OUT[0].IntValue = OP;						\
+      break;								\
+    }									\
+  }
 
   switch (op[0]) { 
-  case '+': 
-    *out = *M1 + *M2;
-    break;    
-  case '-': 
-    *out = *M1 - *M2;
-    break;    
-  case '*': 
-    *out = *M1 * *M2;
-    break;    
-  case '/': 
-    *out = *M1 / *M2;
-    break; 
-  case '%': 
-    *out = (int) *M1 % (int) *M2;
-    break; 
-  case 0x5e: 
-    *out = pow (*M1, *M2);
-    break; 
-  case '@': 
-    *out = DEG_RAD*atan2 (*M1, *M2);
-    break; 
-  case 'D': 
-    *out = MIN (*M1, *M2);
-    break; 
-  case 'U': 
-    *out = MAX (*M1, *M2);
-    break; 
-  case '<': 
-    *out = (*M1 < *M2) ? 1 : 0;
-    break; 
-  case '>': 
-    *out = (*M1 > *M2) ? 1 : 0;
-    break; 
-  case '&': 
-    *out = ((int)*M1 & (int)*M2);
-    break; 
-  case '|': 
-    *out = ((int)*M1 | (int)*M2);
-    break; 
-  case 'E': 
-    *out = (*M1 == *M2) ? 1 : 0;
-    break; 
-  case 'N': 
-    *out = (*M1 != *M2) ? 1 : 0;
-    break; 
-  case 'L': 
-    *out = (*M1 <= *M2) ? 1 : 0;
-    break; 
-  case 'G': 
-    *out = (*M1 >= *M2) ? 1 : 0;
-    break; 
-  case 'A': 
-    *out = (*M1 && *M2) ? 1 : 0;
-    break; 
-  case 'O': 
-    *out = (*M1 || *M2) ? 1 : 0;
-    break; 
-  default:
-    sprintf (line, "error: op %c not defined!", op[0]);
-    push_error (line);
-    return (FALSE);
-  }
-  OUT[0].Float = *(OUT[0].ptr);
-  OUT[0].type = 'S';
+    case '+': SS_FUNC('s', M1 + M2);
+    case '-': SS_FUNC('s', M1 - M2);
+    case '*': SS_FUNC('s', M1 * M2);
+    case '/': SS_FUNC('S', M1 / (opihi_flt) M2);
+    case '%': SS_FUNC('s', (int) M1 % (int) M2);
+    case '^': SS_FUNC('S', pow (M1, M2));
+    case '@': SS_FUNC('S', DEG_RAD*atan2 (M1, M2));
+    case 'D': SS_FUNC('s', MIN (M1, M2));
+    case 'U': SS_FUNC('s', MAX (M1, M2));
+    case '<': SS_FUNC('s', (M1 < M2) ? 1 : 0);
+    case '>': SS_FUNC('s', (M1 > M2) ? 1 : 0);
+    case '&': SS_FUNC('s', ((int)M1 & (int)M2));
+    case '|': SS_FUNC('s', ((int)M1 | (int)M2));
+    case 'E': SS_FUNC('s', (M1 == M2) ? 1 : 0);
+    case 'N': SS_FUNC('s', (M1 != M2) ? 1 : 0);
+    case 'L': SS_FUNC('s', (M1 <= M2) ? 1 : 0);
+    case 'G': SS_FUNC('s', (M1 >= M2) ? 1 : 0);
+    case 'A': SS_FUNC('s', (M1 && M2) ? 1 : 0);
+    case 'O': SS_FUNC('s', (M1 || M2) ? 1 : 0);
+    default:
+      sprintf (line, "error: op %c not defined!", op[0]);
+      push_error (line);
+      return (FALSE);
+  }
+# undef SS_FUNC
 
   clear_stack (V1);
@@ -1188,5 +841,5 @@
 
   /* only 'N' and 'E' are allowed for WW_binary operations. anything else is either a
-   syntax error or is a string which looks like a math expression. */
+     syntax error or is a string which looks like a math expression. */
 
   if ((op[0] != 'N') && (op[0] != 'E')) {
@@ -1210,20 +863,19 @@
 
   switch (op[0]) { 
-  case 'E': 
-    value = strcmp (V1[0].name, V2[0].name) ? 0 : 1;
+    case 'E': 
+      value = strcmp (V1[0].name, V2[0].name) ? 0 : 1;
     break; 
-  case 'N': 
-    value = strcmp (V1[0].name, V2[0].name) ? 1 : 0;
+    case 'N': 
+      value = strcmp (V1[0].name, V2[0].name) ? 1 : 0;
     break; 
-  default:
-    sprintf (line, "error: op %c not defined for string operations!", op[0]);
-    push_error (line);
-    return (FALSE);
+    default:
+      sprintf (line, "error: op %c not defined for string operations!", op[0]);
+      push_error (line);
+      return (FALSE);
   }
 
 escape:
-  OUT[0].Float = value;
+  OUT[0].FltValue = value;
   OUT[0].type = 'S';
-  OUT[0].ptr = &OUT[0].Float;
 
   clear_stack (V1);
@@ -1236,48 +888,68 @@
 int S_unary (StackVar *OUT, StackVar *V1, char *op) {
 
-  float *out, *M1;
+  char line[512]; // this is only used to report an error 
   
-  out = OUT[0].ptr = V1[0].ptr;
-  M1  = V1[0].ptr;
-
-  if (!strcmp (op, "="))     {    }
-  if (!strcmp (op, "abs"))   {    *out = fabs(*M1);           }
-  if (!strcmp (op, "int"))   {    *out = (float)(int)(*M1);   }
-  if (!strcmp (op, "exp"))   {    *out = exp (*M1);           }
-  if (!strcmp (op, "ten"))   {    *out = pow (10.0,*M1);      }
-  if (!strcmp (op, "log"))   {    *out = log10 (*M1);         }
-  if (!strcmp (op, "ln"))    {    *out = log (*M1);           }
-  if (!strcmp (op, "sqrt"))  {    *out = sqrt (*M1);          }
-  if (!strcmp (op, "erf"))   {    *out = erf (*M1);           }
-
-  if (!strcmp (op, "sinh"))  {    *out = sinh (*M1);          }
-  if (!strcmp (op, "cosh"))  {    *out = cosh (*M1);          }
-  if (!strcmp (op, "asinh")) {    *out = asinh (*M1);         }
-  if (!strcmp (op, "acosh")) {    *out = acosh (*M1);         }
-  if (!strcmp (op, "lgamma")) {   *out = lgamma (*M1);        }
-
-  if (!strcmp (op, "sin"))   {    *out = sin (*M1);           }
-  if (!strcmp (op, "cos"))   {    *out = cos (*M1);           }
-  if (!strcmp (op, "tan"))   {    *out = tan (*M1);           }
-  if (!strcmp (op, "dsin"))  {    *out = sin (*M1*RAD_DEG);   }
-  if (!strcmp (op, "dcos"))  {    *out = cos (*M1*RAD_DEG);   }
-  if (!strcmp (op, "dtan"))  {    *out = tan (*M1*RAD_DEG);   }
-  if (!strcmp (op, "asin"))  {    *out = asin (*M1);          }
-  if (!strcmp (op, "acos"))  {    *out = acos (*M1);          }
-  if (!strcmp (op, "atan"))  {    *out = atan (*M1);          }
-  if (!strcmp (op, "dasin")) {    *out = asin (*M1)*DEG_RAD;  }
-  if (!strcmp (op, "dacos")) {    *out = acos (*M1)*DEG_RAD;  }
-  if (!strcmp (op, "datan")) {    *out = atan (*M1)*DEG_RAD;  }
-  if (!strcmp (op, "rnd"))   {    *out = drand48();           }
-  if (!strcmp (op, "not"))   {    *out = !(*M1);              }
-  if (!strcmp (op, "--"))    {    *out = - (*M1);             }
-  if (!strcmp (op, "isinf")) {    *out = !finite(*M1);        }
-  if (!strcmp (op, "isnan")) {    *out = isnan(*M1);          } 
-
-  OUT[0].Float = *out;
-  OUT[0].type = 'S';
-
-  clear_stack (V1);
-  return (TRUE);
+# define S_FUNC(OP,FTYPE) {			\
+    if (V1->type == 'S') {			\
+      opihi_flt M1  = V1[0].FltValue;		\
+      OUT[0].type = 'S';			\
+      OUT[0].FltValue = OP;			\
+      clear_stack (V1);				\
+      return (TRUE);				\
+    }						\
+    if ((FTYPE == 'S') && (V1->type == 's')) {	\
+      opihi_int M1  = V1[0].IntValue;		\
+      OUT[0].type = 'S';			\
+      OUT[0].FltValue = OP;			\
+      clear_stack (V1);				\
+      return (TRUE);				\
+    }						\
+    if ((FTYPE == 's') && (V1->type == 's')) {	\
+      opihi_int M1  = V1[0].IntValue;		\
+      OUT[0].type = 's';			\
+      OUT[0].IntValue = OP;			\
+      clear_stack (V1);				\
+      return (TRUE);				\
+    }						\
+  }
+
+  if (!strcmp (op, "="))      S_FUNC(M1, 's');
+  if (!strcmp (op, "abs"))    S_FUNC(fabs(M1), 's');
+  if (!strcmp (op, "int"))    S_FUNC((int)(M1), 's');
+  if (!strcmp (op, "exp"))    S_FUNC(exp (M1), 'S');
+  if (!strcmp (op, "ten"))    S_FUNC(pow (10.0,M1), 'S');
+  if (!strcmp (op, "log"))    S_FUNC(log10 (M1), 'S');
+  if (!strcmp (op, "ln"))     S_FUNC(log (M1), 'S');
+  if (!strcmp (op, "sqrt"))   S_FUNC(sqrt (M1), 'S');
+  if (!strcmp (op, "erf"))    S_FUNC(erf (M1), 'S');
+  if (!strcmp (op, "sinh"))   S_FUNC(sinh (M1), 'S');
+  if (!strcmp (op, "cosh"))   S_FUNC(cosh (M1), 'S');
+  if (!strcmp (op, "asinh"))  S_FUNC(asinh (M1), 'S');
+  if (!strcmp (op, "acosh"))  S_FUNC(acosh (M1), 'S');
+  if (!strcmp (op, "lgamma")) S_FUNC(lgamma (M1), 'S');
+  if (!strcmp (op, "sin"))    S_FUNC(sin (M1), 'S');
+  if (!strcmp (op, "cos"))    S_FUNC(cos (M1), 'S');
+  if (!strcmp (op, "tan"))    S_FUNC(tan (M1), 'S');
+  if (!strcmp (op, "dsin"))   S_FUNC(sin (M1*RAD_DEG), 'S');
+  if (!strcmp (op, "dcos"))   S_FUNC(cos (M1*RAD_DEG), 'S');
+  if (!strcmp (op, "dtan"))   S_FUNC(tan (M1*RAD_DEG), 'S');
+  if (!strcmp (op, "asin"))   S_FUNC(asin (M1), 'S');
+  if (!strcmp (op, "acos"))   S_FUNC(acos (M1), 'S');
+  if (!strcmp (op, "atan"))   S_FUNC(atan (M1), 'S');
+  if (!strcmp (op, "dasin"))  S_FUNC(asin (M1)*DEG_RAD, 'S');
+  if (!strcmp (op, "dacos"))  S_FUNC(acos (M1)*DEG_RAD, 'S');
+  if (!strcmp (op, "datan"))  S_FUNC(atan (M1)*DEG_RAD, 'S');
+  if (!strcmp (op, "rnd"))    S_FUNC(M1*0.0 + drand48(), 'S');
+  if (!strcmp (op, "not"))    S_FUNC(!(M1), 's');
+  if (!strcmp (op, "--"))     S_FUNC(-1*M1, 's'); // NOTE: opihi_int is signed, 
+  if (!strcmp (op, "isinf"))  S_FUNC(!finite(M1), 'S'); // XXX modify in future 
+  if (!strcmp (op, "isnan"))  S_FUNC(isnan(M1), 'S'); // XXX modify in future   
+
+# undef S_FUNC
+
+  clear_stack (V1);
+  sprintf (line, "error: op %s not defined!", op);
+  push_error (line);
+  return (FALSE);
 
 }
@@ -1286,61 +958,83 @@
 
   int i, Nx;
-  float *out, *M1;
   
   Nx = V1[0].vector[0].Nelements;
- 
-  if (V1[0].type == 'v') {  /** use V1 as temp buffer **/
-    OUT[0].vector = V1[0].vector;
-    V1[0].type = 'V'; /* prevent it from being freed below */
-  } else {  /* no spare temp buffer */
-    OUT[0].vector = InitVector ();
-    CopyVector (OUT[0].vector, V1[0].vector);
-  }
+
+  OUT[0].vector = InitVector ();
   OUT[0].type = 'v'; /*** <<--- says this is a temporary matrix ***/
-  M1  = V1[0].ptr;
-  out = OUT[0].ptr = (float *)OUT[0].vector[0].elements;
-
-  if (!strcmp (op, "="))     { } /* already set equal */
-  if (!strcmp (op, "abs"))   { for (i = 0; i < Nx; i++, out++, M1++) { *out = fabs(*M1);         }}
-  if (!strcmp (op, "int"))   { for (i = 0; i < Nx; i++, out++, M1++) { *out = (float)(int)(*M1); }}
-  if (!strcmp (op, "exp"))   { for (i = 0; i < Nx; i++, out++, M1++) { *out = exp(*M1);          }}
-  if (!strcmp (op, "ten"))   { for (i = 0; i < Nx; i++, out++, M1++) { *out = pow(10.0,*M1);     }}
-  if (!strcmp (op, "log"))   { for (i = 0; i < Nx; i++, out++, M1++) { *out = log10(*M1);        }}
-  if (!strcmp (op, "ln"))    { for (i = 0; i < Nx; i++, out++, M1++) { *out = log(*M1);          }}
-  if (!strcmp (op, "sqrt"))  { for (i = 0; i < Nx; i++, out++, M1++) { *out = sqrt(*M1);         }}
-  if (!strcmp (op, "erf"))   { for (i = 0; i < Nx; i++, out++, M1++) { *out = erf(*M1);          }}
-
-  if (!strcmp (op, "sinh"))   { for (i = 0; i < Nx; i++, out++, M1++) { *out = sinh(*M1);        }}
-  if (!strcmp (op, "cosh"))   { for (i = 0; i < Nx; i++, out++, M1++) { *out = cosh(*M1);        }}
-  if (!strcmp (op, "asinh"))  { for (i = 0; i < Nx; i++, out++, M1++) { *out = asinh(*M1);       }}
-  if (!strcmp (op, "acosh"))  { for (i = 0; i < Nx; i++, out++, M1++) { *out = acosh(*M1);       }}
-  if (!strcmp (op, "lgamma")) { for (i = 0; i < Nx; i++, out++, M1++) { *out = lgamma(*M1);      }}
-
-  if (!strcmp (op, "sin"))   { for (i = 0; i < Nx; i++, out++, M1++) { *out = sin(*M1);          }}
-  if (!strcmp (op, "cos"))   { for (i = 0; i < Nx; i++, out++, M1++) { *out = cos(*M1);          }}
-  if (!strcmp (op, "tan"))   { for (i = 0; i < Nx; i++, out++, M1++) { *out = tan(*M1);          }}
-  if (!strcmp (op, "dsin"))  { for (i = 0; i < Nx; i++, out++, M1++) { *out = sin(*M1*RAD_DEG);  }}
-  if (!strcmp (op, "dcos"))  { for (i = 0; i < Nx; i++, out++, M1++) { *out = cos(*M1*RAD_DEG);  }}
-  if (!strcmp (op, "dtan"))  { for (i = 0; i < Nx; i++, out++, M1++) { *out = tan(*M1*RAD_DEG);  }}
-  if (!strcmp (op, "asin"))  { for (i = 0; i < Nx; i++, out++, M1++) { *out = asin(*M1);         }}
-  if (!strcmp (op, "acos"))  { for (i = 0; i < Nx; i++, out++, M1++) { *out = acos(*M1);         }}
-  if (!strcmp (op, "atan"))  { for (i = 0; i < Nx; i++, out++, M1++) { *out = atan(*M1);         }}
-  if (!strcmp (op, "dasin")) { for (i = 0; i < Nx; i++, out++, M1++) { *out = asin(*M1)*DEG_RAD; }}
-  if (!strcmp (op, "dacos")) { for (i = 0; i < Nx; i++, out++, M1++) { *out = acos(*M1)*DEG_RAD; }}
-  if (!strcmp (op, "datan")) { for (i = 0; i < Nx; i++, out++, M1++) { *out = atan(*M1)*DEG_RAD; }}
-  if (!strcmp (op, "rnd"))   { for (i = 0; i < Nx; i++, out++, M1++) { *out = drand48();         }}
-  if (!strcmp (op, "ramp"))  { for (i = 0; i < Nx; i++, out++, M1++) { *out = i;                 }}
-  if (!strcmp (op, "zero"))  { for (i = 0; i < Nx; i++, out++, M1++) { *out = 0;                 }}
-  if (!strcmp (op, "not"))   { for (i = 0; i < Nx; i++, out++, M1++) { *out = !(*M1);            }}
-  if (!strcmp (op, "--"))    { for (i = 0; i < Nx; i++, out++, M1++) { *out = -(*M1);            }}
-  if (!strcmp (op, "isinf")) { for (i = 0; i < Nx; i++, out++, M1++) { *out = !finite(*M1);      }}
-  if (!strcmp (op, "isnan")) { for (i = 0; i < Nx; i++, out++, M1++) { *out = isnan(*M1);        }}
-
-  /* xramp and yramp only make sense in for matrices. for vectors, xramp = ramp, yramp = zero */
-  if (!strcmp (op, "xramp")) { for (i = 0; i < Nx; i++, out++, M1++) { *out = i;                 }}
-  if (!strcmp (op, "yramp")) { for (i = 0; i < Nx; i++, out++, M1++) { *out = 0;                 }}
+
+# define V_FUNC(OP,FTYPE) {					\
+    if (V1->vector->type == OPIHI_FLT) {			\
+      CopyVector (OUT[0].vector, V1[0].vector);			\
+      opihi_flt *M1  = V1[0].vector[0].elements.Flt;		\
+      opihi_flt *out = OUT[0].vector[0].elements.Flt;		\
+      for (i = 0; i < Nx; i++, out++, M1++) {			\
+	*out = OP;						\
+      }								\
+      clear_stack (V1);						\
+      return (TRUE);						\
+    }								\
+    if ((V1->vector->type == OPIHI_INT) && (FTYPE == 'S')) {	\
+      MatchVector (OUT[0].vector, V1[0].vector, OPIHI_FLT);	\
+      opihi_int *M1  = V1[0].vector[0].elements.Int;		\
+      opihi_flt *out = OUT[0].vector[0].elements.Flt;		\
+      for (i = 0; i < Nx; i++, out++, M1++) {			\
+	*out = OP;						\
+      }								\
+      clear_stack (V1);						\
+      return (TRUE);						\
+    }								\
+    if ((V1->vector->type == OPIHI_INT) && (FTYPE == 's')) {	\
+      CopyVector (OUT[0].vector, V1[0].vector);			\
+      opihi_int *M1  = V1[0].vector[0].elements.Int;		\
+      opihi_int *out = OUT[0].vector[0].elements.Int;		\
+      for (i = 0; i < Nx; i++, out++, M1++) {			\
+	*out = OP;						\
+      }								\
+      clear_stack (V1);						\
+      return (TRUE);						\
+    } }							
+
+  if (!strcmp (op, "="))      V_FUNC(*M1, 's');
+  if (!strcmp (op, "abs"))    V_FUNC(fabs(*M1), 's');
+  if (!strcmp (op, "int"))    V_FUNC((int)(*M1), 's');
+  if (!strcmp (op, "exp"))    V_FUNC(exp(*M1), 'S');
+  if (!strcmp (op, "ten"))    V_FUNC(pow(10.0,*M1), 'S');
+  if (!strcmp (op, "log"))    V_FUNC(log10(*M1), 'S');
+  if (!strcmp (op, "ln"))     V_FUNC(log(*M1), 'S');
+  if (!strcmp (op, "sqrt"))   V_FUNC(sqrt(*M1), 'S');
+  if (!strcmp (op, "erf"))    V_FUNC(erf(*M1), 'S');
+  if (!strcmp (op, "sinh"))   V_FUNC(sinh(*M1), 'S');
+  if (!strcmp (op, "cosh"))   V_FUNC(cosh(*M1), 'S');
+  if (!strcmp (op, "asinh"))  V_FUNC(asinh(*M1), 'S');
+  if (!strcmp (op, "acosh"))  V_FUNC(acosh(*M1), 'S');
+  if (!strcmp (op, "lgamma")) V_FUNC(lgamma(*M1), 'S');
+  if (!strcmp (op, "sin"))    V_FUNC(sin(*M1), 'S');
+  if (!strcmp (op, "cos"))    V_FUNC(cos(*M1), 'S');
+  if (!strcmp (op, "tan"))    V_FUNC(tan(*M1), 'S');
+  if (!strcmp (op, "dsin"))   V_FUNC(sin(*M1*RAD_DEG), 'S');
+  if (!strcmp (op, "dcos"))   V_FUNC(cos(*M1*RAD_DEG), 'S');
+  if (!strcmp (op, "dtan"))   V_FUNC(tan(*M1*RAD_DEG), 'S');
+  if (!strcmp (op, "asin"))   V_FUNC(asin(*M1), 'S');
+  if (!strcmp (op, "acos"))   V_FUNC(acos(*M1), 'S');
+  if (!strcmp (op, "atan"))   V_FUNC(atan(*M1), 'S');
+  if (!strcmp (op, "dasin"))  V_FUNC(asin(*M1)*DEG_RAD, 'S');
+  if (!strcmp (op, "dacos"))  V_FUNC(acos(*M1)*DEG_RAD, 'S');
+  if (!strcmp (op, "datan"))  V_FUNC(atan(*M1)*DEG_RAD, 'S');
+  if (!strcmp (op, "rnd"))    V_FUNC(drand48(), 'S');
+  if (!strcmp (op, "ramp"))   V_FUNC(i, 's');
+  if (!strcmp (op, "zero"))   V_FUNC(0, 's');
+  if (!strcmp (op, "not"))    V_FUNC(!(*M1), 's');
+  if (!strcmp (op, "--"))     V_FUNC(-1*(*M1), 's'); // NOTE: opihi_int is signed
+  if (!strcmp (op, "isinf"))  V_FUNC(!finite(*M1), 'S');
+  if (!strcmp (op, "isnan"))  V_FUNC(isnan(*M1), 'S');
+  if (!strcmp (op, "xramp"))  V_FUNC(i, 's');
+  if (!strcmp (op, "yramp"))  V_FUNC(0, 's');
+  /* xramp and yramp above only make sense for matrices. for vectors, xramp = ramp, yramp = zero */
+
+# undef V_FUNC
 
   if (V1[0].type == 'v') {
-    free (V1[0].vector[0].elements);
+    free (V1[0].vector[0].elements.Ptr);
     free (V1[0].vector);
     V1[0].vector = NULL;
@@ -1368,10 +1062,10 @@
   }
   OUT[0].type = 'm';      /*** <<--- says this is a temporary matrix ***/
-  M1  = V1[0].ptr;
-  out = OUT[0].ptr = (float *)OUT[0].buffer[0].matrix.buffer;
+  M1  = (float *) V1[0].buffer[0].matrix.buffer;
+  out = (float *)OUT[0].buffer[0].matrix.buffer;
 
   if (!strcmp (op, "="))     { }
   if (!strcmp (op, "abs"))   { for (i = 0; i < Nx*Ny; i++, out++, M1++) { *out = fabs(*M1);         }}
-  if (!strcmp (op, "int"))   { for (i = 0; i < Nx*Ny; i++, out++, M1++) { *out = (float)(int)(*M1); }}
+  if (!strcmp (op, "int"))   { for (i = 0; i < Nx*Ny; i++, out++, M1++) { *out = (opihi_flt)(int)(*M1); }}
   if (!strcmp (op, "exp"))   { for (i = 0; i < Nx*Ny; i++, out++, M1++) { *out = exp(*M1);          }}
   if (!strcmp (op, "ten"))   { for (i = 0; i < Nx*Ny; i++, out++, M1++) { *out = pow(10.0,*M1);     }}
@@ -1411,5 +1105,5 @@
     for (j = 0; j < Ny; j++) {
       for (i = 0; i < Nx; i++, out++, M1++) {
-        *out = i;
+	*out = i;
       }
     }
@@ -1418,5 +1112,5 @@
     for (j = 0; j < Ny; j++) {
       for (i = 0; i < Nx; i++, out++, M1++) {
-        *out = j;
+	*out = j;
       }
     }
Index: /trunk/Ohana/src/opihi/mana/findpeaks.c
===================================================================
--- /trunk/Ohana/src/opihi/mana/findpeaks.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/mana/findpeaks.c	(revision 20936)
@@ -76,13 +76,14 @@
   }
 
-  REALLOCATE (vecx[0].elements, float, MAX (Npeak, 1));
-  REALLOCATE (vecy[0].elements, float, MAX (Npeak, 1));
-  REALLOCATE (vecz[0].elements, float, MAX (Npeak, 1));
+  ResetVector (vecx, OPIHI_FLT, MAX (Npeak, 1));
+  ResetVector (vecy, OPIHI_FLT, MAX (Npeak, 1));
+  ResetVector (vecz, OPIHI_FLT, MAX (Npeak, 1));
+
   /* eliminate non-local peaks */
   for (N = n = 0; n < Npeak; n++) {
     if (!keep[n]) continue;
-    vecx[0].elements[N] = xp[n];
-    vecy[0].elements[N] = yp[n];
-    vecz[0].elements[N] = zp[n];
+    vecx[0].elements.Flt[N] = xp[n];
+    vecy[0].elements.Flt[N] = yp[n];
+    vecz[0].elements.Flt[N] = zp[n];
     N ++;
   }
@@ -92,7 +93,7 @@
   free (keep);
 
-  REALLOCATE (vecx[0].elements, float, MAX (N, 1));
-  REALLOCATE (vecy[0].elements, float, MAX (N, 1));
-  REALLOCATE (vecz[0].elements, float, MAX (N, 1));
+  REALLOCATE (vecx[0].elements.Flt, opihi_flt, MAX (N, 1));
+  REALLOCATE (vecy[0].elements.Flt, opihi_flt, MAX (N, 1));
+  REALLOCATE (vecz[0].elements.Flt, opihi_flt, MAX (N, 1));
   vecx[0].Nelements = vecy[0].Nelements = vecz[0].Nelements = N;
 
Index: /trunk/Ohana/src/opihi/mana/fitcontour.c
===================================================================
--- /trunk/Ohana/src/opihi/mana/fitcontour.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/mana/fitcontour.c	(revision 20936)
@@ -18,4 +18,8 @@
   yo = atof (argv[4]);
 
+  // require these to be float vectors
+  REQUIRE_VECTOR_FLT (vecx, FALSE);
+  REQUIRE_VECTOR_FLT (vecy, FALSE);
+
   ALLOCATE (B, double *, NTERM);
   ALLOCATE (C, double *, NTERM);
@@ -32,6 +36,6 @@
   */
   for (i = 0; i < vecx[0].Nelements; i++) {
-    x = vecx[0].elements[i] - xo;
-    y = vecy[0].elements[i] - yo;
+    x = vecx[0].elements.Flt[i] - xo;
+    y = vecy[0].elements.Flt[i] - yo;
     r = hypot (x, y);
 
Index: /trunk/Ohana/src/opihi/mana/rawstars.c
===================================================================
--- /trunk/Ohana/src/opihi/mana/rawstars.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/mana/rawstars.c	(revision 20936)
@@ -55,20 +55,17 @@
   Np = xp[0].Nelements;
 
-  REALLOCATE (xc[0].elements, float, Np);
-  REALLOCATE (yc[0].elements, float, Np);
-  REALLOCATE (sx[0].elements, float, Np);
-  REALLOCATE (sy[0].elements, float, Np);
-  REALLOCATE (sxy[0].elements, float, Np);
-  REALLOCATE (zs[0].elements, float, Np);
-  REALLOCATE (zc[0].elements, float, Np);
-  REALLOCATE (sk[0].elements, float, Np);
-  xc[0].Nelements = yc[0].Nelements = sx[0].Nelements = Np;
-  sy[0].Nelements = zs[0].Nelements = zc[0].Nelements = Np;
-  sxy[0].Nelements = sk[0].Nelements = Np;
+  ResetVector (xc, OPIHI_FLT, Np);
+  ResetVector (yc, OPIHI_FLT, Np);
+  ResetVector (sx, OPIHI_FLT, Np);
+  ResetVector (sy, OPIHI_FLT, Np);
+  ResetVector (sxy, OPIHI_FLT, Np);
+  ResetVector (zs, OPIHI_FLT, Np);
+  ResetVector (zc, OPIHI_FLT, Np);
+  ResetVector (sk, OPIHI_FLT, Np);
 
   v = (float *) buff[0].matrix.buffer;
   for (i = 0; i < Np; i++) {
-    x = xp[0].elements[i];
-    y = yp[0].elements[i];
+    x = (xp[0].type == OPIHI_FLT) ? xp[0].elements.Flt[i] : xp[0].elements.Int[i];
+    y = (yp[0].type == OPIHI_FLT) ? yp[0].elements.Flt[i] : yp[0].elements.Int[i];
     if (x < 0) continue;
     if (x >= Nx) continue;
@@ -77,12 +74,12 @@
 
     get_rough_star (v, Nx, Ny, x, y, 
-		    &xc[0].elements[i], 
-		    &yc[0].elements[i], 
-		    &sx[0].elements[i], 
-		    &sy[0].elements[i], 
-		    &sxy[0].elements[i], 
-		    &zs[0].elements[i], 
-		    &zc[0].elements[i],
-		    &sk[0].elements[i]);
+		    &xc[0].elements.Flt[i], 
+		    &yc[0].elements.Flt[i], 
+		    &sx[0].elements.Flt[i], 
+		    &sy[0].elements.Flt[i], 
+		    &sxy[0].elements.Flt[i], 
+		    &zs[0].elements.Flt[i], 
+		    &zc[0].elements.Flt[i],
+		    &sk[0].elements.Flt[i]);
   }
 
Index: /trunk/Ohana/src/opihi/mana/starcontour.c
===================================================================
--- /trunk/Ohana/src/opihi/mana/starcontour.c	(revision 20935)
+++ /trunk/Ohana/src/opihi/mana/starcontour.c	(revision 20936)
@@ -22,6 +22,6 @@
   N = 0;
   Npts = 100;
-  REALLOCATE (vecx[0].elements, float, MAX (Npts, 1));
-  REALLOCATE (vecy[0].elements, float, MAX (Npts, 1));
+  ResetVector (vecx, OPIHI_FLT, MAX (Npts, 1));
+  ResetVector (vecy, OPIHI_FLT, MAX (Npts, 1));
 
   Nx = buf[0].matrix.Naxis[0];
@@ -41,11 +41,11 @@
 	min = TRUE;
 	xmin = x + (zo - zt)/(v[x + 1 + y*Nx] - zt);
-	vecx[0].elements[N] = xmin;
-	vecy[0].elements[N] = y;
+	vecx[0].elements.Flt[N] = xmin;
+	vecy[0].elements.Flt[N] = y;
 	N ++;
 	if (N >= Npts) {
 	  Npts += 100;
-	  REALLOCATE (vecx[0].elements, float, MAX (Npts, 1));
-	  REALLOCATE (vecy[0].elements, float, MAX (Npts, 1));
+	  REALLOCATE (vecx[0].elements.Flt, opihi_flt, MAX (Npts, 1));
+	  REALLOCATE (vecy[0].elements.Flt, opihi_flt, MAX (Npts, 1));
 	}
       }
@@ -59,11 +59,11 @@
 	max = TRUE;
 	xmax = x - (zo - zt)/(v[x - 1 + y*Nx] - zt);
-	vecx[0].elements[N] = xmax;
-	vecy[0].elements[N] = y;
+	vecx[0].elements.Flt[N] = xmax;
+	vecy[0].elements.Flt[N] = y;
 	N ++;
 	if (N >= Npts) {
 	  Npts += 100;
-	  REALLOCATE (vecx[0].elements, float, MAX (Npts, 1));
-	  REALLOCATE (vecy[0].elements, float, MAX (Npts, 1));
+	  REALLOCATE (vecx[0].elements.Flt, opihi_flt, MAX (Npts, 1));
+	  REALLOCATE (vecy[0].elements.Flt, opihi_flt, MAX (Npts, 1));
 	}
       }
@@ -86,11 +86,11 @@
 	min = TRUE;
 	xmin = x + (zo - zt)/(v[x + 1 + y*Nx] - zt);
-	vecx[0].elements[N] = xmin;
-	vecy[0].elements[N] = y;
+	vecx[0].elements.Flt[N] = xmin;
+	vecy[0].elements.Flt[N] = y;
 	N ++;
 	if (N >= Npts) {
 	  Npts += 100;
-	  REALLOCATE (vecx[0].elements, float, MAX (Npts, 1));
-	  REALLOCATE (vecy[0].elements, float, MAX (Npts, 1));
+	  REALLOCATE (vecx[0].elements.Flt, opihi_flt, MAX (Npts, 1));
+	  REALLOCATE (vecy[0].elements.Flt, opihi_flt, MAX (Npts, 1));
 	}
       }
@@ -104,11 +104,11 @@
 	max = TRUE;
 	xmax = x - (zo - zt)/(v[x - 1 + y*Nx] - zt);
-	vecx[0].elements[N] = xmax;
-	vecy[0].elements[N] = y;
+	vecx[0].elements.Flt[N] = xmax;
+	vecy[0].elements.Flt[N] = y;
 	N ++;
 	if (N >= Npts) {
 	  Npts += 100;
-	  REALLOCATE (vecx[0].elements, float, MAX (Npts, 1));
-	  REALLOCATE (vecy[0].elements, float, MAX (Npts, 1));
+	  REALLOCATE (vecx[0].elements.Flt, opihi_flt, MAX (Npts, 1));
+	  REALLOCATE (vecy[0].elements.Flt, opihi_flt, MAX (Npts, 1));
 	}
       }
Index: /trunk/Ohana/src/relphot/src/GridOps.c
===================================================================
--- /trunk/Ohana/src/relphot/src/GridOps.c	(revision 20935)
+++ /trunk/Ohana/src/relphot/src/GridOps.c	(revision 20936)
@@ -261,4 +261,5 @@
 	fprintf (stderr, "\n");
     }
+    return (TRUE);
 }
 
@@ -286,7 +287,7 @@
 
   int **gotstar, **gridmeas;
-  int i, j, k, N, Nmax, Ngood, Nbad, Nmos, Ncal, Nrel, Nsys, Nfit;
+  int i, j, k, N, Ngood, Nbad, Nmos, Ncal, Nrel, Nsys;
   double **A, **B, *Mjx, *Wjx;
-  float Msys, Mrel, Mcal, Mmos, Merr, Wsys;
+  float Msys, Mcal, Mmos, Merr, Wsys;
   double Mj, Wj;
   
@@ -449,5 +450,5 @@
 
     FILE *f;
-    Header header, theader;
+    Header theader;
     Matrix matrix;
 
Index: /trunk/Ohana/src/relphot/src/ImageOps.c
===================================================================
--- /trunk/Ohana/src/relphot/src/ImageOps.c	(revision 20935)
+++ /trunk/Ohana/src/relphot/src/ImageOps.c	(revision 20936)
@@ -166,6 +166,6 @@
 void matchImage (Catalog *catalog, int meas, int cat) {
 
-  int i, ave, ccdnum;
-  double ra, dec, X, Y;
+  int i, ccdnum;
+  double X, Y;
   char *pname, *filter, *p, base[256];
   Measure *measure;
@@ -191,4 +191,6 @@
 	 and nn is an integer -> ccdnum */
       
+      /// XXX we have an inconsistency here wrt dvo.layout and dvo.photcode
+
       while (!isdigit(*p) && *p) p++;
       if (*p == 0) continue;
Index: /trunk/Ohana/src/relphot/src/StarOps.c
===================================================================
--- /trunk/Ohana/src/relphot/src/StarOps.c	(revision 20935)
+++ /trunk/Ohana/src/relphot/src/StarOps.c	(revision 20936)
@@ -547,5 +547,4 @@
   double *xlist, *Mlist;
   Graphdata graphdata;
-  char *filename, tmp;
 
 # define NBIN 200
Index: /trunk/Ohana/src/skycalc/src/astro.c
===================================================================
--- /trunk/Ohana/src/skycalc/src/astro.c	(revision 20935)
+++ /trunk/Ohana/src/skycalc/src/astro.c	(revision 20936)
@@ -106,5 +106,5 @@
 
   double incl;
-  double xpr,ypr,zpr;
+  double ypr,zpr;
   double T;
 
@@ -141,5 +141,4 @@
 double SC_etcorr (double jd) {
 
-  double jd1900 = 2415019.5;
   double dates[20] = {1900,1905,1910,1915,1920,1925,1930,1935,1940,1945,
 		      1950,1955,1960,1965,1970,1975,1980,1985,1990,1993};
Index: /trunk/Ohana/src/skycalc/src/dusktime.c
===================================================================
--- /trunk/Ohana/src/skycalc/src/dusktime.c	(revision 20935)
+++ /trunk/Ohana/src/skycalc/src/dusktime.c	(revision 20936)
@@ -13,5 +13,5 @@
 }
 
-main (int argc, char **argv) {
+int main (int argc, char **argv) {
 
   struct SC_date_time date, tmpdate;
@@ -59,5 +59,5 @@
 
   if (VERBOSE) {
-    jd_to_date (jdnow, &tmpdate);
+    SC_jd_to_date (jdnow, &tmpdate);
     fprintf (stderr, "%4d/%02d/%02d %02d:%02d:%02f\n", tmpdate.y, tmpdate.mo, tmpdate.d, tmpdate.h, tmpdate.mn, tmpdate.s);
   }
Index: /trunk/Ohana/src/skycalc/src/geometry.c
===================================================================
--- /trunk/Ohana/src/skycalc/src/geometry.c	(revision 20935)
+++ /trunk/Ohana/src/skycalc/src/geometry.c	(revision 20936)
@@ -8,5 +8,4 @@
    double mod;    /* modulus */
    double xy;     /* component in xy plane */
-   short sign;    /* for determining quadrant */
    double radian_ra, radian_dec;
 
Index: /trunk/Ohana/src/skycalc/src/moon.c
===================================================================
--- /trunk/Ohana/src/skycalc/src/moon.c	(revision 20935)
+++ /trunk/Ohana/src/skycalc/src/moon.c	(revision 20936)
@@ -368,7 +368,6 @@
   double geora, geodec, geodist;  /* geocent for moon, not used here.*/
   double ramoon, decmoon, distmoon;
-  double hamoonrise, hamoonset, tmoonrise, tmoonset, jdmoonrise, jdmoonset;
-  short dow; /* day of week */
-  struct SC_date_time date_midnight, tmpdate;
+  double hamoonset, tmoonset, jdmoonset;
+  struct SC_date_time date_midnight;
   double dt, lst0, lst1, djd, horiz;
 
@@ -420,7 +419,6 @@
   double geora, geodec, geodist;  /* geocent for moon, not used here.*/
   double ramoon, decmoon, distmoon;
-  double hamoonrise, hamoonset, tmoonrise, tmoonset, jdmoonrise, jdmoonset;
-  short dow; /* day of week */
-  struct SC_date_time date_midnight, tmpdate;
+  double hamoonset, tmoonrise, jdmoonrise;
+  struct SC_date_time date_midnight;
   double dt, lst0, lst1, djd, horiz;
 
Index: /trunk/Ohana/src/skycalc/src/moondata.c
===================================================================
--- /trunk/Ohana/src/skycalc/src/moondata.c	(revision 20935)
+++ /trunk/Ohana/src/skycalc/src/moondata.c	(revision 20936)
@@ -12,7 +12,7 @@
 }
 
-main (int argc, char **argv) {
+int main (int argc, char **argv) {
 
-  struct SC_date_time date, tmpdate;
+  struct SC_date_time date;
   double longit, lat, elevsea, elev;
   double jdnow, ra, dec, sid;
Index: /trunk/Ohana/src/skycalc/src/sun.c
===================================================================
--- /trunk/Ohana/src/skycalc/src/sun.c	(revision 20935)
+++ /trunk/Ohana/src/skycalc/src/sun.c	(revision 20936)
@@ -5,5 +5,5 @@
 void SC_lpsun (double jd, double *ra, double *dec) {
 
-  double n, L, g, lambda,epsilon,alpha,delta,x,y,z;
+  double n, L, g, lambda,epsilon,x,y,z;
 
   n = jd - J2000;
@@ -54,14 +54,13 @@
 }
 
-/* Given site position, prints Sun info for the given night.
+/* Given site position, prints Sun info for the given night. */
 /* dates are all in UT now */
 double SC_sunset_tonight (struct SC_date_time date, double lat, double longit, double elev) {
 
   double jd, jdmid0, jdmid, stmid;
-  double rasun, decsun, min_alt, max_alt, horiz;
-  double hasunset, jdsunset, jdsunrise, sid;
+  double rasun, decsun, horiz;
+  double hasunset, jdsunset;
   double dt, lst0, lst1, djd;
-  struct SC_date_time date_midnight, tmpdate;
-  short dow;
+  struct SC_date_time date_midnight;
 
   horiz = sqrt (2. * elev / 6378140.) * DEG_IN_RADIAN;
@@ -106,14 +105,13 @@
 }
 
-/* Given site position, prints Sun info for the given night.
+/* Given site position, prints Sun info for the given night. */
 /* dates are all in UT now */
 double SC_sunrise_tonight (struct SC_date_time date, double lat, double longit, double elev) {
 
   double jd, jdmid, stmid;
-  double rasun, decsun, min_alt, max_alt, horiz;
-  double hasunset, jdsunset, jdsunrise, sid;
+  double rasun, decsun, horiz;
+  double hasunset, jdsunrise;
   double dt, lst0, lst1, djd;
-  struct SC_date_time date_midnight, tmpdate;
-  short dow;
+  struct SC_date_time date_midnight;
 
   horiz = sqrt (2. * elev / 6378140.) * DEG_IN_RADIAN;
Index: /trunk/Ohana/src/skycalc/src/sundata.c
===================================================================
--- /trunk/Ohana/src/skycalc/src/sundata.c	(revision 20935)
+++ /trunk/Ohana/src/skycalc/src/sundata.c	(revision 20936)
@@ -12,12 +12,11 @@
 }
 
-main (int argc, char **argv) {
+int main (int argc, char **argv) {
 
-  struct SC_date_time date, tmpdate;
+  struct SC_date_time date;
   double longit, lat, elevsea, elev;
-  double jdnow, ra, dec, sid, alt, az, sind, sinh, cosh;
-  double geora, geodec, geodist, dist;
+  double jdnow, sid, alt, az, sind, sinh, cosh;
   double RAo, DECo, abx, aby, abz, cs, theta;
-  double Rsun, Dsun, days, Hsun;
+  double Rsun, Dsun, Hsun;
   time_t tzero;
   struct tm *stm;
Index: /trunk/Ohana/src/skycalc/src/sunmoon.c
===================================================================
--- /trunk/Ohana/src/skycalc/src/sunmoon.c	(revision 20935)
+++ /trunk/Ohana/src/skycalc/src/sunmoon.c	(revision 20936)
@@ -9,8 +9,8 @@
 double angular_separation (double ra, double dec, double RA, double DEC);
 
-main (int argc, char **argv) {
+int main (int argc, char **argv) {
 
   int N;
-  struct SC_date_time date, tmpdate;
+  struct SC_date_time date;
   double longitude, latitude, elevation;
   double jdnow, sid;
Index: /trunk/Ohana/src/skycalc/src/time.c
===================================================================
--- /trunk/Ohana/src/skycalc/src/time.c	(revision 20935)
+++ /trunk/Ohana/src/skycalc/src/time.c	(revision 20936)
@@ -6,6 +6,4 @@
   time_t t;
   struct tm *stm;
-  double jd, jdb, jde;
-  short dow;
   
   t = time (0);
@@ -109,5 +107,5 @@
 double SC_lst (double jd, double longit) {
   
-  double t, ut, jdmid, jdint, jdfrac, sid_g, sid;
+  double t, ut, jdmid, jdint, jdfrac, sid_g;
   long sid_int;
   
