Index: /branches/eam_branches/ipp-20111122/Ohana/src/opihi/cmd.astro/mkclusters.c
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/opihi/cmd.astro/mkclusters.c	(revision 32874)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/opihi/cmd.astro/mkclusters.c	(revision 32875)
@@ -2,9 +2,10 @@
 
 typedef struct {
-  int *friend;;
-  float *dist;
-  int Ndist;
-  int NDIST;
-  int group;
+  int *friend; // indices for all tested relationships
+  float *dist; // distance for this relationship
+  int Ndist;   // number of tested relationships
+  int NDIST;   // number of allocated relationships
+  int group;   // assigned group
+  int Nfriend; // number of friends brought into group
 } Object;
 
@@ -23,5 +24,5 @@
 // static int NOBJECT = 0;
 
-void add_to_group (int Nobj, float scale) {
+void add_to_group (int Nobj, float scale, int Nfriends) {
 
   int j;
@@ -37,6 +38,7 @@
   CHECK_REALLOCATE (group[Ngroup].entry, int, group[Ngroup].NENTRY, group[Ngroup].Nentry, 100);
 
-  // add all friends of this object
-  for (j = 0; j < object[Nobj].Ndist; j++) {
+  // add all friends of this object (up to Nfriensd)
+  // friends are already sorted by distance, so we add closest friends first
+  for (j = 0; (object[Nobj].Nfriend < Nfriends) && (j < object[Nobj].Ndist); j++) {
     if (object[Nobj].dist[j] > scale) continue;
 
@@ -46,5 +48,6 @@
 
     // found a friend : 
-    add_to_group (Nnew, scale);
+    object[Nobj].Nfriend ++;
+    add_to_group (Nnew, scale, Nfriends);
   }
   return;
@@ -68,4 +71,20 @@
 }
 
+void sortfriends (float *X, int *IDX1, int N) {
+
+# define SWAPFUNC(A,B){ float tmp; int itmp; \
+  tmp  = X[A];    X[A]    = X[B];    X[B]    = tmp; \
+  itmp = IDX1[A]; IDX1[A] = IDX1[B]; IDX1[B] = itmp; \
+}
+
+# define COMPARE(A,B)(X[A] < X[B])
+
+  OHANA_SORT (N, COMPARE, SWAPFUNC);
+
+# undef SWAPFUNC
+# undef COMPARE
+
+}
+
 int mkclusters (int argc, char **argv) {
   
@@ -73,5 +92,5 @@
   Vector *index1, *index2, *distance;
 
-  if (argc != 5) goto usage;
+  if (argc != 6) goto usage;
 
   if ((index1   = SelectVector (argv[1], OLDVECTOR, TRUE)) == NULL) goto escape;
@@ -79,4 +98,5 @@
   if ((distance = SelectVector (argv[3], OLDVECTOR, TRUE)) == NULL) goto escape;
   float scale = atof (argv[4]);
+  int Nfriends = atoi (argv[5]);
 
   // XXX enforce matching lengths on the three vectors
@@ -102,4 +122,5 @@
     object[i].Ndist = 0;
     object[i].group = -1; // unassigned
+    object[i].Nfriend = 0; // no friends yet
   }
 
@@ -133,4 +154,8 @@
   }
 
+  for (i = 0; i < Nobject; i++) {
+    sortfriends (object[i].dist, object[i].friend, object[i].Ndist);
+  }
+
   // generate the set of groups. each group is a list of friends and their friends
   Ngroup = 0;
@@ -155,5 +180,5 @@
     Nnew = index1->elements.Int[i];
     if (object[Nnew].group == -1) {
-      add_to_group (Nnew, scale);
+      add_to_group (Nnew, scale, Nfriends);
       // fprintf (stderr, "new group %d part 1 with %d elements\n", Ngroup, group[Ngroup].Nentry);
       found = TRUE;
@@ -162,5 +187,5 @@
     Nnew = index2->elements.Int[i];
     if (object[Nnew].group == -1) {
-      add_to_group (Nnew, scale);
+      add_to_group (Nnew, scale, Nfriends);
       // fprintf (stderr, "new group %d part 1 with %d elements\n", Ngroup, group[Ngroup].Nentry);
       found = TRUE;
