Index: branches/eam_branches/ohana.20170822/src/opihi/cmd.data/Makefile
===================================================================
--- branches/eam_branches/ohana.20170822/src/opihi/cmd.data/Makefile	(revision 40173)
+++ branches/eam_branches/ohana.20170822/src/opihi/cmd.data/Makefile	(revision 40174)
@@ -155,4 +155,5 @@
 $(SRC)/type.$(ARCH).o		   \
 $(SRC)/uniq.$(ARCH).o		   \
+$(SRC)/uniqpair.$(ARCH).o		   \
 $(SRC)/unsign.$(ARCH).o	           \
 $(SRC)/vbin.$(ARCH).o		   \
Index: branches/eam_branches/ohana.20170822/src/opihi/cmd.data/init.c
===================================================================
--- branches/eam_branches/ohana.20170822/src/opihi/cmd.data/init.c	(revision 40173)
+++ branches/eam_branches/ohana.20170822/src/opihi/cmd.data/init.c	(revision 40174)
@@ -141,6 +141,7 @@
 int tvcontour        PROTO((int, char **));
 int tvgrid           PROTO((int, char **));
-int opihi_type             PROTO((int, char **));
+int opihi_type       PROTO((int, char **));
 int uniq             PROTO((int, char **));
+int uniqpair         PROTO((int, char **));
 int unsign           PROTO((int, char **));
 int vbin             PROTO((int, char **));
@@ -325,4 +326,5 @@
   {1, "ungridify",    ungridify,        "convert image region to vector triplet"},
   {1, "uniq",         uniq,             "create a uniq vector subset from a vector"},
+  {1, "uniqpair",     uniqpair,         "create a uniq vector subset from a pair of vectors, saving duplicates if desired"},
   {1, "unsign",       unsign,           "toggle the UNSIGN status"},
   {1, "vbin",         vbin,             "rebin vector data by a factor of N"},
Index: branches/eam_branches/ohana.20170822/src/opihi/cmd.data/test/uniqpair.sh
===================================================================
--- branches/eam_branches/ohana.20170822/src/opihi/cmd.data/test/uniqpair.sh	(revision 40174)
+++ branches/eam_branches/ohana.20170822/src/opihi/cmd.data/test/uniqpair.sh	(revision 40174)
@@ -0,0 +1,83 @@
+
+
+list tests
+ test1
+ memtest1
+end
+
+# Test if uniqpair works
+macro test1
+
+ $PASS = 1
+
+ local i
+
+ delete ID1 ID2
+
+ vlist -int ID1 1   1   2   3   3   4   5   6
+ vlist -int ID2 2   3   4   5   5   6   7   8
+
+ uniqpair ID1 ID2 IDu -c IDn -d index
+
+ # if ((xvec[1024] != 17) || (yvec[1024] != 100))
+ #  $PASS = 0
+ #  echo "Value mismatch: xvec[1024] yvec[1024] (should be 17,100)"
+ # end
+ # 
+ # imhist -q buff xvec yvec -region 40 0 25 10 -range 0 10
+ # 
+ # if ((xvec[1024] != 10) || (yvec[1024] != 100))
+ #  $PASS = 0
+ #  echo "Value mismatch: xvec[1024] yvec[1024] (should be 10,100)"
+ # end
+
+end
+
+# Test if uniqpair works
+macro test2
+
+ $PASS = 1
+
+ delete ID1 ID2
+
+ vlist -int ID1 {2^16 + 2} {2^17}     {2^18 + 3} {2^16 + 2} {2^17 + 2} {2^18 + 3} 
+ vlist -int ID2 {2^16 + 0} {2^17 + 2} {2^18 + 5} {2^16 + 0} {2^17 + 2} {2^18 + 5} 
+
+ uniqpair ID1 ID2 IDu -c IDn -d index
+
+ reindex ID2s = ID2 using index
+ reindex ID1s = ID1 using index
+
+ vectors
+
+ echo "unique"
+ print_v IDu IDn
+
+ echo "dups"
+ print_v ID1s ID2s index
+end
+
+
+# Memory test
+macro memtest1
+
+ local i
+
+ list word -x "ps -p $PID -o rss"
+ $startmem = $word:1
+
+ for i 0 1000
+  imhist -q buff xvec yvec -region 40 0 25 10 -range 0 10
+ end
+
+ list word -x "ps -p $PID -o rss"
+ $endmem = $word:1
+
+ $PASS = 1
+
+ if ($endmem - $startmem > 10)
+   $PASS = 0
+   echo "growth: {$endmem-$startmem}"
+   echo "kB/loop: {($endmem-$startmem)/1000}"
+ end
+end
Index: branches/eam_branches/ohana.20170822/src/opihi/cmd.data/uniqpair.c
===================================================================
--- branches/eam_branches/ohana.20170822/src/opihi/cmd.data/uniqpair.c	(revision 40173)
+++ branches/eam_branches/ohana.20170822/src/opihi/cmd.data/uniqpair.c	(revision 40174)
@@ -5,5 +5,5 @@
 
   int N;
