Index: trunk/Ohana/src/opihi/cmd.astro/gauss.c
===================================================================
--- trunk/Ohana/src/opihi/cmd.astro/gauss.c	(revision 36671)
+++ trunk/Ohana/src/opihi/cmd.astro/gauss.c	(revision 36679)
@@ -10,4 +10,15 @@
   Buffer *buf;
   KapaImageData data;
+  int VERBOSE;
+
+  VERBOSE = TRUE;
+  if ((N = get_argument (argc, argv, "-q"))) {
+    VERBOSE = FALSE;
+    remove_argument (N, &argc, argv);
+  }
+  if ((N = get_argument (argc, argv, "-quiet"))) {
+    VERBOSE = FALSE;
+    remove_argument (N, &argc, argv);
+  }
 
   name = NULL;
@@ -58,5 +69,5 @@
     KiiCursorRead (kapa, &X, &Y, &ZP, &RA, &DEC, key);
     if (!strcasecmp (key, "Q")) break;
-    get_aperture_stats (&buf[0].matrix, (int)(X+0.5), (int)(Y+0.5), Npix, Nborder, max);
+    get_aperture_stats (&buf[0].matrix, (int)(X+0.5), (int)(Y+0.5), Npix, Nborder, max, VERBOSE);
   }
   KiiCursorOff (kapa);
@@ -64,2 +75,3 @@
 }
 
+
Index: trunk/Ohana/src/opihi/cmd.astro/star.c
===================================================================
--- trunk/Ohana/src/opihi/cmd.astro/star.c	(revision 36671)
+++ trunk/Ohana/src/opihi/cmd.astro/star.c	(revision 36679)
@@ -6,4 +6,15 @@
   double max;
   Buffer *buf;
+  int VERBOSE;
+
+  VERBOSE = TRUE;
+  if ((N = get_argument (argc, argv, "-q"))) {
+    VERBOSE = FALSE;
+    remove_argument (N, &argc, argv);
+  }
+  if ((N = get_argument (argc, argv, "-quiet"))) {
+    VERBOSE = FALSE;
+    remove_argument (N, &argc, argv);
+  }
 
   Nborder = 3;
@@ -36,5 +47,5 @@
   }
 
-  get_aperture_stats (&buf[0].matrix, x, y, dx, Nborder, max);
+  get_aperture_stats (&buf[0].matrix, x, y, dx, Nborder, max, VERBOSE);
   
   return (TRUE);
Index: trunk/Ohana/src/opihi/cmd.data/Makefile
===================================================================
--- trunk/Ohana/src/opihi/cmd.data/Makefile	(revision 36671)
+++ trunk/Ohana/src/opihi/cmd.data/Makefile	(revision 36679)
@@ -64,4 +64,5 @@
 $(SRC)/imcut.$(ARCH).o	 	\
 $(SRC)/imhist.$(ARCH).o	\
+$(SRC)/impeaks.$(ARCH).o	\
 $(SRC)/imsmooth.$(ARCH).o	\
 $(SRC)/imsmooth.generic.$(ARCH).o	\
@@ -88,4 +89,6 @@
 $(SRC)/mget.$(ARCH).o		\
 $(SRC)/minterpolate.$(ARCH).o	\
+$(SRC)/medimage.$(ARCH).o	\
+$(SRC)/medimage_commands.$(ARCH).o \
 $(SRC)/mset.$(ARCH).o		\
 $(SRC)/peak.$(ARCH).o		\
