Index: trunk/Ohana/src/opihi/cmd.data/threshold.c
===================================================================
--- trunk/Ohana/src/opihi/cmd.data/threshold.c	(revision 33963)
+++ trunk/Ohana/src/opihi/cmd.data/threshold.c	(revision 40623)
@@ -3,9 +3,8 @@
 int threshold (int argc, char **argv) {
   
-  int N, QUIET;
-  double value;
+  int N;
   Vector *vecx, *vecy;
 
-  QUIET = FALSE;
+  int QUIET = FALSE;
   if ((N = get_argument (argc, argv, "-q"))) {
     QUIET = TRUE;
@@ -13,8 +12,26 @@
   }
 
+  int REVERSE = FALSE;
+  if ((N = get_argument (argc, argv, "-r"))) {
+    REVERSE = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+
+  int BinMin = -1;
+  int BinMax = -1;
+  if ((N = get_argument (argc, argv, "-range"))) {
+    remove_argument (N, &argc, argv);
+    BinMin = atoi (argv[N]);
+    remove_argument (N, &argc, argv);
+    BinMax = atoi (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
   if (argc != 4) {
-    gprint (GP_ERR, "USAGE: threshold <x> <y> (value)\n");
+    gprint (GP_ERR, "USAGE: threshold <x> <y> (value) [-q] [-r] [-range BinMin BinMax] \n");
     gprint (GP_ERR, "  find the x coordinate at which we pass the specified value\n");
     gprint (GP_ERR, "  by default, y must be monotonically increasing\n");
+    gprint (GP_ERR, "  -q : quiet mode\n");
+    gprint (GP_ERR, "  -r : reverse (find downward transition)\n");
     return (FALSE);
   }
@@ -22,40 +39,70 @@
   if ((vecx = SelectVector (argv[1], OLDVECTOR, TRUE)) == NULL) return (FALSE);
   if ((vecy = SelectVector (argv[2], OLDVECTOR, TRUE)) == NULL) return (FALSE);
+  if (vecx[0].Nelements != vecy[0].Nelements) return FALSE;
+  int Nelements = vecx[0].Nelements;
   
-  value = atof (argv[3]);
+  double value = atof (argv[3]);
   
-  // if (argc == 6) {
-  //   start = atof (argv[4]);
-  //   end   = atof (argv[5]);
-  // } else {
-  //   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];
-  // }
-
   int isFltX = (vecx[0].type == OPIHI_FLT);
   int isFltY = (vecy[0].type == OPIHI_FLT);
 
+  // BinMin = -1 -> range not provide
+  if (BinMin == -1) {
+    BinMin = 0;
+    BinMax = Nelements - 1;
+  } else {
+    if ((BinMin >= vecx[0].Nelements) || (BinMin < -1*vecx[0].Nelements)) {
+      gprint (GP_ERR, "vector subscript out of range\n"); 
+      return FALSE;
+    }
+    if (BinMin < 0) BinMin += vecx[0].Nelements;
+    if ((BinMax >= vecx[0].Nelements) || (BinMax < -1*vecx[0].Nelements)) {
+      gprint (GP_ERR, "vector subscript out of range\n"); 
+      return FALSE;
+    }
+    if (BinMax < 0) BinMax += vecx[0].Nelements;
+  }
+
   // use bisection to find the value
-  int Nlo, Nhi;
-  int Nelements = vecx[0].Nelements;
 
   // find the last entry before start
-  Nlo = 0;
-  Nhi = Nelements - 1;
-  while (Nhi - Nlo > 10) {
-    N = 0.5*(Nlo + Nhi);
-    double testval = isFltY ? vecy[0].elements.Flt[N] : vecy[0].elements.Int[N];
-    if (testval < value) {
-      Nlo = MAX(N, 0);
-    } else {
-      Nhi = MIN(N, Nelements - 1);
+  int Nlo = BinMin;
+  int Nhi = BinMax;
+
+  if (!REVERSE) {
+    while (Nhi - Nlo > 10) {
+      N = 0.5*(Nlo + Nhi);
+      double testval = isFltY ? vecy[0].elements.Flt[N] : vecy[0].elements.Int[N];
+      if (testval < value) {
+	Nlo = MAX(N, 0);
+      } else {
+	Nhi = MIN(N, Nelements - 1);
+      }
     }
-  }
-  // v[Nlo] < value <= v[Nhi]
-  for (N = Nlo; N <= Nhi; N++) {
-    double testval = isFltY ? vecy[0].elements.Flt[N] : vecy[0].elements.Int[N];
-    if (testval > value) {
-      Nhi = N;
-      break;
+    // v[Nlo] < value <= v[Nhi]
+    for (N = Nlo; N <= Nhi; N++) {
+      double testval = isFltY ? vecy[0].elements.Flt[N] : vecy[0].elements.Int[N];
+      if (testval > value) {
+	Nhi = N;
+	break;
+      }
+    }
+  } else {
+    while (Nhi - Nlo > 10) {
+      N = 0.5*(Nlo + Nhi);
+      double testval = isFltY ? vecy[0].elements.Flt[N] : vecy[0].elements.Int[N];
+      if (testval > value) {
+	Nlo = MAX(N, 0);
+      } else {
+	Nhi = MIN(N, Nelements - 1);
+      }
+    }
+    // v[Nlo] > value >= v[Nhi]
+    for (N = Nlo; N <= Nhi; N++) {
+      double testval = isFltY ? vecy[0].elements.Flt[N] : vecy[0].elements.Int[N];
+      if (testval < value) {
+	Nhi = N;
+	break;
+      }
     }
   }