-  Vector *ID1vec = NULL, *ID2vec = NULL, *SEQvec = NULL, *OUTvec = NULL;
+  Vector *ID1vec = NULL, *ID2vec = NULL, *OUTvec = NULL;
 
   int VERBOSE = FALSE;
@@ -14,5 +14,5 @@
 
   Vector *SEQdup = NULL;
-  if ((N = get_argument (argc, argv, "-save-dups"))) {
+  if ((N = get_argument (argc, argv, "-d"))) {
     remove_argument (N, &argc, argv);
     if ((SEQdup = SelectVector (argv[N], ANYVECTOR, TRUE)) == NULL) {
@@ -33,6 +33,9 @@
   }
 
-  if (argc != 5) {
-    gprint (GP_ERR, "USAGE: uniqpair (ID1) (ID2) (IDout) -c count\n");
+  if (argc != 4) {
+    gprint (GP_ERR, "USAGE: uniqpair (ID1) (ID2) (IDout) [-c count] [-d dupindex]\n");
+    gprint (GP_ERR, "  merge ID1 and ID2 (32 bit int values) into a single index and find unique entries\n");
+    gprint (GP_ERR, "  -c count: save the number of each unique entry in the count vector\n");
+    gprint (GP_ERR, "  -d dupindex: save the sequence number of duplicate entries in the dupindex vector\n");
     return (FALSE);
   }
@@ -74,5 +77,5 @@
   opihi_int *SEQdata = NULL;
   ALLOCATE (IDfull, opihi_int, ID1vec->Nelements);
-  ALLOCATE (SEQdata, opihi_int, SEQvec[0].Nelements);
+  ALLOCATE (SEQdata, opihi_int, ID1vec->Nelements);
   for (int i = 0; i < ID1vec->Nelements; i++) {
     IDfull[i] = ID1[i] + (ID2[i] << 32);
@@ -80,5 +83,6 @@
   }
 
-  llsorttwo (IDfull, SEQdata, ID1vec->Nelements);
+  // XXX watch out: this all needs to get rationalized...
+  llsortpair ((off_t *)IDfull, (off_t *)SEQdata, ID1vec->Nelements);
 
   opihi_int *vtgt = OUTvec->elements.Int;
@@ -111,5 +115,5 @@
       // we want to save SEQdata values for the duplicates
       // SEQdata[i-Ndup] .. SEQdata[i-N
-      for (j = i - Ndup; j < i; j++) {
+      for (int j = i - Ndup; j < i; j++) {
 	SEQdup->elements.Int[NseqDup] = SEQdata[j];
 	NseqDup ++;
@@ -129,5 +133,5 @@
   if (SEQdup) {
     SEQdup->Nelements = NseqDup;
-    REALLOCATE (SEQdup->elements.Int, opihi_int, Nseqdup);
+    REALLOCATE (SEQdup->elements.Int, opihi_int, NseqDup);
   }
 
@@ -135,10 +139,6 @@
   OUTvec->elements.Int = vtgt;
   ResetVector (OUTvec, OPIHI_INT, Nout);
-  if (cvec) ResetVector (cvec, OPIHI_INT, Nout);
+  if (CNTvec) ResetVector (CNTvec, OPIHI_INT, Nout);
 
   return (TRUE);
 }
-
-
-
-}