Index: trunk/Ohana/src/opihi/cmd.data/impeaks.c
===================================================================
--- trunk/Ohana/src/opihi/cmd.data/impeaks.c	(revision 36679)
+++ trunk/Ohana/src/opihi/cmd.data/impeaks.c	(revision 36679)
@@ -0,0 +1,113 @@
+# include "data.h"
+
+float *findPeaksInRow (Buffer *buff, int y, float threshold, float *peaks, int *npeaks);
+
+int impeaks (int argc, char **argv) {
+  
+  int iy, n;
+  Vector *vecx, *vecy, *vecf;
+  Buffer *buff;
+
+  if (argc != 6) {
+    gprint (GP_ERR, "USAGE: impeaks (buffer) <xvec> <yvec> <fvec> <threshold>\n");
+    return (FALSE);
+  }
+
+  if ((buff = SelectBuffer (argv[1], OLDBUFFER, TRUE)) == NULL) return (FALSE);
+  if ((vecx = SelectVector (argv[2], ANYVECTOR, TRUE)) == NULL) return (FALSE);
+  if ((vecy = SelectVector (argv[3], ANYVECTOR, TRUE)) == NULL) return (FALSE);
+  if ((vecf = SelectVector (argv[4], ANYVECTOR, TRUE)) == NULL) return (FALSE);
+
+  float threshold = atof (argv[5]);
+
+  // we find the peaks in the image by looking for peaks in each row, then checking their neighboring pixels
+
+  float *image = (float *) buff[0].matrix.buffer;
+  int Nx = buff[0].matrix.Naxis[0];
+  int Ny = buff[0].matrix.Naxis[1];
+
+  // we will use this vector for each row (allocated first pass only)
+  float *rowPeaks = NULL;
+
+  int Npeak = 0;
+  int NPEAK = 1000;
+  opihi_flt *peakX = NULL;
+  opihi_flt *peakY = NULL;
+  opihi_flt *peakF = NULL;
+  ALLOCATE (peakX, opihi_flt, NPEAK);
+  ALLOCATE (peakY, opihi_flt, NPEAK);
+  ALLOCATE (peakF, opihi_flt, NPEAK);
+
+  // exclude peaks on the outer edge
+  for (iy = 1; iy < Ny; iy++) {
+    
+    int iyn = iy - 1;
+    int iyp = iy + 1;
+
+    int nRowPeaks;
+    rowPeaks = findPeaksInRow (buff, iy, threshold, rowPeaks, &nRowPeaks);
+
+    // each each of the row peaks to see if it is an image peak
+
+    for (n = 0; n < nRowPeaks; n++) {
+      int ix = rowPeaks[n];
+      int ixn = ix - 1;
+      int ixp = ix + 1;
+      
+      float value = image[ix + iy*Nx];
+
+      // I know ix,iy is a peak in the row, is it above the neighbors in the previous and next rows?
+      if (value <= image[ix  + iyn*Nx]) continue;
+      if (value <  image[ix  + iyp*Nx]) continue;
+      if (value <  image[ixn + iyn*Nx]) continue;
+      if (value <= image[ixn + iyp*Nx]) continue;
+      if (value <  image[ixp + iyn*Nx]) continue;
+      if (value <= image[ixp + iyp*Nx]) continue;
+
+      peakX[Npeak] = ix;
+      peakY[Npeak] = iy;
+      peakF[Npeak] = value;
+      Npeak ++;
+      if (Npeak == NPEAK) {
+	NPEAK += 100;
+	REALLOCATE (peakX, opihi_flt, NPEAK);
+	REALLOCATE (peakY, opihi_flt, NPEAK);
+	REALLOCATE (peakF, opihi_flt, NPEAK);
+      }
+    }
+
+  }
+
+  free (vecx->elements.Flt); vecx->elements.Flt = peakX; vecx->Nelements = Npeak;
+  free (vecy->elements.Flt); vecy->elements.Flt = peakY; vecy->Nelements = Npeak;
+  free (vecf->elements.Flt); vecf->elements.Flt = peakF; vecf->Nelements = Npeak;
+
+  return (TRUE);
+}
+
+// skip the first and last pixel
+float *findPeaksInRow (Buffer *buff, int y, float threshold, float *peaks, int *npeaks) {
+
+  int ix;
+
+  int Nx = buff[0].matrix.Naxis[0];
+
+  float *row = (float *) buff[0].matrix.buffer + Nx*y;
+
+  if (peaks == NULL) {
+    ALLOCATE (peaks, float, Nx);
+  }
+  int Npeaks = 0;
+  for (ix = 1; ix < Nx - 1; ix++) {
+    if (row[ix] <  threshold) continue;   // only accept pixels above threshold
+    if (row[ix] <  row[ix - 1]) continue; // peak pixel must be at least preceeding pixel
+    if (row[ix] <= row[ix + 1]) continue; // we accept the last pixel of a series of equal values
+    
+    peaks[Npeaks] = ix;
+    Npeaks ++;
+  }
+
+  *npeaks = Npeaks;
+  return peaks;
+}
+    
Index: trunk/Ohana/src/opihi/cmd.data/init.c
===================================================================
--- trunk/Ohana/src/opihi/cmd.data/init.c	(revision 36671)
+++ trunk/Ohana/src/opihi/cmd.data/init.c	(revision 36679)
@@ -53,4 +53,5 @@
 int imcut            PROTO((int, char **));
 int imhist           PROTO((int, char **));
