Index: /branches/eam_branches/largefiles.20100314/Ohana/src/libdvo/src/mosaic_astrom.c
===================================================================
--- /branches/eam_branches/largefiles.20100314/Ohana/src/libdvo/src/mosaic_astrom.c	(revision 27423)
+++ /branches/eam_branches/largefiles.20100314/Ohana/src/libdvo/src/mosaic_astrom.c	(revision 27424)
@@ -1,3 +1,6 @@
 # include <dvo.h>
+
+off_t getDISentry (e_time start, e_time stop, e_time *startMos, off_t *indexMos, off_t Nmosaic);
+void SortDISindex (e_time *S, off_t *I, off_t N);
 
 /* chip-match table: j = ChipMatch[i], images[j] is DIS for images[i] WRP */
@@ -71,5 +74,5 @@
   if (strcmp(&images[entry].coords.ctype[4], "-WRP")) {
     /* not a wrp image, do nothing */
-    return (TRUE); /* error or not */
+    return (TRUE); /* error or not? */
   }
 
@@ -85,5 +88,5 @@
 }
 
-int BuildChipMatch (Image *images, off_t Nimages) {
+int BuildChipMatch_old (Image *images, off_t Nimages) {
 
   off_t i, j, NDIS;
@@ -131,2 +134,97 @@
   return (TRUE);
 }
+
+int BuildChipMatch (Image *images, off_t Nimages) {
+
+  off_t i, j, NDIS;
+
+  if (DISentry != NULL) free (DISentry);
+  if (DIStzero != NULL) free (DIStzero);
+  if (ChipMatch != NULL) free (ChipMatch);
+
+  // allocate containers for DIS indexing
+  Ndis = 0;
+  NDIS = 100;
+  ALLOCATE (DISentry, off_t, NDIS);
+  ALLOCATE (DIStzero, e_time, NDIS);
+
+  // find all DIS images, save tzero (& instrument) 
+  for (i = 0; i < Nimages; i++) {
+    if (strcmp(&images[i].coords.ctype[4], "-DIS")) continue;
+    DISentry[Ndis] = i;
+    DIStzero[Ndis] = images[i].tzero;
+    Ndis ++;
+    if (Ndis >= NDIS) {
+      NDIS += 100;
+      REALLOCATE (DISentry, off_t, NDIS);
+      REALLOCATE (DIStzero, e_time, NDIS);
+    }
+  }
+
+  // sort the index, start, and stop by the start times:
+  SortDISindex (DIStzero, DISentry, Ndis);
+
+  /* find all matched WRP images */
+  ALLOCATE (ChipMatch, off_t, Nimages);
+  for (i = 0; i < Nimages; i++) {
+    ChipMatch[i] = -1;
+    if (strcmp(&images[i].coords.ctype[4], "-WRP")) continue;
+
+    j = getDISentry (images[i].tzero, images[i].tzero + (int) images[i].exptime, DIStzero, DISentry, Ndis);
+    if (j == -1) {
+      fprintf (stderr, "WARNING: can't find matching mosaic \n");
+      ChipMatch[i] = -2;
+      continue;
+    }
+    if (j >= Nimages) abort();
+
+    ChipMatch[i] = j;
+  }
+  return (TRUE);
+}
+
+off_t getDISentry (e_time start, e_time stop, e_time *startMos, off_t *indexMos, off_t Nmosaic) {
+
+  // use bisection to find the overlapping mosaic
+
+  off_t Nlo, Nhi, N;
+
+  // find the last mosaic before start
+  Nlo = 0; Nhi = Nmosaic;
+  while (Nhi - Nlo > 10) {
+    N = 0.5*(Nlo + Nhi);
+    if (startMos[N] < start) {
+      Nlo = MAX(N, 0);
+    } else {
+      Nhi = MIN(N + 1, Nmosaic);
+    }
+  }
+
+  // check for the matched mosaic starting from Nlo 
+  // we may have to go much beyond Nlo since stop is not sorted
+  // can we use a sorted version of stop to check when we are beyond the valid range??
+  for (N = Nlo; N < Nmosaic; N++) { 
+    if (startMos[N] < start) continue;
+    if (startMos[N] > stop) return (-1);
+    return (indexMos[N]);
+  }
+
+  return (-1);
+}
+
+// sort two times vectors and an index by first time vector
+void SortDISindex (e_time *S, off_t *I, off_t N) {
+
+# define SWAPFUNC(A,B){ e_time tmp_t; off_t tmp_i; \
+  tmp_t = S[A]; S[A] = S[B]; S[B] = tmp_t; \
+  tmp_i = I[A]; I[A] = I[B]; I[B] = tmp_i; \
+}
+# define COMPARE(A,B)(S[A] < S[B])
+
+  OHANA_SORT (N, COMPARE, SWAPFUNC);
+
+# undef SWAPFUNC
+# undef COMPARE
+
+}
+
