Index: branches/eam_branches/ipp-20211108/Ohana/src/opihi/cmd.data/Makefile
===================================================================
--- branches/eam_branches/ipp-20211108/Ohana/src/opihi/cmd.data/Makefile	(revision 41962)
+++ branches/eam_branches/ipp-20211108/Ohana/src/opihi/cmd.data/Makefile	(revision 41963)
@@ -78,4 +78,6 @@
 $(SRC)/imsmooth.2d.$(ARCH).o	\
 $(SRC)/imconvolve.$(ARCH).o	\
+$(SRC)/imresample.$(ARCH).o	\
+$(SRC)/imcollapse.$(ARCH).o	\
 $(SRC)/integrate.$(ARCH).o	\
 $(SRC)/interpolate.$(ARCH).o	\
Index: branches/eam_branches/ipp-20211108/Ohana/src/opihi/cmd.data/cut.c
===================================================================
--- branches/eam_branches/ipp-20211108/Ohana/src/opihi/cmd.data/cut.c	(revision 41962)
+++ branches/eam_branches/ipp-20211108/Ohana/src/opihi/cmd.data/cut.c	(revision 41963)
@@ -96,4 +96,5 @@
   if (argc != 9) {
     gprint (GP_ERR, "USAGE: cut <buffer> <X vector> <Y vector> <X|Y> sx sy nx ny\n");
+    gprint (GP_ERR, "  extract a vector in the X or Y direction based on the pixel values in window\n");
     return (FALSE);
   }