+int impeaks          PROTO((int, char **));
 int imsmooth         PROTO((int, char **));
 int imsmooth_generic PROTO((int, char **));
@@ -78,4 +79,5 @@
 int mget             PROTO((int, char **));
 int minterp          PROTO((int, char **));
+int medimage_command PROTO((int, char **));
 int mset             PROTO((int, char **));
 int peak             PROTO((int, char **));
@@ -211,4 +213,5 @@
   {1, "imcut",        imcut,            "linear image cut between arbitrary coords"},
   {1, "imhistogram",  imhist,           "histogram of an image region"},
+  {1, "impeaks",      impeaks,          "find peaks in an image (return vectors)"},
   {1, "imsmooth",     imsmooth,         "circular gaussian smoothing"},
   {1, "imsmooth.generic", imsmooth_generic, "circular non-gaussian smoothing"},
@@ -233,4 +236,5 @@
   {1, "minterp",      minterp,          "interpolate image pixels"},
   {1, "iminterp",     minterp,          "interpolate image pixels"},
+  {1, "medimage",     medimage_command, "median image manipulation"},
   {1, "matrix",       matrix,           "matrix math operations"},
   {1, "match2d",      match2d,          "match 2 pairs of X,Y vectors and return matched indexes"},
Index: trunk/Ohana/src/opihi/cmd.data/medimage.c
===================================================================
--- trunk/Ohana/src/opihi/cmd.data/medimage.c	(revision 36679)
+++ trunk/Ohana/src/opihi/cmd.data/medimage.c	(revision 36679)
@@ -0,0 +1,53 @@
+# include "data.h"
+
+int medimage_help (int argc, char **argv);
+int medimage_list (int argc, char **argv);
+int medimage_add (int argc, char **argv);
+int medimage_calc (int argc, char **argv);
+int medimage_delete (int argc, char **argv);
+int medimage_rename (int argc, char **argv);
+
+static Command medimage_commands[] = {
+  {1, "help",       medimage_help,       "list medimage help info"},
+  {1, "list",       medimage_list,       "list medimages"},
+  {1, "add",        medimage_add,        "add an image to the given medimage (creates new one if needed)"},
+  {1, "calc",       medimage_calc,       "measure the median image and save to a buffer"},
+  {1, "delete",     medimage_delete,     "delete a medimage"},
+  {1, "rename",     medimage_rename,     "rename a medimage"},
+};
+
+int medimage_help (int argc, char **argv) {
+
+  gprint (GP_ERR, "USAGE: medimage (command)\n");
+  gprint (GP_ERR, "    medimage help                       : this listing\n");
+  gprint (GP_ERR, "    medimage list                       : list medimages\n");
+  gprint (GP_ERR, "    medimage add    (medimage) (image)  : add the given image to a medimage\n");
+  gprint (GP_ERR, "    medimage calc   (medimage) (output) : calculate the median image\n");
+  gprint (GP_ERR, "    medimage delete (medimage)          : delete named medimage\n");
+  gprint (GP_ERR, "    medimage rename (medimage) (new)    : change medimage name to new name\n");
+
+  return FALSE;
+}
+
+int medimage_command (int argc, char **argv) {
+
+  int i, N, status;
+
+  if (argc < 2) {
+    medimage_help(0,NULL);
+    return (FALSE);
+  }
+
+  N = sizeof (medimage_commands) / sizeof (Command);
+
+  /* find the medimage sub-command which matches */
+  for (i = 0; i < N; i++) {
+    if (!strcmp (medimage_commands[i].name, argv[1])) {
+      status = (*medimage_commands[i].func) (argc - 1, argv + 1);
+      return (status);
+    }
+  }
+
+  gprint (GP_ERR, "unknown medimage command %s\n", argv[1]);
+  return (FALSE);
+}
Index: trunk/Ohana/src/opihi/cmd.data/medimage_commands.c
===================================================================
--- trunk/Ohana/src/opihi/cmd.data/medimage_commands.c	(revision 36679)
+++ trunk/Ohana/src/opihi/cmd.data/medimage_commands.c	(revision 36679)
@@ -0,0 +1,186 @@
+# include "data.h"
+
+int medimage_list (int argc, char **argv) {
+  if (argc != 1) {
+    gprint (GP_ERR, "USAGE: medimage list\n");
+    return FALSE;
+  }
+
+  ListMedImages();
+  return TRUE;
+}
+
+int medimage_add (int argc, char **argv) {
+
+  Buffer *image;
+
+  if (argc != 3) {
+    gprint (GP_ERR, "USAGE: medimage add (name) (image)\n");
+    gprint (GP_ERR, "       add the given image to the set of images to be medianed\n");
+    return FALSE;
+  }
+
+  if ((image = SelectBuffer (argv[2], OLDBUFFER, TRUE)) == NULL) return (FALSE);
+
+  MedImageType *median = FindMedImage (argv[1]);
+  if (!median) {
+    // create a new median with this name
+    median = CreateMedImage (argv[1], image->matrix.Naxis[0], image->matrix.Naxis[1]);
+    if (!median) {
+      gprint (GP_ERR, "failed to generate a new median image\n");
+      return FALSE;
+    }
+  }
+
+  if (median->Nx != image->matrix.Naxis[0]) {
+    gprint (GP_ERR, "image does not match medimage dimensions\n");
+    return FALSE;
+  }
+  if (median->Ny != image->matrix.Naxis[1]) {
+    gprint (GP_ERR, "image does not match medimage dimensions\n");
+    return FALSE;
+  }
+
+  // new image should match existing medimage dimensions
+
+  int Ninput = median->Ninput;
+  median->Ninput ++;
+  REALLOCATE (median->buffers, float *, median->Ninput);
+
+  ALLOCATE (median->buffers[Ninput], float, median->Nx*median->Ny);
+  memcpy (median->buffers[Ninput], image->matrix.buffer, sizeof(float)*median->Nx*median->Ny);
+
+  return TRUE;
+}
+
+int medimage_calc (int argc, char **argv) {
+
+  int ix, iy, n;
+  Buffer *output;
+
+  if (argc != 3) {
+    gprint (GP_ERR, "USAGE: medimage calc (name) (output)\n");
+    gprint (GP_ERR, "       calculate the median image for the median image set\n");
+    return FALSE;
+  }
+
+  MedImageType *median = FindMedImage (argv[1]);
+  if (!median) {
+    gprint (GP_ERR, "median image %s not found\n", argv[1]);
+    return FALSE;
+  }
+
+  if ((output = SelectBuffer (argv[2], ANYBUFFER, TRUE)) == NULL) return (FALSE);
+
+  int Ninput = median->Ninput;
+  int Nx = median->Nx;
+  int Ny = median->Ny;
+
+  float *value = NULL;
+  ALLOCATE (value, float, Ninput);
+
+  gfits_free_matrix (&output->matrix);
+  gfits_free_header (&output->header);
+  CreateBuffer (output, Nx, Ny, -32, 0.0, 1.0);
+
+  float *outvalue = (float *) output->matrix.buffer;
+
+  for (iy = 0; iy < Ny; iy++) {
+    for (ix = 0; ix < Nx; ix++) {
+
+      int N = 0;
+      int Npix = ix + Nx*iy;
+      for (n = 0; n < Ninput; n++) {
+	float v = median->buffers[n][Npix];
+	if (!isfinite(v)) continue;
+	value[N] = v;
+	N++;
+      }
+      if (N == 0) continue;
+
+      fsort (value, N);
+      outvalue[Npix] = value[(int)(0.5*N)];
+    }
+  }
+
+  return TRUE;
+}
+
+/* 
+int medimage_save (int argc, char **argv) {
+
+  int N;
+
+  int APPEND = FALSE;
+  if ((N = get_argument (argc, argv, "-append"))) {
+    APPEND = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+
+  if (argc != 3) {
+    gprint (GP_ERR, "USAGE: medimage save (name) (filename) [-append]\n");
+    return FALSE;
+  }
+
+  if (!SaveMedImage(argv[2], argv[1], APPEND)) {
+    gprint (GP_ERR, "failed to save medimage %s\n", argv[1]);
+    return (FALSE);
+  }
+  return TRUE;
+}
+
+int medimage_load (int argc, char **argv) {
+
+  if (argc != 3) {
+    gprint (GP_ERR, "USAGE: medimage load (name) (filename)\n");
+    return FALSE;
+  }
+
+  if (!LoadMedImage(argv[2], argv[1])) {
+    gprint (GP_ERR, "failed to load medimage %s\n", argv[1]);
+    return (FALSE);
+  }
+  return TRUE;
+}
+*/
+
+int medimage_delete (int argc, char **argv) {
+
+  int status;
+  MedImageType *medimage;
+
+  if (argc != 2) {
+    gprint (GP_ERR, "USAGE: medimage delete (medimage)\n");
+    return FALSE;
+  }
+
+  medimage = FindMedImage (argv[1]);
+  if (medimage == NULL) {
+    gprint (GP_ERR, "medimage %s not found\n", argv[1]);
+    return FALSE;
+  }
+
+  status = DeleteMedImage (medimage);
+  if (!status) abort ();
+  return TRUE;
+}
+
+int medimage_rename (int argc, char **argv) {
+
+  MedImageType *medimage;
+
+  if (argc != 3) {
+    gprint (GP_ERR, "USAGE: medimage rename (medimage) (newname)\n");
+    return FALSE;
+  }
+
+  medimage = FindMedImage (argv[1]);
+  if (medimage == NULL) {
+    gprint (GP_ERR, "medimage %s not found\n", argv[1]);
+    return FALSE;
+  }
+
+  free (medimage->name);
+  medimage->name = strcreate (argv[2]);
+  return TRUE;
+}
Index: trunk/Ohana/src/opihi/cmd.data/rebin.c
===================================================================
--- trunk/Ohana/src/opihi/cmd.data/rebin.c	(revision 36671)
+++ trunk/Ohana/src/opihi/cmd.data/rebin.c	(revision 36679)
@@ -133,4 +133,5 @@
 	      *Vout += *Vin;
 	      if (Normalize) {(*Vn) ++;}
