Index: trunk/Ohana/src/opihi/cmd.data/tdhistogram.c
===================================================================
--- trunk/Ohana/src/opihi/cmd.data/tdhistogram.c	(revision 41891)
+++ trunk/Ohana/src/opihi/cmd.data/tdhistogram.c	(revision 42942)
@@ -5,14 +5,79 @@
 int tdhistogram (int argc, char **argv) {
 
-  int i, Nx, Ny, Nz, N;
+  int i, N;
   float *val;
   Buffer *bf;
   Vector *vx, *vy, *vz, *range;
   opihi_flt *x, *y, *z;
+  int kapa;
+  Graphdata graphmode;
+
+  int useGraph = FALSE;
+  if ((N = get_argument (argc, argv, "-graph"))) {
+    remove_argument (N, &argc, argv);
+    useGraph = TRUE;
+    if (!style_args (&graphmode, &argc, argv, &kapa)) return FALSE;
+  }
 
   int reuse = FALSE;
   if ((N = get_argument (argc, argv, "-reuse"))) {
+    if (useGraph) { gprint (GP_ERR, "-reuse and -graph are incompatible\n"); return FALSE; }
     remove_argument (N, &argc, argv);
     reuse = TRUE;
+  }
+
+  int Nx = 100;
+  double dx = NAN;
+  if ((N = get_argument (argc, argv, "-dx"))) {
+    if (useGraph) { gprint (GP_ERR, "-dx and -graph are incompatible\n"); return FALSE; }
+    remove_argument (N, &argc, argv);
+    dx = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+  if ((N = get_argument (argc, argv, "-Nx"))) {
+    if (useGraph) { gprint (GP_ERR, "-Nx and -graph are incompatible\n"); return FALSE; }
+    if (isfinite(dx)) { gprint (GP_ERR, "-Nx and -dx are incompatible\n"); return FALSE; }
+    remove_argument (N, &argc, argv);
+    Nx = atoi(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  int Ny = 100;
+  double dy = NAN;
+  if ((N = get_argument (argc, argv, "-dy"))) {
+    if (useGraph) { gprint (GP_ERR, "-dx and -graph are incompatible\n"); return FALSE; }
+    remove_argument (N, &argc, argv);
+    dy = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+  if ((N = get_argument (argc, argv, "-Ny"))) {
+    if (useGraph) { gprint (GP_ERR, "-Ny and -graph are incompatible\n"); return FALSE; }
+    if (isfinite(dy)) { gprint (GP_ERR, "-Ny and -dy are incompatible\n"); return FALSE; }
+    remove_argument (N, &argc, argv);
+    Ny = atoi(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  int Nz = 100;
+  double dz = NAN;
+  if ((N = get_argument (argc, argv, "-dz"))) {
+    remove_argument (N, &argc, argv);
+    dz = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+  if ((N = get_argument (argc, argv, "-Nz"))) {
+    if (useGraph) { gprint (GP_ERR, "-Nz and -graph are incompatible\n"); return FALSE; }
+    if (isfinite(dz)) { gprint (GP_ERR, "-Nz and -dz are incompatible\n"); return FALSE; }
+    remove_argument (N, &argc, argv);
+    Nz = atoi(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  int binning = 1;
+  if ((N = get_argument (argc, argv, "-binning"))) {
+    if (!useGraph) { gprint (GP_ERR, "-binning requires -graph\n"); return FALSE; }
+    remove_argument (N, &argc, argv);
+    binning = atoi(argv[N]);
+    remove_argument (N, &argc, argv);
   }
 
@@ -24,29 +89,13 @@
   }
 
-  double dx = NAN;
-  if ((N = get_argument (argc, argv, "-dx"))) {
-    remove_argument (N, &argc, argv);
-    dx = atof(argv[N]);
-    remove_argument (N, &argc, argv);
-  }
-  double dy = NAN;
-  if ((N = get_argument (argc, argv, "-dy"))) {
-    remove_argument (N, &argc, argv);
-    dy = atof(argv[N]);
-    remove_argument (N, &argc, argv);
-  }
-  double dz = NAN;
-  if ((N = get_argument (argc, argv, "-dz"))) {
-    remove_argument (N, &argc, argv);
-    dz = atof(argv[N]);
-    remove_argument (N, &argc, argv);
-  }
-
-  int valid = (!reuse && (argc == 11)) || (reuse && (argc == 5));
+  int valid = (reuse && (argc == 5)) || (useGraph && (argc == 7)) || (argc == 11);
   if (!valid) {
     gprint (GP_ERR, "USAGE: tdhistogram buffer x y z (Xmin) (Xmax) (Ymin) (Ymax) (Zmin) (Zmax) [-dx dx] [-dy dy] [-dz dz] [-range range]\n");
+    gprint (GP_ERR, "USAGE: tdhistogram buffer x y z (Zmin) (Zmax) -graph [-binning N] [-dz dz] [-range range]\n");
     gprint (GP_ERR, "   OR: tdhistogram buffer x y z -reuse\n");
     gprint (GP_ERR, "   -dx, -dy, -dy specify the bin size in these directions\n");
     gprint (GP_ERR, "   -range : generate an output vector corresponding to the elements in the z-direction\n");
+    gprint (GP_ERR, "   -graph : use X,Y range from active graph\n");
+    gprint (GP_ERR, "   -binning N : use binning to define bin sizes relative to graph\n");
     gprint (GP_ERR, " output buffer is 3D\n");
     return (FALSE);
@@ -63,47 +112,5 @@
   double Xmin, Xmax, Ymin, Ymax, Zmin, Zmax;
 
-  if (!reuse) {
-    Xmin = atof(argv[5]);
-    Xmax = atof(argv[6]);
-    if (!isfinite(dx)) {
-      Nx = 100;
-      dx = (Xmax - Xmin) / (Nx - 1);
-    } else {
-      Nx = (Xmax - Xmin) / dx + 1;
-    }
-    if (dx < 0) {
-      gprint (GP_ERR, "invalid value for delta: %f\n", dx);
-      return (FALSE);
-    }
-    Ymin = atof(argv[7]);
-    Ymax = atof(argv[8]);
-    if (!isfinite(dy)) {
-      Ny = 100;
-      dy = (Ymax - Ymin) / (Ny - 1);
-    } else {
-      Ny = (Ymax - Ymin) / dy + 1;
-    }
-    if (dy < 0) {
-      gprint (GP_ERR, "invalid value for delta: %f\n", dy);
-      return (FALSE);
-    }
-    Zmin = atof(argv[9]);
-    Zmax = atof(argv[10]);
-    if (!isfinite(dz)) {
-      Nz = 100;
-      dz = (Zmax - Zmin) / (Nz - 1);
-    } else {
-      Nz = (Zmax - Zmin) / dz + 1;
-    }
-    if (dz < 0) {
-      gprint (GP_ERR, "invalid value for delta: %f\n", dz);
-      return (FALSE);
-    }
-
-    if (Nz > 1000) {
-      gprint (GP_ERR, "warning: delta of %f will result in %d histogram bins\n", dz, Nz);
-      return (FALSE);
-    }
-  } else {
+  if (reuse) {
     gfits_scan (&bf[0].header, "XMIN", "%lf", 1, &Xmin);
     gfits_scan (&bf[0].header, "XMAX", "%lf", 1, &Xmax);
@@ -118,6 +125,73 @@
     Ny = bf[0].header.Naxis[1];
     Nz = bf[0].header.Naxis[2];
-  }
-
+    goto got_range;
+  }
+
+  if (useGraph) {
+    int Xpix, Ypix;
+    KapaGetImageRange (kapa, &Xmin, &Xmax, &Ymax, &Ymin, &Xpix, &Ypix);
+    Xmax = graphmode.xmax;
+    Xmin = graphmode.xmin;
+    Ymax = graphmode.ymax;
+    Ymin = graphmode.ymin;
+
+    // (dX, dY) are the pixel scale of the output image (output pixels / input pixels)
+
+    dx = binning * (Xmax - Xmin) / (Xpix - 1);
+    dy = binning * (Ymax - Ymin) / (Ypix - 1);
+
+    Nx = abs((Xmax - Xmin) / dx) + 1;
+    Ny = abs((Ymax - Ymin) / dy) + 1;
+  
+    // XXX : note that Zmin and Zmax have a different argv location in useGraph
+    Zmin = atof(argv[5]);
+    Zmax = atof(argv[6]);
+
+    goto set_Zvalues;
+  }
+
+  // This section is only used if !reuse and !useGraph
+  Xmin = atof(argv[5]);
+  Xmax = atof(argv[6]);
+  if (!isfinite(dx)) {
+    dx = (Xmax - Xmin) / (Nx - 1);
+  } else {
+    Nx = (Xmax - Xmin) / dx + 1;
+  }
+  if (dx < 0) {
+    gprint (GP_ERR, "invalid value for delta: %f\n", dx);
+    return (FALSE);
+  }
+  Ymin = atof(argv[7]);
+  Ymax = atof(argv[8]);
+  if (!isfinite(dy)) {
+    dy = (Ymax - Ymin) / (Ny - 1);
+  } else {
+    Ny = (Ymax - Ymin) / dy + 1;
+  }
+  if (dy < 0) {
+    gprint (GP_ERR, "invalid value for delta: %f\n", dy);
+    return (FALSE);
+  }
+  // XXX : note that Zmin and Zmax have a different argv location in useGraph
+  Zmin = atof(argv[9]);
+  Zmax = atof(argv[10]);
+
+set_Zvalues:
+  if (!isfinite(dz)) {
+    dz = (Zmax - Zmin) / (Nz - 1);
+  } else {
+    Nz = (Zmax - Zmin) / dz + 1;
+  }
+  if (dz < 0) {
+    gprint (GP_ERR, "invalid value for delta: %f\n", dz);
+    return (FALSE);
+  }
+  if (Nz > 1000) {
+    gprint (GP_ERR, "warning: delta of %f will result in %d histogram bins\n", dz, Nz);
+    return (FALSE);
+  }
+
+got_range:
   REQUIRE_VECTOR_FLT (vx, FALSE); 
   REQUIRE_VECTOR_FLT (vy, FALSE); 