Index: branches/eam_branches/ipp-20211108/Ohana/src/opihi/cmd.data/imcollapse.c
===================================================================
--- branches/eam_branches/ipp-20211108/Ohana/src/opihi/cmd.data/imcollapse.c	(revision 41963)
+++ branches/eam_branches/ipp-20211108/Ohana/src/opihi/cmd.data/imcollapse.c	(revision 41963)
@@ -0,0 +1,113 @@
+# include "data.h"
+
+enum {CALC_MEDIAN, CALC_MEAN, CALC_IRLS, CALC_WTMEAN, CALC_INNER_FRACTION};
+
+// take an image and collapse to a histogram along x or y 
+int imcollapse (int argc, char **argv) {
+  
+  int N;
+  Buffer *buf;
+  Vector *vecX, *vecY;
+
+  int mode = CALC_MEDIAN;
+  if ((N = get_argument (argc, argv, "-mean"))) {
+    mode = CALC_MEAN;
+    remove_argument (N, &argc, argv);
+  }
+
+  int sx = 0, sy = 0;
+  int nx = 0, ny = 0;
+  if ((N = get_argument (argc, argv, "-region"))) {
+    remove_argument (N, &argc, argv);
+    sx = atoi (argv[N]);
+    remove_argument (N, &argc, argv);
+    sy = atoi (argv[N]);
+    remove_argument (N, &argc, argv);
+    nx = atoi (argv[N]);
+    remove_argument (N, &argc, argv);
+    ny = atoi (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  if (argc != 5) {
+    gprint (GP_ERR, "USAGE: imcollapse <buffer> <x> <y> <X|Y> [-region sx sy nx ny]\n");
+    return (FALSE);
+  }
+
+  if ((buf = SelectBuffer (argv[1], OLDBUFFER, TRUE)) == NULL) return (FALSE);
+  
+  int Nx = buf[0].matrix.Naxis[0];
+  int Ny = buf[0].matrix.Naxis[1];
+
+  /* if either range is set to zero, use the rest of the chip */
+  if (nx == 0) nx = Nx - sx;
+  if (ny == 0) ny = Ny - sy;
+
+  if ((sx < 0) || (sy < 0) || (sx+nx > Nx) || (sy+ny > Ny)) {
+    gprint (GP_ERR, "region out of range\n");
+    return (FALSE);
+  }
+  if ((nx < 0) || (ny < 0)) {
+    gprint (GP_ERR, "invalid region\n");
+    return (FALSE);
+  }
+
+  if ((vecX = SelectVector (argv[2], ANYVECTOR, TRUE)) == NULL) return (FALSE);
+  if ((vecY = SelectVector (argv[3], ANYVECTOR, TRUE)) == NULL) return (FALSE);
+
+  int direction = 0;
+  if (!strcasecmp(argv[4], "x")) direction = 1;
+  if (!strcasecmp(argv[4], "y")) direction = 2;
+  if (!direction) { 
+    gprint (GP_ERR, "invalid direction %s\n", argv[4]);
+    return (FALSE);
+  }
+
+  // 'direction' is the direction of collapse 
+  int Nbins = (direction == 1) ? ny : nx;
+  ResetVector (vecX, OPIHI_FLT, Nbins);
+  ResetVector (vecY, OPIHI_FLT, Nbins);
+  bzero (vecX->elements.Flt, vecX->Nelements*sizeof(opihi_flt));
+  bzero (vecY->elements.Flt, vecY->Nelements*sizeof(opihi_flt));
+  opihi_flt *xout = vecX->elements.Flt;
+  opihi_flt *yout = vecY->elements.Flt;
+  
+  float *V = (float *)buf[0].matrix.buffer;
+
+  // temp storage for extracted values
+  int Nvals = (direction == 1) ? nx : ny;
+  ALLOCATE_PTR (values, opihi_flt, Nvals);
+
+  if (direction == 1) {
+    for (int iy = sy; iy < sy + ny; iy++) {
+      xout[iy - sy] = iy;
+      // accumulate the values for this output bin
+      int n = 0;
+      for (int ix = sx; ix < sx + nx; ix++) {
+	double val = V[iy*Nx + ix];
+	if (!isfinite(val)) continue;
+	values[n] = val;
+	n++;
+      }
+      if (n == 0) {
+	yout[iy - sy] = NAN;
+	continue;
+      }
+      // calculate the statistic (mean or median)
+      if (mode == CALC_MEDIAN) {
+	dsort (values, n);
+	int midpt = 0.5*n;
+	yout[iy - sy] = (n % 2) ? values[midpt] : 0.5*(values[midpt] + values[midpt-1]);
+      }
+      if (mode == CALC_MEAN) {
+	opihi_flt sum = 0.0;
+	for (int i = 0; i < n; i++) {	
+	  sum += values[i];
+	}
+	yout[iy - sy] = sum / (float) n;
+      }
+    }
+  }  
+  return (TRUE);
+}
+
Index: branches/eam_branches/ipp-20211108/Ohana/src/opihi/cmd.data/imcut.c
===================================================================
--- branches/eam_branches/ipp-20211108/Ohana/src/opihi/cmd.data/imcut.c	(revision 41962)
+++ branches/eam_branches/ipp-20211108/Ohana/src/opihi/cmd.data/imcut.c	(revision 41963)
@@ -9,8 +9,5 @@
   float *V;
 
-  if (argc != 8) {
-    gprint (GP_ERR, "USAGE: cut <buffer> <X vector> <Y vector> xs ys xe ye\n");
-    return (FALSE);
-  }
+  if (argc != 8) goto usage;
 
   if ((buf  = SelectBuffer (argv[1], OLDBUFFER, TRUE)) == NULL) goto missed;
@@ -51,5 +48,7 @@
 
  usage: 
-  gprint (GP_ERR, "USAGE: circstats <buffer> x y radius\n");
+  gprint (GP_ERR, "USAGE: imcut <buffer> <X vector> <Y vector> xs ys xe ye\n");
+  gprint (GP_ERR, " extract pixels along the line from (xs,ys) to (xe,ye)\n");
+  gprint (GP_ERR, " (see also imvector)\n");
   return (FALSE);
 
Index: branches/eam_branches/ipp-20211108/Ohana/src/opihi/cmd.data/imresample.c
===================================================================
--- branches/eam_branches/ipp-20211108/Ohana/src/opihi/cmd.data/imresample.c	(revision 41963)
+++ branches/eam_branches/ipp-20211108/Ohana/src/opihi/cmd.data/imresample.c	(revision 41963)
@@ -0,0 +1,78 @@
+# include "data.h"
+
+int imresample (int argc, char **argv) {
+  
+  Buffer *buf, *out;
+
+  if (argc != 8) goto usage;
+
+  if ((buf  = SelectBuffer (argv[1], OLDBUFFER, TRUE)) == NULL) goto missed;
+  if ((out  = SelectBuffer (argv[2], ANYBUFFER, TRUE)) == NULL) goto usage;
+ 
+  double xs = atof (argv[3]);
+  double ys = atof (argv[4]);
+  double xe = atof (argv[5]);
+  double ye = atof (argv[6]);
+  int    Wo = atoi (argv[7]);
+
+  int Nx = buf[0].matrix.Naxis[0];
+  int Ny = buf[0].matrix.Naxis[1];
+
+  // allow window to fall off the edge?
+  if ((xs < 0) || (xs > Nx)) goto range;
+  if ((ys < 0) || (ys > Ny)) goto range;
+  if ((xe < 0) || (xe > Nx)) goto range;
+  if ((ye < 0) || (ye > Ny)) goto range;
+
+  // relationship between a pixel in the output window (x,y) and the input image (X,Y)
+  // (0,0) corner of the output window is:
+  // Xo,Yo = xs + dY * Wo/2, ys - dX * Wo/2
+  // output window has size Lo, Wo
+  // a pixel (x,y) in the output window has coords in the input image of:
+  // (X,Y) = (Xo + x*dX - y*dY, Yo + x*dY + y*dX)
+
+  double dX = xe - xs;
+  double dY = ye - ys;
+  double Lo = hypot (dX, dY);
+  dX = dX / Lo;
+  dY = dY / Lo;
+  double Xo = xs + dY * Wo/2.0;
+  double Yo = ys - dX * Wo/2.0;
+
+  // dimensions of output window:
+  int nx = Lo;
+  int ny = Wo;
+
+  gfits_free_matrix (&out[0].matrix);
+  gfits_free_header (&out[0].header);
+  if (!CreateBuffer (out, nx, ny, -32, 1.0, 0.0)) return FALSE;
+
+  float *Vi = (float *)buf[0].matrix.buffer;
+  float *Vo = (float *)out[0].matrix.buffer;
+  for (int ix = 0; ix < nx; ix++) {
+    for (int iy = 0; iy < ny; iy++) {
+      int xi = Xo + ix*dX - iy*dY;
+      int yi = Yo + ix*dY + iy*dX;
+      if (xi < 0) continue;
+      if (yi < 0) continue;
+      if (xi >= Nx) continue;
+      if (yi >= Ny) continue;
+      Vo[ix + nx*iy] = Vi[xi + Nx*yi];
+    }
+  }
+  return (TRUE);
+
+ usage: 
+  gprint (GP_ERR, "USAGE: imresample <buffer> <output> xs ys xe ye width\n");
+  gprint (GP_ERR, "  resample image in new window along line (xs,ys) to (xe,ye) of given width\n");
+  return (FALSE);
+
+ range:
+  gprint (GP_ERR, "ERROR: coordinates out of range\n");
+  return (FALSE);
+
+ missed:
+  gprint (GP_ERR, "ERROR: buffer not found\n");
+  return (FALSE);
+}
+
Index: branches/eam_branches/ipp-20211108/Ohana/src/opihi/cmd.data/init.c
===================================================================
--- branches/eam_branches/ipp-20211108/Ohana/src/opihi/cmd.data/init.c	(revision 41962)
+++ branches/eam_branches/ipp-20211108/Ohana/src/opihi/cmd.data/init.c	(revision 41963)
@@ -18,5 +18,4 @@
 int clear            PROTO((int, char **));
 int clip             PROTO((int, char **));
-int imclip           PROTO((int, char **));
 int close_device     PROTO((int, char **));
 int concat           PROTO((int, char **));
@@ -61,4 +60,5 @@
 int hermitian2d      PROTO((int, char **));
 int idxread          PROTO((int, char **));
+int imclip           PROTO((int, char **));
 int imcut            PROTO((int, char **));
 int imhist           PROTO((int, char **));
@@ -68,4 +68,6 @@
 int imsmooth_2d      PROTO((int, char **));
 int imconvolve       PROTO((int, char **));
+int imresample       PROTO((int, char **));
+int imcollapse       PROTO((int, char **));
 int integrate        PROTO((int, char **));
 int interpolate      PROTO((int, char **));
@@ -266,4 +268,6 @@
   {1, "imclip",       imclip,           "clip values in an image to be within a range"},
   {1, "imcut",        imcut,            "linear image cut between arbitrary coords"},
+  {1, "imresample",   imresample,       "extract arbitrary window from image"},
+  {1, "imcollapse",   imcollapse,       "collapse to histogram along axis"},
   {1, "imhistogram",  imhist,           "histogram of an image region"},
   {1, "impeaks",      impeaks,          "find peaks in an image (return vectors)"},
Index: branches/eam_branches/ipp-20211108/Ohana/src/opihi/cmd.data/medacc.c
===================================================================
--- branches/eam_branches/ipp-20211108/Ohana/src/opihi/cmd.data/medacc.c	(revision 41962)
+++ branches/eam_branches/ipp-20211108/Ohana/src/opihi/cmd.data/medacc.c	(revision 41963)
@@ -10,4 +10,8 @@
   if ((argc != 6) && (argc != 7)) {
     gprint (GP_ERR, "USAGE: medacc <value> <vector> <key> start end [delta]\n");
+    gprint (GP_ERR, "  value and key are vectors of the same length\n");
+    gprint (GP_ERR, "  the output vector bins correspond to values ranging from start to end in steps of delta (default 1)\n");
+    gprint (GP_ERR, "  for a given output bin, all input values for which the key matches the output bin are averaged\n");
+
     return (FALSE);
   }