+	      // if ((i == 1) && (j == 1)) fprintf (stderr, "%d,%d : %d,%d : %f : %f : %d\n", i, j, x, y, *Vin, *Vout, *Vn);
 	    }
 	    if (Normalize) {Vn ++;}
Index: trunk/Ohana/src/opihi/cmd.data/test/medimage.sh
===================================================================
--- trunk/Ohana/src/opihi/cmd.data/test/medimage.sh	(revision 36679)
+++ trunk/Ohana/src/opihi/cmd.data/test/medimage.sh	(revision 36679)
@@ -0,0 +1,11 @@
+
+macro go
+ mcreate a 30 30
+ for i 0 40
+  set a$i = zero(a) + $i
+ end
+
+ for i 0 40
+  medimage add t1 a$i
+ end
+end
Index: trunk/Ohana/src/opihi/cmd.data/vellipse.c
===================================================================
--- trunk/Ohana/src/opihi/cmd.data/vellipse.c	(revision 36671)
+++ trunk/Ohana/src/opihi/cmd.data/vellipse.c	(revision 36679)
@@ -228,4 +228,5 @@
  */
 
+// XXX NOTE that PHI is defined with the wrong sign, should fix this...
 opihi_flt fellipseOD (opihi_flt alpha, opihi_flt *par, int Npar, opihi_flt *dpar) {
   
Index: trunk/Ohana/src/opihi/include/data.h
===================================================================
--- trunk/Ohana/src/opihi/include/data.h	(revision 36671)
+++ trunk/Ohana/src/opihi/include/data.h	(revision 36679)
@@ -33,4 +33,21 @@
   char **pageIDs;
 } Book;
