Index: /branches/eam_branches/ipp-20150616/Ohana/src/addstar/src/loadgalphot_join.c
===================================================================
--- /branches/eam_branches/ipp-20150616/Ohana/src/addstar/src/loadgalphot_join.c	(revision 38510)
+++ /branches/eam_branches/ipp-20150616/Ohana/src/addstar/src/loadgalphot_join.c	(revision 38511)
@@ -1,41 +1,49 @@
+# include "addstar.h"
+# include "loadgalphot.h"
 
+typedef struct {
+  int *ID;
+  int *type;
+  int  N;
+} GalPhotIDset;
 
-int join_IDs_inner (Vector *ID1, Vector *ID2, Vector *index1, Vector *index2) {
+// find the entries in 'fit' which match entries in 'gal'
+// return an index from gal -> fit (for gal[i], fit[index[i]] is a match)
+int *join_IDs (GalPhotIDset *gal, GalPhotIDset *fit) {
   
-  off_t i, j, first_j, I, J, *N1, *N2, Nmatch, NMATCH, DMATCH;
+  off_t ifit, igal, first_ifit, Ifit, Igal, *seq_fit, *seq_gal, Nmatch, NMATCH;
   opihi_int dID;
 
-  NMATCH = MAX(MAX(0.01*ID1->Nelements, 0.01*ID2->Nelements), 100);
-  DMATCH = NMATCH;
+  NMATCH = gal->N;
+  ALLOCATE (idx_gal, off_t, gal->N);
 
-  ResetVector (index1, OPIHI_INT, NMATCH);
-  ResetVector (index2, OPIHI_INT, NMATCH);
+  ALLOCATE (seq_gal, off_t, gal->N);
+  ALLOCATE (seq_fit, off_t, fit->N);
 
-  ALLOCATE (N1, off_t, ID1->Nelements);
-  ALLOCATE (N2, off_t, ID2->Nelements);
+  for (i = 0; i < gal->N; i++) { seq_gal[i] = i; }
+  for (i = 0; i < fit->N; i++) { seq_fit[i] = i; }
 
-  for (i = 0; i < ID1->Nelements; i++) { N1[i] = i; }
-  for (i = 0; i < ID2->Nelements; i++) { N2[i] = i; }
-
-  sort_IDs_indexonly (ID1->elements.Int, N1, ID1->Nelements);
-  sort_IDs_indexonly (ID2->elements.Int, N2, ID2->Nelements);
+  // sort the sequences 
+  sort_IDs_seqonly (gal->ID, seq_gal, gal->N);
+  sort_IDs_seqonly (fit->ID, seq_fit, fit->N);
 
   Nmatch = 0;
-  for (i = j = 0; (i < ID1->Nelements) && (j < ID2->Nelements);) {
-    I = N1[i];
-    J = N2[j];
+  for (ifit = igal = 0; (igal < gal->N) && (ifit < fit->N);) {
+    Igal = seq_gal[i];
+    Ifit = seq_fit[j];
 
-    dID = ID1->elements.Int[I] - ID2->elements.Int[J];
+    dID = gal->ID[Igal] - fit->ID[Ifit];
 
-    if (dID < 0) { i++; continue; }
-    if (dID > 0) { j++; continue; }
+    if (dID < 0) { igal++; continue; }
+    if (dID > 0) { ifit++; continue; }
 
     // look for all matches of list2() to list1(i)
     // this allows for multiple values of ID1 or ID2
-    first_j = j;
-    for (j = first_j; (dID == 0) && (j < ID2->Nelements); j++) {
-      J = N2[j];
-      dID = ID1->elements.Int[I] - ID2->elements.Int[J];
+    first_ifit = ifit;
+    for (ifit = first_ifit; (dID == 0) && (ifit < fit->N); ifit++) {
+      Ifit = seq_fit[j];
+      dID = gal->ID[Igal] - fit->ID[Ifit];
       if (dID == 0) {
+	// XXX find the matching model types
 	index1->elements.Int[Nmatch] = I;
 	index2->elements.Int[Nmatch] = J;
Index: /branches/eam_branches/ipp-20150616/Ohana/src/addstar/src/loadgalphot_readstars.c
===================================================================
--- /branches/eam_branches/ipp-20150616/Ohana/src/addstar/src/loadgalphot_readstars.c	(revision 38510)
+++ /branches/eam_branches/ipp-20150616/Ohana/src/addstar/src/loadgalphot_readstars.c	(revision 38511)
@@ -42,9 +42,32 @@
 
   if (!gfits_scan (PHU, "MTNUM", "%d", 1, &ModelTypeN)) { myAbort ("fail"); }
+  ALLOCATE (ModelTypeName, char *, ModelTypeN);
+  ALLOCATE (ModelTypeNum,  int, ModelTypeN);
+  ALLOCATE (ModelTypeHash, int, ModelTypeN);
+
+  int tmpnumber, namehash[256][3];
+  for (i = 0; i < 256; i++) {
+    namehash[i][0] = -1;
+    namehash[i][1] = -1;
+    namehash[i][2] = -1;
+  }
+
+  char name[256], tmpname[256];
   for (i = 0; i < ModelTypeN; i++) {
     snprintf (name, 64, "MTNAM%02d", i);
-    if (!gfits_scan (PHU, name, "%s", 1, ModelTypeTmp)) { myAbort ("fail"); }
+    if (!gfits_scan (PHU, name, "%s", 1, tmpname)) { myAbort ("fail"); }
+    ModelTypeName[i] = strcreate (tmpname);
+    int found = FALSE;
+    int myHash = strhash (tmpname);
+    ModelTypeHash[i] = myHash;
+    for (j = 0; (j < 3) && !found; j++) {
+      if (namehash[myHash][j] != -1) continue;
+      found = TRUE;
+      namehash[myHash][j] = i;
+    }
+    myAssert (found, "hash conflict");
     snprintf (name, 64, "MTVAL%02d", i);
-    if (!gfits_scan (PHU, name, "%d", 1, &ModelTypeVal)) { myAbort ("fail"); }
+    if (!gfits_scan (PHU, name, "%d", 1, &tmpnumber)) { myAbort ("fail"); }
+    ModelTypeNum[i] = tmpnumber;
   }
 
@@ -71,5 +94,5 @@
   firstCol = TRUE;
   GET_COLUMN (xfit, ID_fit,         "IPP_IDET",      int);
-  GET_COLUMN (xfit, MODEL_TYPE_fit, "MODEL_TYPE",    char); NcharModel = Ncol;
+  GET_COLUMN (xfit, MODEL_TYPE_str, "MODEL_TYPE",    char); NcharModel = Ncol;
   GET_COLUMN (xfit, EXT_WIDTH_MAJ,  "EXT_WIDTH_MAJ", float);
   GET_COLUMN (xfit, EXT_WIDTH_MIN,  "EXT_WIDTH_MIN", float);
@@ -77,8 +100,23 @@
   GET_COLUMN (xfit, EXT_THETA_ERR,  "EXT_THETA_ERR", float);
   GET_COLUMN (xfit, INDEX,          "EXT_PAR_07",    float);
+  int Nfit = Nrow;
 
   // free the memory associated with the FITS files
   gfits_free_header (&header_xfit);
   gfits_free_table (&ftable_xfit);
+
+  // convert MODEL_TYPE_str to MODEL_TYPE_fit (transforming strings to values)
+  ALLOCATE (MODEL_TYPE_fit, int, Nfit);
+  for (i = 0; i < Nfit; i++) {
+    int myHash = strhash (MODEL_TYPE_str[i]);
+    int found = FALSE;
+    for (j = 0; !found && (j < 3); j++) {
+      int n = namehash[myHash][j];
+      if (strcmp(ModelTypeName[n], MODEL_TYPE_str[i])) continue;
+      MODEL_TYPE_fit[i] = ModelTypeNum[n];
+      found = TRUE;
+    }
+    myAssert (found, "unknown model name? %s", MODEL_TYPE_str[i]);
+  }
 
   Header header_xgal;
@@ -117,7 +155,15 @@
   GET_COLUMN (xgal, FR_MINOR_MAX,  "FR_MINOR_MAX", float);
   GET_COLUMN (xgal, FR_MINOR_DEL,  "FR_MINOR_DEL", float);
+  Ngal = Nrow;
 
   // i need to match the two lists based on (ID_gal == ID_fit), (MODEL_TYPE_gal == MODEL_TYPE_fit)
-  join_IDs (ID_gal, ID_fit, index
+  GalPhotIDset fit, gal;
+  fit.ID   = ID_fit;
+  fit.type = MODEL_TYPE_fit;
+  fit.N    = Nfit;
+  gal.ID   = ID_gal;
+  gal.type = MODEL_TYPE_gal;
+  gal.N    = Ngal;
+  int *index = join_IDs (&gal, &fit);
 
   // free the memory associated with the FITS files
