Index: trunk/Ohana/src/opihi/cmd.data/read_vectors.c
===================================================================
--- trunk/Ohana/src/opihi/cmd.data/read_vectors.c	(revision 34088)
+++ trunk/Ohana/src/opihi/cmd.data/read_vectors.c	(revision 34461)
@@ -22,5 +22,5 @@
 
 // vector types
-enum {COLTYPE_NONE, COLTYPE_FLT, COLTYPE_INT, COLTYPE_TIME};
+enum {COLTYPE_NONE, COLTYPE_FLT, COLTYPE_INT, COLTYPE_TIME, COLTYPE_CHAR};
 
 int read_vectors (int argc, char **argv) {
@@ -101,4 +101,5 @@
       if (!strcasecmp(ptr, "float")) { coltype[i] = COLTYPE_FLT; }
       if (!strcasecmp(ptr, "int"))   { coltype[i] = COLTYPE_INT; }
+      if (!strcasecmp(ptr, "char"))  { coltype[i] = COLTYPE_CHAR; }
       if (!strcasecmp(ptr, "time"))  { coltype[i] = COLTYPE_TIME; }
       if (!coltype[i]) goto bad_colname;
@@ -143,5 +144,5 @@
   NELEM = 1000;
   for (i = 0; i < Nvec; i++) {
-    if (coltype[i] == COLTYPE_INT) {
+    if ((coltype[i] == COLTYPE_INT) || (coltype[i] == COLTYPE_CHAR)) {
       ResetVector (vec[i], OPIHI_INT, NELEM);
     } else {
@@ -195,4 +196,5 @@
       for (i = 0; i < Nvec; i++) {
 	int ivalue;
+	char cvalue;
 	double dvalue;
 	time_t tvalue;
@@ -203,4 +205,8 @@
 	    readStatus = IsCSV ? iparse_csv (&ivalue, col[i], c0) : iparse (&ivalue, col[i], c0);
 	    vec[i][0].elements.Int[Nelem] = readStatus ? ivalue : 0;
+	    break;
+	  case COLTYPE_CHAR:
+	    readStatus = IsCSV ? charparse_csv (&cvalue, col[i], c0) : charparse (&cvalue, col[i], c0);
+	    vec[i][0].elements.Int[Nelem] = readStatus ? cvalue : 0;
 	    break;
 	  case COLTYPE_FLT:
Index: trunk/Ohana/src/opihi/cmd.data/reindex.c
===================================================================
--- trunk/Ohana/src/opihi/cmd.data/reindex.c	(revision 34088)
+++ trunk/Ohana/src/opihi/cmd.data/reindex.c	(revision 34461)
@@ -5,9 +5,15 @@
 int reindex (int argc, char **argv) {
   
-  int  i, Npts, Nmax;
+  int  i, Nmax, N;
   Vector *ivec, *ovec, *xvec;
 
   ivec = ovec = xvec = NULL;
-  Npts = 0;
+  int Npts = 0;
+
+  int KEEP_UNMATCH = FALSE;
+  if ((N = get_argument (argc, argv, "-keep-unmatched"))) {
+    remove_argument (N, &argc, argv);
+    KEEP_UNMATCH = TRUE;
+  }
 
   if (argc != 6) goto usage;
@@ -22,4 +28,5 @@
 
   // ovec matches ivec in type and xvec in size (xvec need not have all ivec elements, and may have duplicates
+  int NPTS = xvec[0].Nelements;
   ResetVector (ovec, ivec->type, xvec[0].Nelements);
 
@@ -31,6 +38,15 @@
     opihi_int *vx = xvec[0].elements.Int;
     for (Npts = i = 0; i < xvec[0].Nelements; i++, vx++) {
-      if (*vx == -1) continue;
-      if (*vx < 0) ESCAPE("unexpected value in index: %d (%d)\n", *vx, i);
+      if (Npts >= NPTS) {
+	NPTS += 2000;
+	REALLOCATE (ovec[0].elements.Flt, opihi_flt, NPTS);
+      }
+      if (*vx < 0) {
+	if (KEEP_UNMATCH) {
+	  ovec[0].elements.Flt[Npts] = NAN;
+	  Npts++;
+	} 
+	continue;
+      }
       if (*vx > Nmax) ESCAPE("unexpected value in index: %d (%d)\n", *vx, i);
       ovec[0].elements.Flt[Npts] = vi[*vx];
@@ -42,6 +58,15 @@
     opihi_int *vx = xvec[0].elements.Int;
     for (Npts = i = 0; i < xvec[0].Nelements; i++, vx++) {
-      if (*vx == -1) continue;
-      if (*vx < 0) ESCAPE("unexpected value in index: %d (%d)\n", *vx, i);
+      if (Npts >= NPTS) {
+	NPTS += 2000;
+	REALLOCATE (ovec[0].elements.Int, opihi_int, NPTS);
+      }
+      if (*vx < 0) {
+	if (KEEP_UNMATCH) {
+	  ovec[0].elements.Flt[Npts] = -1;
+	  Npts++;
+	} 
+	continue;
+      }
       if (*vx > Nmax) ESCAPE("unexpected value in index: %d (%d)\n", *vx, i);
       ovec[0].elements.Int[Npts] = vi[*vx];
@@ -60,5 +85,10 @@
 usage:
     gprint (GP_ERR, "USAGE: reindex (out) = (in) using (index)\n");
-    gprint (GP_ERR, "  creates a new vectors (out) from (in) based on sequence in (index)\n");
+    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, "    otherwise they will be skipped in the output.\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");
     return (FALSE);
 }
Index: trunk/Ohana/src/opihi/cmd.data/subset.c
===================================================================
--- trunk/Ohana/src/opihi/cmd.data/subset.c	(revision 34088)
+++ trunk/Ohana/src/opihi/cmd.data/subset.c	(revision 34461)
@@ -13,6 +13,10 @@
   Npts = 0;
 
+  if (argc < 6) {
+    gprint (GP_ERR, "SYNTAX: subset vec = vec [if/where] (logic expression)\n");
+    return (FALSE);
+  }
+
   valid = TRUE;
-  valid &= (argc >= 6);
   valid &= !strcmp(argv[2], "=");
   valid &= !strcmp(argv[4], "if") || !strcmp (argv[4], "where");