+
+// the interpolating spline has valu
+typedef struct {
+  int Nknots;
+  opihi_flt *xk;
+  opihi_flt *yk;
+  opihi_flt *y2;
+  char *name;
+} Spline;
+
+typedef struct {
+  char *name;
+  int Ninput;
+  int Nx;
+  int Ny;
+  float **buffers;
+} MedImageType;
 
 void InitData (void);
@@ -144,5 +161,5 @@
 
 /* starfuncs.c */
-double get_aperture_stats (Matrix *matrix, int X, int Y, int Npix, int Nborder, double max);
+double get_aperture_stats (Matrix *matrix, int X, int Y, int Npix, int Nborder, double max, int VERBOSE);
 int set_rough_radii (double Ra, double Ri, double Ro);
 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);
@@ -170,13 +187,4 @@
 void FreeQueues (void);
 void FreeBooks (void);
-
-// the interpolating spline has valu
-typedef struct {
-  int Nknots;
-  opihi_flt *xk;
-  opihi_flt *yk;
-  opihi_flt *y2;
-  char *name;
-} Spline;
 
 /* in SplineOps.c */
@@ -207,3 +215,12 @@
 double hermitian_10(double x);
 
+/* in MedImageOps.c */
+void InitMedImages ();
+void FreeMedImages ();
+void FreeMedImage (MedImageType *medimage);
+MedImageType *FindMedImage (char *name);
+MedImageType *CreateMedImage (char *name, int Nx, int Ny);
+int DeleteMedImage (MedImageType *medimage);
+void ListMedImages ();
+
 # endif
