Index: trunk/Ohana/src/opihi/cmd.data/box.c
===================================================================
--- trunk/Ohana/src/opihi/cmd.data/box.c	(revision 42456)
+++ trunk/Ohana/src/opihi/cmd.data/box.c	(revision 42466)
@@ -305,5 +305,5 @@
   gprint (GP_ERR, "        -xfminor, -yfminor, +xfminor, +yfminor\n");
   gprint (GP_ERR, "  \n");
-  gprint (GP_ERR, "  -dmajor : set the major tixk spacing (all axes)\n");
+  gprint (GP_ERR, "  -dmajor : set the major tick spacing (all axes)\n");
   gprint (GP_ERR, "         alternatively, set each axis independently with:\n");
   gprint (GP_ERR, "        -xdmajor, -ydmajor, +xdmajor, +ydmajor\n");
@@ -312,4 +312,8 @@
   gprint (GP_ERR, "         alternatively, set each axis independently with:\n");
   gprint (GP_ERR, "        -xflabel, -yflabel, +xflabel, +yflabel\n");
+  gprint (GP_ERR, "  \n");
+  gprint (GP_ERR, "  -format : set the format (C-style) for the tick labels (all axes)\n");
+  gprint (GP_ERR, "         alternatively, set each axis independently with:\n");
+  gprint (GP_ERR, "        -xformat, -yformat, +xformat, +yformat\n");
 
   return (FALSE);
Index: trunk/Ohana/src/opihi/cmd.data/concat.c
===================================================================
--- trunk/Ohana/src/opihi/cmd.data/concat.c	(revision 42456)
+++ trunk/Ohana/src/opihi/cmd.data/concat.c	(revision 42466)
@@ -32,5 +32,25 @@
   if ((ivec = SelectVector (argv[1], OLDVECTOR, TRUE)) == NULL) return (FALSE);
   
-  // we have 4 cases: (ivec == flt or int) and (ovec == flt or int)
+  // if the output vector is empty, inherit the type of the input vector
+  if (!ovec->Nelements) { ResetVector (ovec, ivec->type, ovec->Nelements); }
+
+  // we have 3 input and 3 output types : INT, FLT, STR
+
+  // both are strings
+  if ((ovec[0].type == OPIHI_STR) && (ivec[0].type == OPIHI_STR)) {
+    REALLOCATE (ovec->elements.Str, char *, MAX(1, ovec->Nelements + ivec->Nelements));
+    for (j = ovec[0].Nelements, i = 0; i < ivec[0].Nelements; i++, j++) {
+      ovec[0].elements.Str[j] = strcreate(ivec[0].elements.Str[i]);
+    }
+    goto done;
+  }
+
+  // if only one is a string, raise an error
+  if ((ovec[0].type == OPIHI_STR) || (ivec[0].type == OPIHI_STR)) {
+    gprint (GP_ERR, "ERROR: cannot mix string and numerical vectors\n");
+    return FALSE;
+  }
+
+  // both vectors are floats
   if ((ovec[0].type == OPIHI_FLT) && (ivec[0].type == OPIHI_FLT)) {
     REALLOCATE (ovec[0].elements.Flt, opihi_flt, ovec[0].Nelements + ivec[0].Nelements);
@@ -38,5 +58,16 @@
       ovec[0].elements.Flt[j] = ivec[0].elements.Flt[i];
     }
+    goto done;
   }
+  // both vectors are ints
+  if ((ovec[0].type == OPIHI_INT) && (ivec[0].type == OPIHI_INT)) {
+    REALLOCATE (ovec[0].elements.Int, opihi_int, ovec[0].Nelements + ivec[0].Nelements);
+    for (j = ovec[0].Nelements, i = 0; i < ivec[0].Nelements; i++, j++) {
+      ovec[0].elements.Int[j] = ivec[0].elements.Int[i];
+    }
+    goto done;
+  }
+
+  // if output vector is a float and input is an int, cast the int values to the float
   if ((ovec[0].type == OPIHI_FLT) && (ivec[0].type == OPIHI_INT)) {
     REALLOCATE (ovec[0].elements.Flt, opihi_flt, ovec[0].Nelements + ivec[0].Nelements);
@@ -44,12 +75,8 @@
       ovec[0].elements.Flt[j] = ivec[0].elements.Int[i];
     }
-  }
-  if ((ovec[0].type == OPIHI_INT) && (ivec[0].type == OPIHI_INT)) {
-    REALLOCATE (ovec[0].elements.Int, opihi_int, ovec[0].Nelements + ivec[0].Nelements);
-    for (j = ovec[0].Nelements, i = 0; i < ivec[0].Nelements; i++, j++) {
-      ovec[0].elements.Int[j] = ivec[0].elements.Int[i];
-    }
+    goto done;
   }
 
+  // the output vector is an int and input is a float:
   // this case forces ovec to be raised to FLT
   if ((ovec[0].type == OPIHI_INT) && (ivec[0].type == OPIHI_FLT)) {
@@ -64,6 +91,8 @@
       ovec[0].elements.Flt[j] = ivec[0].elements.Flt[i];
     }
+    goto done;
   }
 
+done:
   ovec[0].Nelements += ivec[0].Nelements;
   return (TRUE);
Index: trunk/Ohana/src/opihi/cmd.data/medacc.c
===================================================================
--- trunk/Ohana/src/opihi/cmd.data/medacc.c	(revision 42456)
+++ trunk/Ohana/src/opihi/cmd.data/medacc.c	(revision 42466)
@@ -8,9 +8,23 @@
   Vector *val, *key, *out;
 
