Index: /branches/eam_branches/ipp-20230313/Ohana/src/opihi/cmd.data/Makefile
===================================================================
--- /branches/eam_branches/ipp-20230313/Ohana/src/opihi/cmd.data/Makefile	(revision 42609)
+++ /branches/eam_branches/ipp-20230313/Ohana/src/opihi/cmd.data/Makefile	(revision 42610)
@@ -67,4 +67,5 @@
 $(SRC)/ungridify.$(ARCH).o     \
 $(SRC)/histogram.$(ARCH).o	\
+$(SRC)/histbins.$(ARCH).o	\
 $(SRC)/tdhistogram.$(ARCH).o	\
 $(SRC)/hermitian1d.$(ARCH).o	\
Index: /branches/eam_branches/ipp-20230313/Ohana/src/opihi/cmd.data/histbins.c
===================================================================
--- /branches/eam_branches/ipp-20230313/Ohana/src/opihi/cmd.data/histbins.c	(revision 42610)
+++ /branches/eam_branches/ipp-20230313/Ohana/src/opihi/cmd.data/histbins.c	(revision 42610)
@@ -0,0 +1,47 @@
+# include "data.h"
+
+int histbins (int argc, char **argv) {
+  
+  Vector *vals, *mins, *maxs, *out;
+
+  if (argc != 5) {
+    gprint (GP_ERR, "USAGE: histbins <values> <output> <binmin> <binmax>\n");
+    gprint (GP_ERR, "  count <values> in each bin defined by the limit vectors\n");
+    return (FALSE);
+  }
+
+  if ((vals = SelectVector (argv[1], OLDVECTOR, TRUE)) == NULL) return (FALSE);
+  if ((mins = SelectVector (argv[3], OLDVECTOR, TRUE)) == NULL) return (FALSE);
+  if ((maxs = SelectVector (argv[4], OLDVECTOR, TRUE)) == NULL) return (FALSE);
+  if (mins[0].Nelements != maxs[0].Nelements) {
+    gprint (GP_ERR, "binmin and binmax number of elements don't match\n");
+    return (FALSE);
+  }
+  if ((out = SelectVector (argv[2], ANYVECTOR, TRUE)) == NULL) return (FALSE);
+
+  REQUIRE_VECTOR_FLT (vals, FALSE); 
+  REQUIRE_VECTOR_FLT (mins, FALSE); 
+  REQUIRE_VECTOR_FLT (maxs, FALSE); 
+
+  int Nbins = mins->Nelements;
+  ResetVector (out, OPIHI_FLT, Nbins);
+  bzero (out[0].elements.Flt, sizeof(opihi_flt)*out[0].Nelements);
+
+  opihi_flt *V = vals[0].elements.Flt;
+
+  // this function allows the bins to be completely arbitrary and potentially overlapping
+  // find all bins which contain each value
+  for (int i = 0; i < vals->Nelements; i++, V++) {
+    opihi_flt *S = mins[0].elements.Flt;
+    opihi_flt *E = maxs[0].elements.Flt;
+    opihi_flt *O = out[0].elements.Flt;
+    for (int j = 0; j < mins->Nelements; j++, S++, E++, O++) {
+      // note lower bound is inclusive, upper bound is exclusive:
+      if (*V <  *S) continue;
+      if (*V >= *E) continue;
+      *O += 1.0;
+    }
+  }      
+  return (TRUE);
+}
+
Index: /branches/eam_branches/ipp-20230313/Ohana/src/opihi/cmd.data/init.c
===================================================================
--- /branches/eam_branches/ipp-20230313/Ohana/src/opihi/cmd.data/init.c	(revision 42609)
+++ /branches/eam_branches/ipp-20230313/Ohana/src/opihi/cmd.data/init.c	(revision 42610)
@@ -56,4 +56,5 @@
 int ungridify        PROTO((int, char **));
 int histogram        PROTO((int, char **));
+int histbins         PROTO((int, char **));
 int tdhistogram      PROTO((int, char **));
 int hermitian1d      PROTO((int, char **));
@@ -266,4 +267,5 @@
   {1, "header",       header,           "print image header"},
   {1, "histogram",    histogram,        "generate histogram from vector"},
+  {1, "histbins",     histbins,         "generate histogram from vector, bins specified by vectors"},
   {1, "tdhistogram",  tdhistogram,      "generate 2D histogram image from vector set"},
   {1, "hermitian1d",  hermitian1d,      "generate 1-D Hermitian Polynomial"},