Index: trunk/Ohana/src/opihi/lib.data/Makefile
===================================================================
--- trunk/Ohana/src/opihi/lib.data/Makefile	(revision 36671)
+++ trunk/Ohana/src/opihi/lib.data/Makefile	(revision 36679)
@@ -24,4 +24,5 @@
 $(SDIR)/spline.$(ARCH).o		\
 $(SDIR)/SplineOps.$(ARCH).o		\
+$(SDIR)/MedImageOps.$(ARCH).o		\
 $(SDIR)/mrqmin.$(ARCH).o		\
 $(SDIR)/mrq2dmin.$(ARCH).o		\
Index: trunk/Ohana/src/opihi/lib.data/MedImageOps.c
===================================================================
--- trunk/Ohana/src/opihi/lib.data/MedImageOps.c	(revision 36679)
+++ trunk/Ohana/src/opihi/lib.data/MedImageOps.c	(revision 36679)
@@ -0,0 +1,125 @@
+# include "data.h"
+
+/* this file contains functions to manage the median image data
+ */
+
+MedImageType **medimages = NULL; /* book to store the list of all splines */
+int     Nmedimages;   /* number of currently defined medimages */
+int     NMEDIMAGES;   /* number of currently allocated medimages */
+
+void InitMedImages () {
+  Nmedimages = 0;
+  NMEDIMAGES = 16;
+  ALLOCATE (medimages, MedImageType *, NMEDIMAGES); 
+}
+
+void FreeMedImages () {
+
+  int i;
+
+  for (i = 0; i < Nmedimages; i++) {
+    FreeMedImage (medimages[i]);
+  }
+  free (medimages);
+}
+
+void FreeMedImage (MedImageType *medimage) {
+
+  int i;
+
+  if (!medimage) return;
+
+  free (medimage[0].name);
+  for (i = 0; i < medimage[0].Ninput; i++) {
+    free (medimage[0].buffers[i]);
+  }
+  free (medimage[0].buffers);
+  free (medimage);
+}
+
+/* return the given medimage */
+MedImageType *FindMedImage (char *name) {
+
+  int i;
+
+  if (!medimages) return NULL;
+
+  for (i = 0; i < Nmedimages; i++) {
+    if (!strcmp (medimages[i][0].name, name)) {
+      return (medimages[i]);
+    }
+  }
+  return (NULL);
+}
+
+/* make a new named medimage */
+MedImageType *CreateMedImage (char *name, int Nx, int Ny) {
+
+  int N;
+  MedImageType *medimage;
+
+  // do not create an image if one exists
+  medimage = FindMedImage (name);
+  if (medimage != NULL) {
+    return NULL;
+  }
+
+  if (!medimages) InitMedImages ();
+
+  N = Nmedimages;
+  Nmedimages ++;
+  CHECK_REALLOCATE (medimages, MedImageType *, NMEDIMAGES, Nmedimages, 16);
+  ALLOCATE (medimage, MedImageType, 1);
+  medimage->name = strcreate (name);
+  medimage->Ninput = 0;
+  medimage->Nx = Nx;
+  medimage->Ny = Ny;
+  ALLOCATE (medimage->buffers, float *, 1);
+
+  medimages[N] = medimage;
+  return (medimage);
+}
+
+/* delete a medimage */
+int DeleteMedImage (MedImageType *medimage) {
+
+  int i, N, NMEDIMAGES_2;
+
+  if (!medimages) return FALSE;
+
+  /* find medimage in medimage list */
+  N = -1;
+  for (i = 0; i < Nmedimages; i++) {
+    if (medimages[i] == medimage) {
+      N = i;
+      break;
+    }
+  }
+  if (N == -1) return (FALSE);
+
+  for (i = N; i < Nmedimages - 1; i++) {
+    medimages[i] = medimages[i + 1];
+  }
+  Nmedimages --;
+  NMEDIMAGES_2 = MAX (16, NMEDIMAGES / 2);
+  if (Nmedimages < NMEDIMAGES_2) {
+    NMEDIMAGES = NMEDIMAGES_2;
+    REALLOCATE (medimages, MedImageType *, NMEDIMAGES);
+  }
+
+  FreeMedImage (medimage);
+  return (TRUE);
+}
+
+/* list known medimages */
+void ListMedImages () {
+
+  int i;
+
+  if (!medimages) return;
+
+  for (i = 0; i < Nmedimages; i++) {
+    gprint (GP_ERR, "%-15s %4d x %4d : %3d inputs\n", medimages[i][0].name, medimages[i][0].Nx, medimages[i][0].Ny, medimages[i][0].Ninput);
+  }
+  return;
+}
Index: trunk/Ohana/src/opihi/lib.data/starfuncs.c
===================================================================
--- trunk/Ohana/src/opihi/lib.data/starfuncs.c	(revision 36671)
+++ trunk/Ohana/src/opihi/lib.data/starfuncs.c	(revision 36679)
@@ -1,5 +1,5 @@
 # include "data.h"
 