+  Vector *stdev = NULL;
+  if ((N = get_argument (argc, argv, "-stdev"))) {
+    remove_argument (N, &argc, argv);
+    stdev = SelectVector (argv[N], ANYVECTOR, TRUE);
+    remove_argument (N, &argc, argv);
+    if (!stdev) {
+      gprint (GP_ERR, "output vector for standard deviation not found\n");
+      return (FALSE);
+    }
+  }
+
   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");
+    gprint (GP_ERR, "  for a given output bin, all input values for which the key matches the output bin are used to calculate the statistic\n");
+
+    gprint (GP_ERR, "  the output is the average of the inner 25%% of data values\n");
+    gprint (GP_ERR, "  -stdev (outvec) : optionally return the standard deviation, calculated based on the 68%%-ile range\n");
 
     return (FALSE);
@@ -43,4 +57,8 @@
   ResetVector (out, OPIHI_FLT, Nbins);
   bzero (out[0].elements.Flt, sizeof(opihi_flt)*out[0].Nelements);
+
+  if (stdev) {
+    ResetVector (stdev, OPIHI_FLT, Nbins);
+  }
 
   /* copy vec and key to temp vectors */
@@ -80,4 +98,12 @@
     }
     if (fn > 0) O[i] /= fn;
+
+    if (stdev) {
+      int Nmin = 0.16*N;
+      int Nmax = 0.84*N;
+      float Smin = tmpvec[N0 + Nmin];
+      float Smax = tmpvec[N0 + Nmax];
+      stdev[0].elements.Flt[i] = 0.5*(Smax - Smin);
+    }
   }      
   
Index: trunk/Ohana/src/opihi/cmd.data/reindex.c
===================================================================
--- trunk/Ohana/src/opihi/cmd.data/reindex.c	(revision 42456)
+++ trunk/Ohana/src/opihi/cmd.data/reindex.c	(revision 42466)
@@ -13,4 +13,12 @@
     remove_argument (N, &argc, argv);
     KEEP_UNMATCH = TRUE;
+  }
+
+  // BLANKVAL is the name of the value to use for unmatched elements
+  char *BLANKVAL = NULL;
+  if ((N = get_argument (argc, argv, "-blank")) || (N = get_argument (argc, argv, "-blank-value"))) {
+    remove_argument (N, &argc, argv);
+    BLANKVAL = strcreate (argv[N]);
+    remove_argument (N, &argc, argv);
   }
 
@@ -35,4 +43,5 @@
     opihi_flt *vi = ivec[0].elements.Flt;
     opihi_int *vx = xvec[0].elements.Int;
+    opihi_flt myBlank = (BLANKVAL == NULL) ? NAN : atof(BLANKVAL);
     for (Npts = i = 0; i < xvec[0].Nelements; i++, vx++) {
       if (Npts >= NPTS) {
@@ -42,5 +51,5 @@
       if (*vx < 0) {
 	if (KEEP_UNMATCH) {
-	  ovec[0].elements.Flt[Npts] = NAN;
+	  ovec[0].elements.Flt[Npts] = myBlank;
 	  Npts++;
 	} 
@@ -55,4 +64,5 @@
     opihi_int *vi = ivec[0].elements.Int;
     opihi_int *vx = xvec[0].elements.Int;
+    opihi_int myBlank = (BLANKVAL == NULL) ? -4096 : atoi(BLANKVAL);
     for (Npts = i = 0; i < xvec[0].Nelements; i++, vx++) {
       if (Npts >= NPTS) {
@@ -62,5 +72,5 @@
       if (*vx < 0) {
 	if (KEEP_UNMATCH) {
-	  ovec[0].elements.Int[Npts] = -4096; // XXX use a different or a specified value?
+	  ovec[0].elements.Int[Npts] = myBlank;
 	  Npts++;
 	} 
@@ -74,4 +84,5 @@
   if (ivec->type == OPIHI_STR) {
     opihi_int *vx = xvec[0].elements.Int;
+    char *myBlank = (BLANKVAL == NULL) ? strcreate ("") : strcreate(BLANKVAL);
     for (Npts = i = 0; i < xvec[0].Nelements; i++, vx++) {
       if (Npts >= NPTS) {
@@ -90,12 +101,15 @@
       Npts++;
     }
+    FREE (myBlank);
   }
 
   // free up unused memory
   ResetVector (ovec, ivec->type, Npts);
+  FREE (BLANKVAL);
   return (TRUE);
 
 error:
   DeleteVector (ovec);
+  FREE (BLANKVAL);
   return (FALSE);
 
@@ -104,8 +118,10 @@
     gprint (GP_ERR, "  Creates a new vector (out) from (in) based on sequence in (index)\n");
     gprint (GP_ERR, "  output[i] = input[index[i]]\n");
-    gprint (GP_ERR, "  If -keep-unmatched is provided, elements of index with negative values will be set to NaN / -1,\n");
+    gprint (GP_ERR, "  If -keep-unmatched is provided, elements of index with negative values will be set to NaN / -4096 (or specific value)\n");
     gprint (GP_ERR, "    otherwise they will be skipped in the output.\n");
+    gprint (GP_ERR, "  If -blank-value is provided, this supplied value will be used for unmatched elements\n");
     gprint (GP_ERR, "  The output vector has the type of the input vector and the length of the index (if -keep-unmatched).\n");
     gprint (GP_ERR, "  The index vector may have duplicates\n");
+    FREE (BLANKVAL);
     return (FALSE);
 }