-double get_aperture_stats (Matrix *matrix, int X, int Y, int Npix, int Nborder, double max) {
+double get_aperture_stats (Matrix *matrix, int X, int Y, int Npix, int Nborder, double max, int VERBOSE) {
 
   double *ring;
@@ -95,5 +95,5 @@
   set_int_variable ("Npts", Npts);
   
-  gprint (GP_LOG, "%f %f %f %f %f %f %f %f\n", x, y, FWHMx, FWHMy, sky, I, mag, dmag);
+  if (VERBOSE) gprint (GP_LOG, "%f %f %f %f %f %f %f %f\n", x, y, FWHMx, FWHMy, sky, I, mag, dmag);
 
   return (mag);
Index: trunk/Ohana/src/opihi/lib.shell/ListOps.c
===================================================================
--- trunk/Ohana/src/opihi/lib.shell/ListOps.c	(revision 36671)
+++ trunk/Ohana/src/opihi/lib.shell/ListOps.c	(revision 36679)
@@ -198,7 +198,4 @@
 
   ptr = nextword (line);
-  if (!strncmp("-excel", ptr, strlen("-excel"))) ptr = nextword (ptr);
-  if (!strncmp("-excel-style", ptr, strlen("-excel-style"))) ptr = nextword (ptr);
-  ptr = nextword (ptr);
   if (!strncmp("-excel", ptr, strlen("-excel"))) ptr = nextword (ptr);
   if (!strncmp("-excel-style", ptr, strlen("-excel-style"))) ptr = nextword (ptr);
Index: trunk/Ohana/src/opihi/lib.shell/convert_to_RPN.c
===================================================================
--- trunk/Ohana/src/opihi/lib.shell/convert_to_RPN.c	(revision 36671)
+++ trunk/Ohana/src/opihi/lib.shell/convert_to_RPN.c	(revision 36679)
@@ -70,4 +70,6 @@
     if (!strcmp (argv[i], "^"))      { type = ST_POWER; goto gotit; }
 
+    if (!strcmp (argv[i], "max"))    { type = ST_BINARY; strcpy (argv[i], "U"); goto gotit; }
+    if (!strcmp (argv[i], "min"))    { type = ST_BINARY; strcpy (argv[i], "D"); goto gotit; }
     if (!strcmp (argv[i], "atan2"))  { type = ST_BINARY; goto gotit; }
     if (!strcmp (argv[i], ","))      { type = ST_COMMA; goto gotit; }
Index: trunk/Ohana/src/tools/src/medianfilter.c
===================================================================
--- trunk/Ohana/src/tools/src/medianfilter.c	(revision 36671)
+++ trunk/Ohana/src/tools/src/medianfilter.c	(revision 36679)
@@ -114,5 +114,5 @@
       if (debug) fprintf (stderr, "\n");
       if (Nvalid == 0) {
-	*O = 0.0;
+	*O = NAN;
 	if (debug) {
 	    fprintf (stderr, "Nvalid is 0\n");
