Index: /trunk/Ohana/src/addstar/Makefile
===================================================================
--- /trunk/Ohana/src/addstar/Makefile	(revision 5228)
+++ /trunk/Ohana/src/addstar/Makefile	(revision 5229)
@@ -25,4 +25,5 @@
 $(SRC)/airmass.$(ARCH).o \
 $(SRC)/args.$(ARCH).o \
+$(SRC)/build_links.$(ARCH).o \
 $(SRC)/calibrate.$(ARCH).o \
 $(SRC)/check_permissions.$(ARCH).o \
@@ -31,4 +32,5 @@
 $(SRC)/edge_check.$(ARCH).o \
 $(SRC)/find_matches.$(ARCH).o \
+$(SRC)/find_matches_closest.$(ARCH).o \
 $(SRC)/find_matches_refstars.$(ARCH).o \
 $(SRC)/find_subset.$(ARCH).o \
Index: /trunk/Ohana/src/addstar/doc/Changes.txt
===================================================================
--- /trunk/Ohana/src/addstar/doc/Changes.txt	(revision 5228)
+++ /trunk/Ohana/src/addstar/doc/Changes.txt	(revision 5229)
@@ -1,4 +1,26 @@
 
-2005.02.24 : I am adding the mosaic two-level astrometry information to the Image table.
+2005.10.04
+	- moved measure/missing list manipulation to separate functions
+	- added concept of sorted / unsorted measure catalog
+	- defined build_meas_links and reorder_measure,missing
+	- some cleanup of both find_matches.c and find_matches_closest.c
+
+2005.10.03:
+	- dropping GSCRegion *region entry from find_matches (unused!)
+	- adding function find_matches_closest (alternate matches)
+
+2005.08.19:
+	changed load_photcode to handle CATMODE and CATFORMAT variations
+	- addstar.h: added CATMODE and CATFORMAT globals
+	- ConfigInit: read CATMODE and CATFORMAT from config
+	- gcatalog: set catalog.catmode from CATMODE
+	- mkcatalog: set CATFORMAT and CATMODE for new catalog
+	- wcatalog: set CATFORMAT for new catalog
+	
+	using full photometry conversions in find_matches
+	added SetZeroPoint to gstars to enable phot conversions
+	
+2005.08.15:
+	cleanup of the minor Wall,Werror messages
 
 2005.07.06 : current release is addstar-1.1
@@ -21,16 +43,4 @@
         need to know about the mysql backend interface.  
 
-2005.08.15:
-	cleanup of the minor Wall,Werror messages
+2005.02.24 : I am adding the mosaic two-level astrometry information to the Image table.
 
-2005.08.19:
-	changed load_photcode to handle CATMODE and CATFORMAT variations
-	- addstar.h: added CATMODE and CATFORMAT globals
-	- ConfigInit: read CATMODE and CATFORMAT from config
-	- gcatalog: set catalog.catmode from CATMODE
-	- mkcatalog: set CATFORMAT and CATMODE for new catalog
-	- wcatalog: set CATFORMAT for new catalog
-	
-	using full photometry conversions in find_matches
-	added SetZeroPoint to gstars to enable phot conversions
-	
Index: /trunk/Ohana/src/addstar/doc/notes.txt
===================================================================
--- /trunk/Ohana/src/addstar/doc/notes.txt	(revision 5228)
+++ /trunk/Ohana/src/addstar/doc/notes.txt	(revision 5229)
@@ -1,2 +1,10 @@
+
+- measure <-> average matches and reordering
+
+  next[i] = i + 1
+  
+
+  
+
 
 2005.03.07 : notes related to new version of addstar
Index: /trunk/Ohana/src/addstar/include/addstar.h
===================================================================
--- /trunk/Ohana/src/addstar/include/addstar.h	(revision 5228)
+++ /trunk/Ohana/src/addstar/include/addstar.h	(revision 5229)
@@ -102,4 +102,6 @@
 int REPLACE;
 int ONLY_MATCH;
+int CLOSEST;
+int REORDER;
 
 int MODE;
@@ -110,5 +112,5 @@
 
 /*** addstar prototypes ***/
-void       AddToCalibration       PROTO((Average *average, Measure *measure, Measure *new, int Nstar));
+void       AddToCalibration       PROTO((Average *average, Measure *measure, Measure *new, int *next, int Nstar));
 void       ConfigInit             PROTO((int *argc, char **argv));
 void       FindCalibration        PROTO((Image *image));
@@ -132,4 +134,5 @@
 int        edge_check             PROTO((double *x1, double *y1, double *x2, double *y2));
 void       find_matches           PROTO((GSCRegion *region, Stars *stars, int Nstars, Catalog *catalog, Image *image, Image *overlap, int Noverlap));
+void       find_matches_closest   PROTO((GSCRegion *region, Stars *stars, int Nstars, Catalog *catalog, Image *image, Image *overlap, int Noverlap));
 void       find_matches_refstars  PROTO((GSCRegion *region, Stars **stars, int Nstars, Catalog *catalog));
 Stars    **find_subset            PROTO((GSCRegion *region, Stars *stars, int Nstars, int *NSTARS));
@@ -182,4 +185,12 @@
 void       fsort2                 PROTO((float *X, float *Y, int N));
 
+int *init_measure_links (Average *average, int Naverage, Measure *measure, int Nmeasure);
+int *init_missing_links (Average *average, int Naverage, Missing *missing, int Nmissing);
+int add_meas_link (Average *average, int *next, int Nmeasure);
+int add_miss_link (Average *average, int *next, int Nmissing);
+int *build_measure_links (Average *average, int Naverage, Measure *measure, int Nmeasure);
+Measure *reorder_measure (Average *average, int Naverage, Measure *measure, int Nmeasure, int *next);
+Missing *reorder_missing (Average *average, int Naverage, Missing *missing, int Nmissing, int *next_miss);
+
 /** 
   there is an inconsistency to be resolved: fixed structures (like Image)
Index: /trunk/Ohana/src/addstar/src/ConfigInit.c
===================================================================
--- /trunk/Ohana/src/addstar/src/ConfigInit.c	(revision 5228)
+++ /trunk/Ohana/src/addstar/src/ConfigInit.c	(revision 5229)
@@ -62,4 +62,5 @@
   }
 
+  /* default mode, format, if not specified */
   if (*CATMODE == 0) strcpy (CATMODE, "RAW");
   if (*CATFORMAT == 0) strcpy (CATFORMAT, "ELIXIR");
Index: /trunk/Ohana/src/addstar/src/addstar.c
===================================================================
--- /trunk/Ohana/src/addstar/src/addstar.c	(revision 5228)
+++ /trunk/Ohana/src/addstar/src/addstar.c	(revision 5229)
@@ -61,5 +61,9 @@
     case M_IMAGE:
       Nsubset = Nstars;
-      find_matches (&regions[i], stars, Nstars, &catalog, &image, overlap, Noverlap);
+      if (CLOSEST) {
+	find_matches_closest (&regions[i], stars, Nstars, &catalog, &image, overlap, Noverlap);
+      } else {
+	find_matches (&regions[i], stars, Nstars, &catalog, &image, overlap, Noverlap);
+      }
       break;
     case M_REFCAT:
Index: /trunk/Ohana/src/addstar/src/args.c
===================================================================
--- /trunk/Ohana/src/addstar/src/args.c	(revision 5228)
+++ /trunk/Ohana/src/addstar/src/args.c	(revision 5229)
@@ -22,4 +22,5 @@
   fprintf (stderr, "  -missed               	  : skipped 'missed' entries\n");
   fprintf (stderr, "  -replace              	  : replace time/photcode measurements (no duplication)\n");
+  fprintf (stderr, "  -closest             	  : use closest-star algorith\n");
   fprintf (stderr, "  -image                	  : only insert image data\n");
   fprintf (stderr, "  -cal                  	  : perform zero-point calibration\n");
@@ -144,4 +145,16 @@
     remove_argument (N, &argc, argv);
   }
+  /* use 'closest star' matching, rather than traditional method */
+  CLOSEST = FALSE;
+  if ((N = get_argument (argc, argv, "-closest"))) {
+    CLOSEST = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+  /* only add new rows (-update) or re-write complete measure table */
+  REORDER = TRUE;
+  if ((N = get_argument (argc, argv, "-update"))) {
+    REORDER = FALSE;
+    remove_argument (N, &argc, argv);
+  }
   /* only add image potion to image table */
   ONLY_IMAGES = FALSE;
Index: /trunk/Ohana/src/addstar/src/build_links.c
===================================================================
--- /trunk/Ohana/src/addstar/src/build_links.c	(revision 5229)
+++ /trunk/Ohana/src/addstar/src/build_links.c	(revision 5229)
@@ -0,0 +1,144 @@
+# include "addstar.h"
+
+/* build the initial links assuming the table is re-ordered */
+int *init_measure_links (Average *average, int Naverage, Measure *measure, int Nmeasure) {
+
+  int i, j, N;
+  int *next;
+
+  N = 0;
+
+  ALLOCATE (next, int, Nmeasure);
+  for (i = 0; i < Naverage; i++, N++) {
+    for (j = 0; j < average[i].Nm - 1; j++, N++) {
+      next[N] = N + 1;
+    }
+    next[N] = -1;
+    if (N >= Nmeasure) {
+      fprintf (stderr, "overflow in init_measure_links\n");
+      abort ();
+    }
+  }
+  return (next);
+}
+
+/* build the initial links assuming the table is re-ordered */
+int *init_missing_links (Average *average, int Naverage, Missing *missing, int Nmissing) {
+
+  int i, j, N;
+  int *next;
+
+  N = 0;
+
+  ALLOCATE (next, int, Nmissing);
+  for (i = 0; i < Naverage; i++) {
+    for (j = 0; j < average[i].Nn - 1; j++, N++) {
+      next[N] = N + 1;
+    }
+    if (average[i].Nn > 0) {
+      next[N] = -1;
+      if (N >= Nmissing) {
+	fprintf (stderr, "overflow in init_missing_links");
+	abort ();
+      }
+      N++;
+    }
+
+  }
+  return (next);
+}
+
+int add_meas_link (Average *average, int *next, int Nmeasure) {
+
+  int k, m;
+
+  m = average[0].offset;  
+  for (k = 0; k < average[0].Nm - 1; k++) m = next[m];
+  /* set up references */
+  next[Nmeasure] = -1;
+  next[m] = Nmeasure;
+  return (TRUE);
+}
+
+int add_miss_link (Average *average, int *next, int Nmissing) {
+
+  int k, m;
+
+  /* there may be 0 Nmiss; this is not true for Nmeas */
+  if (average[0].Nn < 1) {
+    average[0].missing = Nmissing;
+    next[Nmissing] = -1;
+    return (TRUE);
+  }
+
+  m = average[0].missing;  
+  for (k = 0; k < average[0].Nn - 1; k++) m = next[m];
+  /* set up references */
+  next[Nmissing] = -1;
+  next[m] = Nmissing;
+  return (TRUE);
+}
+
+int *build_measure_links (Average *average, int Naverage, Measure *measure, int Nmeasure) {
+
+  int m, k, Nm, averef;
+  int *next;
+
+  ALLOCATE (next, int, Nmeasure);
+
+  for (Nm = 0; Nm < Nmeasure; Nm++) {
+    next[Nm] = -1;
+    averef = measure[Nm].averef;
+    m = average[averef].offset;  
+    for (k = 0; next[m] != -1; k++) {
+      m = next[m];
+    }
+    if (m == Nm) continue;
+    next[m] = Nm;
+  }
+  return (next);
+}
+
+/* Missing does not carry enough information to reconsruct the links
+   we must always save the missing table, if it exists */
+
+Measure *reorder_measure (Average *average, int Naverage, Measure *measure, int Nmeasure, int *next) {
+
+  int i, k, n, N;
+  Measure *tmpmeasure;
+
+  /* fix order of Measure (memory intensive, but fast) */
+  N = 0; 
+  ALLOCATE (tmpmeasure, Measure, Nmeasure);
+  for (i = 0; i < Naverage; i++) {
+    n = average[i].offset;
+    average[i].offset = N;
+    for (k = 0; k < average[i].Nm; k++, N++) {
+      tmpmeasure[N] = measure[n]; 
+      tmpmeasure[N].averef = i;
+      n = next[n];
+    }
+  }
+  free (measure);
+  return (tmpmeasure);
+}
+
+Missing *reorder_missing (Average *average, int Naverage, Missing *missing, int Nmissing, int *next) {
+
+  int i, k, n, N;
+  Missing *tmpmissing;
+
+  /* fix order of Missing (memory intensive, but fast) */
+  N = 0; 
+  ALLOCATE (tmpmissing, Missing, Nmissing);
+  for (i = 0; i < Naverage; i++) {
+    n = average[i].missing;
+    average[i].missing = N;
+    for (k = 0; k < average[i].Nn; k++, N++) {
+      tmpmissing[N] = missing[n]; 
+      n = next[n];
+    }
+  }
+  free (missing);
+  return (tmpmissing);
+}
Index: /trunk/Ohana/src/addstar/src/calibrate.c
===================================================================
--- /trunk/Ohana/src/addstar/src/calibrate.c	(revision 5228)
+++ /trunk/Ohana/src/addstar/src/calibrate.c	(revision 5229)
@@ -41,10 +41,8 @@
 }
 
-/* this does not use the linked list to navigate the measure structure
-   this is OK for old measures, but will break for entries which have
-   already added a new measure to the list.  */
-void AddToCalibration (Average *average, Measure *measure, Measure *new, int Nstar) {
+/* use the linked list to navigate the measures; safe for unsorted measures */
+void AddToCalibration (Average *average, Measure *measure, Measure *new, int *next, int Nstar) {
 
-  int i, found0, found1, found2;
+  int i, m, found0, found1, found2;
   float CalM0, CalM1, CalM2, dCalM;
   short CalC0, CalC1, CalC2;
@@ -57,17 +55,18 @@
   CalC2 = thiscode[0].c2;
 
+  m = average[0].offset;
   for (i = 0; i < average[0].Nm; i++) {
-    if (measure[0].source == CalC0) { 
+    if (measure[m].source == CalC0) { 
       found0 = TRUE; 
-      CalM0  = measure[i].M_PS; 
-      dCalM  = measure[i].dM_PS; 
+      CalM0  = measure[m].M_PS; 
+      dCalM  = measure[m].dM_PS; 
     }
-    if (measure[i].source == CalC1) { 
+    if (measure[m].source == CalC1) { 
       found1 = TRUE; 
-      CalM1  = measure[i].M_PS; 
+      CalM1  = measure[m].M_PS; 
     }
-    if (measure[i].source == CalC2) { 
+    if (measure[m].source == CalC2) { 
       found2 = TRUE; 
-      CalM2  = measure[i].M_PS; 
+      CalM2  = measure[m].M_PS; 
     }
     if (found0 && found1 && found2) {
@@ -75,5 +74,5 @@
       return;
     }
-    /* n = next[n]; - if we use this, we need to pass in measure[0] above */
+    m = next[m];
   }
   return;
Index: /trunk/Ohana/src/addstar/src/find_matches.c
===================================================================
--- /trunk/Ohana/src/addstar/src/find_matches.c	(revision 5228)
+++ /trunk/Ohana/src/addstar/src/find_matches.c	(revision 5229)
@@ -3,15 +3,17 @@
 void find_matches (GSCRegion *region, Stars *stars, int Nstars, Catalog *catalog, Image *image, Image *overlap, int Noverlap) {
 
-  int i, j, k, n, m, N, J;
+  int i, j, n, N, J;
   double X, Y, RADIUS, RADIUS2, secz;
   float *X1, *Y1, *X2, *Y2;
   float dX, dY, dR;
-  int *N1, *N2,  *next, *next_miss, last, last_miss;
+  int *N1, *N2,  *next_meas, *next_miss;
   int Nave, NAVE, Nmeas, NMEAS, Nmiss, NMISS, Nmatch;
-  Measure *tmpmeasure;
-  Missing *tmpmissing;
   Coords tcoords;
   int Nsecfilt, Nsec;
   float Mcat, *Mval, MTIME;
+  double dtime;
+  struct timeval start, stop;
+
+  gettimeofday (&start, NULL);
 
   /* photcode data - must by of type DEP, (PRI, SEC) - probably should restrict to DEP */
@@ -28,24 +30,15 @@
 
   /** allocate local arrays (catalog) **/
-  Nave = catalog[0].Naverage;
-  NAVE = Nave + 1000;
+  NAVE = Nave = catalog[0].Naverage;
   ALLOCATE (X2, float, NAVE);
   ALLOCATE (Y2, float, NAVE);
   ALLOCATE (N2, int,   NAVE);
   ALLOCATE (catalog[0].found, int, NAVE);
-  REALLOCATE (catalog[0].average, Average, NAVE);
-  REALLOCATE (catalog[0].secfilt, SecFilt, NAVE*catalog[0].Nsecfilt);
   /* for secfilt j and star i, secfilt[i*Nsecfilt+j] */
 
+  /* internal counters */
   Nmatch = 0;
-  Nmeas = catalog[0].Nmeasure;
-  NMEAS = Nmeas + 1000;
-  ALLOCATE (next, int, NMEAS);
-  REALLOCATE (catalog[0].measure, Measure, NMEAS);
-  
-  Nmiss = catalog[0].Nmissing;
-  NMISS = Nmiss + 1000;
-  ALLOCATE (next_miss, int, NMISS);
-  REALLOCATE (catalog[0].missing, Missing, NMISS);
+  NMEAS = Nmeas = catalog[0].Nmeasure;
+  NMISS = Nmiss = catalog[0].Nmissing;
   
   /* project onto rectilinear grid with 1 arcsec pixels */
@@ -67,4 +60,5 @@
   }
 
+  /* build spatial index (RA sort) */
   for (i = 0; i < Nstars; i++) {
     fRD_to_XY (&X1[i], &Y1[i], stars[i].R, stars[i].D, &tcoords);
@@ -73,4 +67,5 @@
   if (Nstars > 1) sort_lists (X1, Y1, N1, Nstars);
   
+  /* build spatial index (RA sort) */
   for (i = 0; i < Nave; i++) {
     fRD_to_XY (&X2[i], &Y2[i], catalog[0].average[i].R_PS, catalog[0].average[i].D_PS, &tcoords);
@@ -80,16 +75,12 @@
   if (Nave > 1) sort_lists (X2, Y2, N2, Nave);
 
-  /* set up pointers for linked list of measurements */
-  for (i = 0; i < Nmeas - 1; i++) {
-    next[i] = i+1;
-  }
-  next[i] = -1;
-  last = i;
-
-  for (i = 0; i < Nmiss - 1; i++) {
-    next_miss[i] = i+1;
-  }
-  next_miss[i] = -1;
-  last_miss = i;
+  /* set up pointers for linked list of measure, missing */
+  if (catalog[0].ordered) {
+    next_meas = init_measure_links (catalog[0].average, Nave, catalog[0].measure, Nmeas);
+  } else {
+    next_meas = build_measure_links (catalog[0].average, Nave, catalog[0].measure, Nmeas);
+  }    
+  next_miss = init_missing_links (catalog[0].average, Nave, catalog[0].missing, Nmiss);
+  /* missing MUST be written ordered, or not at all */
 
   /* choose a radius for matches */
@@ -102,13 +93,10 @@
 
   /* correct instrumental mags for exposure time */
-  if (image[0].exptime > 0) {
-    MTIME = 2.500*log10(image[0].exptime);
-  } else {
-    MTIME = 0;
-  }
+  MTIME = (image[0].exptime > 0) ? 2.500*log10(image[0].exptime) : 0.0;
 
   /** find matched stars **/
   for (i = j = 0; (i < Nstars) && (j < Nave); ) {
     
+    /* negative dX: j is too large */
     dX = X1[i] - X2[j];
     if (dX <= -2*RADIUS) {
@@ -116,4 +104,5 @@
       continue;
     }
+    /* positive dX, i is too large */
     if (dX >= 2*RADIUS) {
       j++;
@@ -121,5 +110,5 @@
     }
 
-    /* negative dX: j is too large, positive dX, i is too large */
+    /* within match range; look for matches */
     for (J = j; (dX > -2*RADIUS) && (J < Nave); J++) {
       dX = X1[i] - X2[J];
@@ -128,18 +117,18 @@
       if (dR > RADIUS2) continue;
 
+      /* make sure there is space for next entry */
+      if (Nmeas >= NMEAS) {
+	NMEAS = Nmeas + 1000;
+	REALLOCATE (next_meas, int, NMEAS);
+	REALLOCATE (catalog[0].measure, Measure, NMEAS);
+      }
+
       Nmatch ++;
       n = N2[J];
       N = N1[i];
-      m = catalog[0].average[n].offset;  
-
-      /** insert star in measurement list */
-      /* find last measurement of this star */
-      for (k = 0; k < catalog[0].average[n].Nm - 1; k++) m = next[m];
-      /* set up references */
-      next[Nmeas] = next[m];
-      next[m] = Nmeas;
-      /* last just was moved */
-      if (next[Nmeas] == -1) last = Nmeas;
-	
+
+      /* add to end of measurement list */
+      add_meas_link (&catalog[0].average[n], next_meas, Nmeas);
+
       /* calculate accurate per-star airmass */
       secz = airmass (image[0].secz_PS, stars[N].R, stars[N].D, SiderealTime, Latitude);
@@ -171,8 +160,7 @@
       if (*Mval == NO_MAG) *Mval = Mcat;
 
-      /** this is a little tricky: the new measures are not in the measure sequence
-	  this call can run into the next star if we have had two measures found at this location. **/
+      /* adds the measurement to the calibration if appropriate color terms are found */
       if (CALIBRATE) {
-	AddToCalibration (&catalog[0].average[n], &catalog[0].measure[m], &catalog[0].measure[Nmeas], N);
+	AddToCalibration (&catalog[0].average[n], catalog[0].measure, &catalog[0].measure[Nmeas], next_meas, N);
       }
 
@@ -196,14 +184,8 @@
 	catalog[0].found[n] = Nmeas;
       }
-
       catalog[0].average[n].Nm ++;
       Nmeas ++;
-      if (Nmeas == NMEAS) {
-	NMEAS = Nmeas + 1000;
-	REALLOCATE (next, int, NMEAS);
-	REALLOCATE (catalog[0].measure, Measure, NMEAS);
-      }
-
-      update_coords (&catalog[0].average[n], &catalog[0].measure[0], next);
+
+      update_coords (&catalog[0].average[n], &catalog[0].measure[0], next_meas);
     }
     i++;
@@ -215,22 +197,15 @@
     n = N2[j];
     if (catalog[0].found[n] < 0) { 
+      /* make sure there is space for next entry */
+      if (Nmiss >= NMISS) {
+	NMISS = Nmiss + 1000;
+	REALLOCATE (next_miss, int, NMISS);
+	REALLOCATE (catalog[0].missing, Missing, NMISS);
+      }
+
       /* should the catalog star be on this image? project into image coords */
       if (!in_image (catalog[0].average[n].R_PS, catalog[0].average[n].D_PS, image)) continue;
-      /* find last missing meas */
-      if (catalog[0].average[n].Nn < 1) { /* no previous missing obs */
-	catalog[0].average[n].missing = Nmiss;
-	next_miss[last_miss] = Nmiss;
-	next_miss[Nmiss] = -1;
-	last_miss = Nmiss;
-      } else {
-	m = catalog[0].average[n].missing;
-	for (k = 0; k < catalog[0].average[n].Nn - 1; k++)
-	  m = next_miss[m];
-	next_miss[Nmiss] = next_miss[m];
-	next_miss[m] = Nmiss;
-	if (next_miss[Nmiss] == -1) { /* last just was moved */
-	  last_miss = Nmiss;
-	}
-      }
+      add_miss_link (&catalog[0].average[n], next_miss, Nmiss);
+
       /* calculate time of exposure for this coordinate in the image */
       RD_to_XY (&X, &Y, catalog[0].average[n].R_PS, catalog[0].average[n].D_PS, &image[0].coords);	  
@@ -238,9 +213,4 @@
       catalog[0].average[n].Nn ++;
       Nmiss ++;
-      if (Nmiss == NMISS) {
-	NMISS = Nmiss + 1000;
-	REALLOCATE (next_miss, int, NMISS);
-	REALLOCATE (catalog[0].missing, Missing, NMISS);
-      }
     }
   }
@@ -248,4 +218,16 @@
   /* incorporate unmatched image stars, if this star is in field of this catalog */
   for (i = 0; (i < Nstars) && !ONLY_MATCH; i++) {
+    /* make sure there is space for next entry */
+    if (Nmeas >= NMEAS) {
+      NMEAS = Nmeas + 1000;
+      REALLOCATE (next_meas, int, NMEAS);
+      REALLOCATE (catalog[0].measure, Measure, NMEAS);
+    }
+    if (Nave >= NAVE) {
+      NAVE = Nave + 1000;
+      REALLOCATE (catalog[0].average, Average, NAVE);
+      REALLOCATE (catalog[0].secfilt, SecFilt, NAVE*catalog[0].Nsecfilt);
+    }
+
     N = N1[i];
     if (stars[N].found >= 0) continue;
@@ -297,12 +279,14 @@
     /** now add references from all previous non-detection observations of this spot on the sky */
     for (j = 0; (j < Noverlap) && !SKIP_MISSED; j++) {
+      /* make sure there is space for next entry */
+      if (Nmiss >= NMISS) {
+	NMISS = Nmiss + 1000;
+	REALLOCATE (next_miss, int, NMISS);
+	REALLOCATE (catalog[0].missing, Missing, NMISS);
+      }
       if (!FindMosaicForImage (overlap, Noverlap, j)) continue;
       if (!in_image (catalog[0].average[Nave].R_PS, catalog[0].average[Nave].D_PS, &overlap[j])) continue;
-      if (catalog[0].average[Nave].Nn < 1) {
-	catalog[0].average[Nave].missing = Nmiss;
-      }
-      next_miss[last_miss] = Nmiss;
-      next_miss[Nmiss] = -1;
-      last_miss = Nmiss;
+      add_miss_link (&catalog[0].average[Nave], next_miss, Nmiss);
+
       /* get time of exposure of this portion of the image */
       RD_to_XY (&X, &Y, catalog[0].average[Nave].R_PS, catalog[0].average[Nave].D_PS, &overlap[j].coords);	  
@@ -310,27 +294,10 @@
       catalog[0].average[Nave].Nn ++;
       Nmiss ++;
-      if (Nmiss == NMISS) {
-	NMISS = Nmiss + 1000;
-	REALLOCATE (next_miss, int, NMISS);
-	REALLOCATE (catalog[0].missing, Missing, NMISS);
-      }
     }
 
     stars[N].found = Nmeas;
-    next[last] = Nmeas;
-    next[Nmeas] = -1;
-    last = Nmeas;
+    next_meas[Nmeas] = -1;
     Nmeas ++;
-    if (Nmeas == NMEAS) {
-      NMEAS = Nmeas + 1000;
-      REALLOCATE (next, int, NMEAS);
-      REALLOCATE (catalog[0].measure, Measure, NMEAS);
-    }
     Nave ++;
-    if (Nave == NAVE) {
-      NAVE = Nave + 1000;
-      REALLOCATE (catalog[0].average, Average, NAVE);
-      REALLOCATE (catalog[0].secfilt, SecFilt, NAVE*catalog[0].Nsecfilt);
-    }
   }
       
@@ -338,35 +305,23 @@
   REALLOCATE (catalog[0].average, Average, Nave);
   REALLOCATE (catalog[0].measure, Measure, Nmeas);
+  REALLOCATE (catalog[0].missing, Missing, Nmiss);
  
-  /* fix order of Measure (memory intensive, but fast) */
-  N = 0; 
-  ALLOCATE (tmpmeasure, Measure, Nmeas);
-  for (i = 0; i < Nave; i++) {
-    n = catalog[0].average[i].offset;
-    catalog[0].average[i].offset = N;
-    for (k = 0; k < catalog[0].average[i].Nm; k++, N++) {
-      tmpmeasure[N] = catalog[0].measure[n]; 
-      tmpmeasure[N].averef = i;
-      n = next[n];
-    }
-  }
-  free (catalog[0].measure);
-  catalog[0].measure = tmpmeasure;
-    
-  /* fix order of Missing (memory intensive, but fast) */
-  N = 0; 
-  ALLOCATE (tmpmissing, Missing, Nmiss);
-  for (i = 0; i < Nave; i++) {
-    if (catalog[0].average[i].Nn > 0) {
-      n = catalog[0].average[i].missing;
-      catalog[0].average[i].missing = N;
-      for (k = 0; k < catalog[0].average[i].Nn; k++, N++) {
-	tmpmissing[N] = catalog[0].missing[n]; 
-	n = next_miss[n];
-      }
-    }
-  }
-  free (catalog[0].missing);
-  catalog[0].missing = tmpmissing;
+  /* XXX EAM - temporary examination of next_meas
+  for (i = 0; i < 5; i++) {
+    m = catalog[0].average[i].offset;
+    for (j = 0; j < catalog[0].average[i].Nm; j++) {
+      fprintf (stderr, "this: %d (%f), next: %d\n", m, catalog[0].measure[m].M_PS, next_meas[m]);
+      m = next_meas[m];
+    }
+  } */
+
+  if (REORDER) {
+    catalog[0].measure = reorder_measure (catalog[0].average, Nave, catalog[0].measure, Nmeas, next_meas);
+    catalog[0].ordered = TRUE;
+  } else {
+    catalog[0].ordered = FALSE;
+  }
+  catalog[0].missing = reorder_missing (catalog[0].average, Nave, catalog[0].missing, Nmiss, next_miss);
+  /* missing is REQUIRED to be sorted */
 
   /* note stars which have been found in this catalog */
@@ -384,4 +339,10 @@
   catalog[0].Nmissing = Nmiss;
   if (VERBOSE) fprintf (stderr, "Nstars, Nave, Nmeas, Nmiss: %d %d %d %d, (%d matches)\n", Nstars, Nave, Nmeas, Nmiss, Nmatch);
+
+  gettimeofday (&stop, NULL);
+  dtime = DTIME (stop, start);
+  fprintf (stderr, "  match time %8.3f sec for %5d stars, %6d average\n", dtime, Nstars, Nave);
+
+  return;
 }
 
Index: /trunk/Ohana/src/addstar/src/find_matches_closest.c
===================================================================
--- /trunk/Ohana/src/addstar/src/find_matches_closest.c	(revision 5229)
+++ /trunk/Ohana/src/addstar/src/find_matches_closest.c	(revision 5229)
@@ -0,0 +1,359 @@
+# include "addstar.h"
+
+void find_matches_closest (GSCRegion *region, Stars *stars, int Nstars, Catalog *catalog, Image *image, Image *overlap, int Noverlap) {
+
+  int i, j, n, N, J;
+  double X, Y, RADIUS, RADIUS2, Rmin, secz;
+  float *X1, *Y1, *X2, *Y2;
+  float dX, dY, dR;
+  int *N1, *N2,  *next_meas, *next_miss;
+  int Nave, NAVE, Nmeas, NMEAS, Nmiss, NMISS, Nmatch, Jmin;
+  Coords tcoords;
+  int Nsecfilt, Nsec;
+  float Mcat, *Mval, MTIME;
+  double dtime;
+  struct timeval start, stop;
+
+  gettimeofday (&start, NULL);
+
+  /* photcode data - must by of type DEP, (PRI, SEC) - probably should restrict to DEP */
+  Nsecfilt = GetPhotcodeNsecfilt ();
+  Nsec = (thiscode[0].type == PHOT_DEP) ?
+    GetPhotcodeNsec (thiscode[0].equiv) :
+    GetPhotcodeNsec (thiscode[0].code);
+  /* this function requires incoming stars to have the same photcode */
+
+  /** allocate local arrays (stars) **/
+  ALLOCATE (X1, float, Nstars);
+  ALLOCATE (Y1, float, Nstars);
+  ALLOCATE (N1, int,   Nstars);
+
+  /** allocate local arrays (catalog) **/
+  NAVE = Nave = catalog[0].Naverage;
+  ALLOCATE (X2, float, NAVE);
+  ALLOCATE (Y2, float, NAVE);
+  ALLOCATE (N2, int,   NAVE);
+  ALLOCATE (catalog[0].found, int, NAVE);
+  /* for secfilt j and star i, secfilt[i*Nsecfilt+j] */
+
+  /* internal counters */
+  Nmatch = 0;
+  NMEAS = Nmeas = catalog[0].Nmeasure;
+  NMISS = Nmiss = catalog[0].Nmissing;
+  
+  /* project onto rectilinear grid with 1 arcsec pixels */
+  /* we keep the original crpix1,2 and crref1,2 */
+  /* for mosaic astrometry, the grid should be w.r.t. the tangent-plane, not chip coords */
+  if (!strcmp (&image[0].coords.ctype[4], "-WRP")) {
+    tcoords = MOSAIC[0];
+    tcoords.cdelt1 = tcoords.cdelt2 = 1.0 / 3600.0;
+    tcoords.pc1_1 = tcoords.pc2_2 = 1.0;
+    tcoords.pc1_2 = tcoords.pc2_1 = 0.0;
+    tcoords.Npolyterms = 1;
+    strcpy (tcoords.ctype, "RA---TAN");
+  } else {
+    tcoords = image[0].coords;
+    tcoords.cdelt1 = tcoords.cdelt2 = 1.0 / 3600.0;
+    tcoords.pc1_1 = tcoords.pc2_2 = 1.0;
+    tcoords.pc1_2 = tcoords.pc2_1 = 0.0;
+    strcpy (tcoords.ctype, "RA---TAN");
+  }
+
+  /* build spatial index (RA sort) */
+  for (i = 0; i < Nstars; i++) {
+    fRD_to_XY (&X1[i], &Y1[i], stars[i].R, stars[i].D, &tcoords);
+    N1[i] = i;
+  }
+  if (Nstars > 1) sort_lists (X1, Y1, N1, Nstars);
+  
+  /* build spatial index (RA sort) */
+  for (i = 0; i < Nave; i++) {
+    fRD_to_XY (&X2[i], &Y2[i], catalog[0].average[i].R_PS, catalog[0].average[i].D_PS, &tcoords);
+    N2[i] = i;
+    catalog[0].found[N2[i]] = -1;
+  }
+  if (Nave > 1) sort_lists (X2, Y2, N2, Nave);
+
+  /* set up pointers for linked list of measure, missing */
+  if (catalog[0].ordered) {
+    next_meas = init_measure_links (catalog[0].average, Nave, catalog[0].measure, Nmeas);
+  } else {
+    next_meas = build_measure_links (catalog[0].average, Nave, catalog[0].measure, Nmeas);
+  }    
+  next_miss = init_missing_links (catalog[0].average, Nave, catalog[0].missing, Nmiss);
+  /* missing MUST be written ordered, or not at all */
+
+  /* choose a radius for matches */
+  if (DEFAULT_RADIUS == 0) {
+    RADIUS = NSIGMA * 0.02 * image[0].cerror;  /* 0.02 corrects cerror to arcsec from storage units */
+  } else {
+    RADIUS = DEFAULT_RADIUS; /* provided by config */
+  }
+  RADIUS2 = RADIUS*RADIUS;
+
+  /* correct instrumental mags for exposure time */
+  MTIME = (image[0].exptime > 0) ? 2.500*log10(image[0].exptime) : 0.0;
+
+  /** find matched stars **/
+  for (i = j = 0; (i < Nstars) && (j < Nave); ) {
+    
+    /* negative dX: j is too large */
+    dX = X1[i] - X2[j];
+    if (dX <= -2*RADIUS) {
+      i++;
+      continue;
+    }
+    /* positive dX, i is too large */
+    if (dX >= 2*RADIUS) {
+      j++;
+      continue;
+    }
+
+    Jmin = -1;
+    Rmin = RADIUS2;
+    for (J = j; (dX > -2*RADIUS) && (J < Nave); J++) {
+      /* find closest match for this detection */
+      dX = X1[i] - X2[J];
+      dY = Y1[i] - Y2[J];
+      dR = dX*dX + dY*dY;
+      if (dR > RADIUS2) continue;
+      if (dR < Rmin) {
+	Rmin = dR;
+	Jmin  = J;
+      }
+    }
+
+    /* no match, try next detection */ 
+    if (Jmin == -1) {
+      i++;
+      continue;
+    }
+
+    /*** a match is found, add to average, measure ***/
+
+    /* make sure there is space for next entry */
+    if (Nmeas >= NMEAS) {
+      NMEAS = Nmeas + 1000;
+      REALLOCATE (next_meas, int, NMEAS);
+      REALLOCATE (catalog[0].measure, Measure, NMEAS);
+    }
+
+    Nmatch ++;
+    n = N2[Jmin];
+    N = N1[i];
+
+    /* add to end of measurement list */
+    add_meas_link (&catalog[0].average[n], next_meas, Nmeas);
+	
+    /* calculate accurate per-star airmass, if required */
+    secz = airmass (image[0].secz_PS, stars[N].R, stars[N].D, SiderealTime, Latitude);
+      
+    /** add measurements for this star **/
+    /** dR,dD now represent arcsec **/
+    catalog[0].measure[Nmeas].dR_PS       = 3600.0*(catalog[0].average[n].R_PS - stars[N].R);
+    catalog[0].measure[Nmeas].dD_PS       = 3600.0*(catalog[0].average[n].D_PS - stars[N].D);
+    catalog[0].measure[Nmeas].M_PS        = MIN (stars[N].M + MTIME, NO_MAG);
+    catalog[0].measure[Nmeas].dM_PS       = MIN (stars[N].dM, NO_ERR);  /* error in input files stored in thousandths of mag */
+    catalog[0].measure[Nmeas].Mcal_PS     = image[0].Mcal_PS;
+    catalog[0].measure[Nmeas].t           = image[0].tzero + 1e-4*stars[N].Y*image[0].trate;  /* trate is in 0.1 msec / row */
+    catalog[0].measure[Nmeas].averef      = n;
+    catalog[0].measure[Nmeas].source      = stars[N].code;  /* photcode */
+    catalog[0].measure[Nmeas].dophot      = stars[N].dophot;  
+    catalog[0].measure[Nmeas].flags       = 0;
+    catalog[0].measure[Nmeas].dt_PS       = MTIME;
+    catalog[0].measure[Nmeas].airmass_PS  = secz;
+
+    catalog[0].measure[Nmeas].Mgal_PS     = MIN (stars[N].Mgal + MTIME, NO_MAG);
+    catalog[0].measure[Nmeas].FWx         = MIN (100*stars[N].fx, NO_MAG);
+    catalog[0].measure[Nmeas].FWy         = MIN (100*stars[N].fy, NO_MAG);
+    catalog[0].measure[Nmeas].theta       = MIN ((255/360)*stars[N].df, NO_ERR);
+	
+    /* it is not valid to pass PRI/SEC/REF photcodes to this routine */
+    /* check for entries in the secfilt lists */
+    Mcat = PhotCat (&catalog[0].measure[Nmeas]);
+    Mval = (Nsec == -1) ? &catalog[0].average[n].M_PS : &catalog[0].secfilt[n*Nsecfilt+Nsec].M_PS;
+    if (*Mval == NO_MAG) *Mval = Mcat;
+
+    /* adds the measurement to the calibration if appropriate color terms are found */
+    if (CALIBRATE) {
+      AddToCalibration (&catalog[0].average[n], catalog[0].measure, &catalog[0].measure[Nmeas], next_meas, N);
+    }
+
+    /* if we choose to flag close encounters, see find_matches.c */
+    /* if we choose to calculate RA,DEC averages, see update_coords.c */
+
+    stars[N].found = Nmeas;
+    catalog[0].found[n] = Nmeas;
+    catalog[0].average[n].Nm ++;
+    Nmeas ++;
+    i++;
+  }
+
+  /** add reference for undetected catalog stars **/
+  if (!strcmp (&image[0].coords.ctype[4], "-WRP")) RegisterMosaic (MOSAIC);
+  for (j = 0; (j < Nave) && !SKIP_MISSED; j++) {
+    n = N2[j];
+    if (catalog[0].found[n] < 0) { 
+      /* make sure there is space for next entry */
+      if (Nmiss >= NMISS) {
+	NMISS = Nmiss + 1000;
+	REALLOCATE (next_miss, int, NMISS);
+	REALLOCATE (catalog[0].missing, Missing, NMISS);
+      }
+
+      /* should the catalog star be on this image? project into image coords */
+      if (!in_image (catalog[0].average[n].R_PS, catalog[0].average[n].D_PS, image)) continue;
+      add_miss_link (&catalog[0].average[n], next_miss, Nmiss);
+
+      /* calculate time of exposure for this coordinate in the image */
+      RD_to_XY (&X, &Y, catalog[0].average[n].R_PS, catalog[0].average[n].D_PS, &image[0].coords);	  
+      catalog[0].missing[Nmiss].t  = image[0].tzero + 1e-4*Y*image[0].trate;  /* trate is in 0.1 msec / row */
+      catalog[0].average[n].Nn ++;
+      Nmiss ++;
+    }
+  }
+
+  /** incorporate unmatched image stars, if this star is in field of this catalog **/
+  for (i = 0; (i < Nstars) && !ONLY_MATCH; i++) {
+    /* make sure there is space for next entry */
+    if (Nmeas >= NMEAS) {
+      NMEAS = Nmeas + 1000;
+      REALLOCATE (next_meas, int, NMEAS);
+      REALLOCATE (catalog[0].measure, Measure, NMEAS);
+    }
+    if (Nave >= NAVE) {
+      NAVE = Nave + 1000;
+      REALLOCATE (catalog[0].average, Average, NAVE);
+      REALLOCATE (catalog[0].secfilt, SecFilt, NAVE*catalog[0].Nsecfilt);
+    }
+
+    N = N1[i];
+    if (stars[N].found >= 0) continue;
+    if (!IN_CATALOG (stars[N].R, stars[N].D)) continue;
+
+    secz = airmass (image[0].secz_PS, stars[N].R, stars[N].D, SiderealTime, Latitude);
+
+    catalog[0].average[Nave].R_PS      = stars[N].R;
+    catalog[0].average[Nave].D_PS      = stars[N].D;
+    catalog[0].average[Nave].M_PS      = NO_MAG;
+    catalog[0].average[Nave].dM_PS     = NO_MAG;
+    catalog[0].average[Nave].Nm        = 1;
+    catalog[0].average[Nave].Nn        = 0;
+    catalog[0].average[Nave].Xp        = NO_MAG;
+    catalog[0].average[Nave].Xm        = NO_MAG;
+    catalog[0].average[Nave].Xg        = NO_MAG;
+    catalog[0].average[Nave].offset    = Nmeas;
+    catalog[0].average[Nave].missing   = -1;
+    catalog[0].average[Nave].code      = 0;
+
+    for (j = 0; j < Nsecfilt; j++) {
+      catalog[0].secfilt[Nave*Nsecfilt+j].M_PS  = NO_MAG;
+      catalog[0].secfilt[Nave*Nsecfilt+j].dM_PS = NO_MAG;
+      catalog[0].secfilt[Nave*Nsecfilt+j].Xm    = NO_MAG;
+    }
+
+    catalog[0].measure[Nmeas].dR_PS       = 0.0;
+    catalog[0].measure[Nmeas].dD_PS       = 0.0;
+    catalog[0].measure[Nmeas].M_PS        = MIN (stars[N].M + MTIME, NO_MAG);
+    catalog[0].measure[Nmeas].dM_PS       = MIN (stars[N].dM, NO_ERR);
+    catalog[0].measure[Nmeas].Mcal_PS  	  = image[0].Mcal_PS;
+    catalog[0].measure[Nmeas].t        	  = image[0].tzero + 1e-4*stars[N].Y*image[0].trate; /* trate is in 0.1 msec / row */
+    catalog[0].measure[Nmeas].averef   	  = Nave;
+    catalog[0].measure[Nmeas].source   	  = stars[N].code;  /* photcode */
+    catalog[0].measure[Nmeas].dophot   	  = stars[N].dophot;  
+    catalog[0].measure[Nmeas].flags    	  = 0;
+    catalog[0].measure[Nmeas].dt_PS    	  = MTIME;
+    catalog[0].measure[Nmeas].airmass_PS  = secz;
+
+    catalog[0].measure[Nmeas].Mgal_PS  	  = MIN (stars[N].Mgal + MTIME, NO_MAG);
+    catalog[0].measure[Nmeas].FWx      	  = MIN (100*stars[N].fx, NO_MAG);
+    catalog[0].measure[Nmeas].FWy      	  = MIN (100*stars[N].fy, NO_MAG);
+    catalog[0].measure[Nmeas].theta    	  = MIN ((255/360)*stars[N].df, NO_ERR);
+
+    Mcat = PhotCat (&catalog[0].measure[Nmeas]);
+    Mval = (Nsec == -1) ? &catalog[0].average[Nave].M_PS : &catalog[0].secfilt[Nave*Nsecfilt+Nsec].M_PS;
+    if (*Mval == NO_MAG) *Mval = Mcat;
+
+    /** now add references from all previous non-detection observations of this spot on the sky */
+    for (j = 0; (j < Noverlap) && !SKIP_MISSED; j++) {
+      /* make sure there is space for next entry */
+      if (Nmiss >= NMISS) {
+	NMISS = Nmiss + 1000;
+	REALLOCATE (next_miss, int, NMISS);
+	REALLOCATE (catalog[0].missing, Missing, NMISS);
+      }
+      if (!FindMosaicForImage (overlap, Noverlap, j)) continue;
+      if (!in_image (catalog[0].average[Nave].R_PS, catalog[0].average[Nave].D_PS, &overlap[j])) continue;
+      add_miss_link (&catalog[0].average[Nave], next_miss, Nmiss);
+
+      /* get time of exposure of this portion of the image */
+      RD_to_XY (&X, &Y, catalog[0].average[Nave].R_PS, catalog[0].average[Nave].D_PS, &overlap[j].coords);	  
+      catalog[0].missing[Nmiss].t  = overlap[j].tzero + 1e-4*Y*overlap[j].trate;  /* rough guess at time */
+      catalog[0].average[Nave].Nn ++;
+      Nmiss ++;
+    }
+
+    /* next[Nmeas] should always be -1 in this context (it is always the only
+       measurement for the star) */
+    stars[N].found = Nmeas;
+    next_meas[Nmeas] = -1;
+    Nmeas ++;
+    Nave ++;
+  }
+      
+  free (catalog[0].found);
+  REALLOCATE (catalog[0].average, Average, Nave);
+  REALLOCATE (catalog[0].measure, Measure, Nmeas);
+  REALLOCATE (catalog[0].missing, Missing, Nmiss);
+ 
+  /* XXX EAM - temporary examination of next_meas
+  for (i = 0; i < 5; i++) {
+    m = catalog[0].average[i].offset;
+    for (j = 0; j < catalog[0].average[i].Nm; j++) {
+      fprintf (stderr, "this: %d (%f), next: %d\n", m, catalog[0].measure[m].M_PS, next_meas[m]);
+      m = next_meas[m];
+    }
+  } */
+
+  if (REORDER) {
+    catalog[0].measure = reorder_measure (catalog[0].average, Nave, catalog[0].measure, Nmeas, next_meas);
+    catalog[0].ordered = TRUE;
+  } else {
+    catalog[0].ordered = FALSE;
+  }
+  catalog[0].missing = reorder_missing (catalog[0].average, Nave, catalog[0].missing, Nmiss, next_miss);
+  /* missing is REQUIRED to be sorted */
+
+  /* note stars which have been found in this catalog */
+  for (i = 0; i < Nstars; i++) {
+    if (stars[i].found > -1) {
+      stars[i].found = -2;
+    } else {
+      stars[i].found = -3;
+    }
+  }
+
+  /* check if the catalog has changed?  if no change, no need to write */
+  catalog[0].Naverage = Nave;
+  catalog[0].Nmeasure = Nmeas;
+  catalog[0].Nmissing = Nmiss;
+  if (VERBOSE) fprintf (stderr, "Nstars, Nave, Nmeas, Nmiss: %d %d %d %d, (%d matches)\n", Nstars, Nave, Nmeas, Nmiss, Nmatch);
+
+  gettimeofday (&stop, NULL);
+  dtime = DTIME (stop, start);
+  fprintf (stderr, "  match time %8.3f sec for %5d stars, %6d average\n", dtime, Nstars, Nave);
+
+  return;
+}
+
+/* 
+   notes:
+   
+   for finding if a catalog star is in an image or an image star is in the catalog:
+   
+   catalogs have boundaries defined by RA and DEC, but they may curve in projection
+   images have boundaries which are lines in pixels coords, but curve in RA and DEC
+   
+   catalog[0].found[Ncat] but stars[Nstar].found
+   
+*/
Index: /trunk/Ohana/src/addstar/src/gcatalog.c
===================================================================
--- /trunk/Ohana/src/addstar/src/gcatalog.c	(revision 5228)
+++ /trunk/Ohana/src/addstar/src/gcatalog.c	(revision 5229)
@@ -3,5 +3,5 @@
 int gcatalog (Catalog *catalog) {
   
-  int Nsecfilt;
+  int Nsecfilt, status;
   char mode;
 
@@ -14,4 +14,9 @@
     exit (1);
   }
+
+  /* should this be moved into save_catalog?? */
+  status = fits_scan (&catalog[0].header, "ORDERED", "%t", 1, &catalog[0].ordered);
+  if (!status) catalog[0].ordered = TRUE;
+  /* XXX EAM - is this a good choice?  should the default be 'FALSE'? */
 
   /* check Nsecfile value, update if needed */
Index: /trunk/Ohana/src/addstar/src/image-db.c
===================================================================
--- /trunk/Ohana/src/addstar/src/image-db.c	(revision 5228)
+++ /trunk/Ohana/src/addstar/src/image-db.c	(revision 5229)
@@ -40,5 +40,6 @@
 
   /* set the recommended mode */
-  if (!strcmp (CATMODE, "RAW")) {
+  db[0].mode = DVO_MODE_UNDEF;
+  if (!strcasecmp (CATMODE, "RAW")) {
     /* make header a fake image */
     db[0].header.bitpix   = 16;
@@ -49,17 +50,20 @@
     db[0].mode = DVO_MODE_RAW;
   }
-
-  if (!strcmp (CATMODE, "MEF") || !strcmp (CATMODE, "SPLIT")) {
+  if (!strcasecmp (CATMODE, "MEF") || !strcasecmp (CATMODE, "SPLIT")) {
     db[0].header.extend   = TRUE;
     fits_create_header (&db[0].header);
     db[0].mode = DVO_MODE_MEF;
   }
+  if (db[0].mode == DVO_MODE_UNDEF) {
+    fprintf (stderr, "invalid output catalog mode\n");
+    exit (1);
+  }
 
   /* set the recommended format */
   db[0].format = DVO_FORMAT_UNDEF;
-  if (!strcmp (CATFORMAT, "INTERNAL"))  db[0].format = DVO_FORMAT_INTERNAL;
-  if (!strcmp (CATFORMAT, "LONEOS"))    db[0].format = DVO_FORMAT_LONEOS;
-  if (!strcmp (CATFORMAT, "ELIXIR"))    db[0].format = DVO_FORMAT_ELIXIR;
-  if (!strcmp (CATFORMAT, "PANSTARRS")) db[0].format = DVO_FORMAT_PANSTARRS;
+  if (!strcasecmp (CATFORMAT, "INTERNAL"))  db[0].format = DVO_FORMAT_INTERNAL;
+  if (!strcasecmp (CATFORMAT, "LONEOS"))    db[0].format = DVO_FORMAT_LONEOS;
+  if (!strcasecmp (CATFORMAT, "ELIXIR"))    db[0].format = DVO_FORMAT_ELIXIR;
+  if (!strcasecmp (CATFORMAT, "PANSTARRS")) db[0].format = DVO_FORMAT_PANSTARRS;
   if (db[0].format == DVO_FORMAT_UNDEF) {
     fprintf (stderr, "invalid output catalog format\n");
Index: /trunk/Ohana/src/addstar/src/mkcatalog.c
===================================================================
--- /trunk/Ohana/src/addstar/src/mkcatalog.c	(revision 5228)
+++ /trunk/Ohana/src/addstar/src/mkcatalog.c	(revision 5229)
@@ -3,5 +3,6 @@
 void mkcatalog (GSCRegion *region, Catalog *catalog) {
   
-  char *line;
+  int length, status;
+  char *path, *root, *file, *line;
   time_t now;
 
@@ -10,8 +11,8 @@
   /* set the recommended CATFORMAT */
   catalog[0].catformat = DVO_FORMAT_UNDEF;
-  if (!strcmp (CATFORMAT, "INTERNAL"))  catalog[0].catformat = DVO_FORMAT_INTERNAL;
-  if (!strcmp (CATFORMAT, "LONEOS"))    catalog[0].catformat = DVO_FORMAT_LONEOS;
-  if (!strcmp (CATFORMAT, "ELIXIR"))    catalog[0].catformat = DVO_FORMAT_ELIXIR;
-  if (!strcmp (CATFORMAT, "PANSTARRS")) catalog[0].catformat = DVO_FORMAT_PANSTARRS;
+  if (!strcasecmp (CATFORMAT, "INTERNAL"))  catalog[0].catformat = DVO_FORMAT_INTERNAL;
+  if (!strcasecmp (CATFORMAT, "LONEOS"))    catalog[0].catformat = DVO_FORMAT_LONEOS;
+  if (!strcasecmp (CATFORMAT, "ELIXIR"))    catalog[0].catformat = DVO_FORMAT_ELIXIR;
+  if (!strcasecmp (CATFORMAT, "PANSTARRS")) catalog[0].catformat = DVO_FORMAT_PANSTARRS;
   if (catalog[0].catformat == DVO_FORMAT_UNDEF) {
     fprintf (stderr, "invalid output catalog format\n");
@@ -20,7 +21,12 @@
 
   /* set the recommended CATMODE */
-  catalog[0].catmode = DVO_MODE_RAW;
-  if (!strcmp (CATMODE, "RAW"))  catalog[0].catmode = DVO_MODE_RAW;
-  if (!strcmp (CATMODE, "MEF"))  catalog[0].catmode = DVO_MODE_MEF;
+  catalog[0].catmode = DVO_MODE_UNDEF;
+  if (!strcasecmp (CATMODE, "RAW"))  catalog[0].catmode = DVO_MODE_RAW;
+  if (!strcasecmp (CATMODE, "MEF"))  catalog[0].catmode = DVO_MODE_MEF;
+  if (!strcasecmp (CATMODE, "SPLIT"))  catalog[0].catmode = DVO_MODE_SPLIT;
+  if (catalog[0].catmode == DVO_MODE_UNDEF) {
+    fprintf (stderr, "invalid output catalog mode\n");
+    exit (1);
+  }
 
   fits_init_header (&catalog[0].header);
@@ -36,4 +42,55 @@
   fits_create_header (&catalog[0].header);
   
+  if (catalog[0].catmode == DVO_MODE_SPLIT) {
+    path = pathname (catalog[0].filename);
+    root = filerootname (catalog[0].filename);
+    length = strlen(path) + strlen(root) + 6;
+
+    /* define measure catalog file */
+    ALLOCATE (catalog[0].measure_catalog, Catalog, 1);
+    fits_init_header (&catalog[0].measure_catalog[0].header);
+    fits_create_header (&catalog[0].measure_catalog[0].header);
+    ALLOCATE (catalog[0].measure_catalog[0].filename, char, length);
+    sprintf (catalog[0].measure_catalog[0].filename, "%s/%s.cpm", path, root);
+    status = lock_catalog (catalog[0].measure_catalog, catalog[0].lockmode);
+    if (status != 2) {
+      fprintf (stderr, "error with file lock\n");
+      exit (2);
+    }
+    file = filebasename (catalog[0].measure_catalog[0].filename);
+    fits_modify (&catalog[0].header, "MEASURE", "%s", 1, file);
+    free (file);
+
+    /* define missing catalog file */
+    ALLOCATE (catalog[0].missing_catalog, Catalog, 1);
+    fits_init_header (&catalog[0].missing_catalog[0].header);
+    fits_create_header (&catalog[0].missing_catalog[0].header);
+    ALLOCATE (catalog[0].missing_catalog[0].filename, char, length);
+    sprintf (catalog[0].missing_catalog[0].filename, "%s/%s.cpn", path, root);
+    if (lock_catalog (catalog[0].missing_catalog, catalog[0].lockmode) != 2) {
+      fprintf (stderr, "error with file lock\n");
+      exit (2);
+    }
+    file = filebasename (catalog[0].missing_catalog[0].filename);
+    fits_modify (&catalog[0].header, "MISSING", "%s", 1, file);
+    free (file);
+
+    /* define secfilt catalog file */
+    ALLOCATE (catalog[0].secfilt_catalog, Catalog, 1);
+    fits_init_header (&catalog[0].secfilt_catalog[0].header);
+    fits_create_header (&catalog[0].secfilt_catalog[0].header);
+    ALLOCATE (catalog[0].secfilt_catalog[0].filename, char, length);
+    sprintf (catalog[0].secfilt_catalog[0].filename, "%s/%s.cps", path, root);
+    if (lock_catalog (catalog[0].secfilt_catalog, catalog[0].lockmode) != 2) {
+      fprintf (stderr, "error with file lock\n");
+      exit (2);
+    }
+    file = filebasename (catalog[0].secfilt_catalog[0].filename);
+    fits_modify (&catalog[0].header, "SECFILT", "%s", 1, file);
+    free (file);
+    free (path);
+    free (root);
+  }    
+
   /* write RA,DEC range in header */
   fits_modify (&catalog[0].header, "RA0",  "%lf", 1, region[0].RA[0]);
@@ -48,14 +105,15 @@
   free (line);
 
+  /* dummy allocation so realloc will succeed */
   ALLOCATE (catalog[0].average, Average, 1);
   ALLOCATE (catalog[0].measure, Measure, 1);
   ALLOCATE (catalog[0].missing, Missing, 1);
+  ALLOCATE (catalog[0].secfilt, SecFilt, 1);
   catalog[0].Naverage = catalog[0].Nmeasure = catalog[0].Nmissing = 0;
+  catalog[0].Nsecfilt = GetPhotcodeNsecfilt ();
 
   /* setup secondary filters to match photcodes:
-   *  Nsecfilt is number of filters.  Number of entries in array is
-   *  Nsecfilt * Naverage.  At this point, N entries == 0
+   * Nsecfilt is number of filters.  Number of entries in array is
+   * Nsecfilt * Naverage.  At this point, N entries == 0
    */
-  ALLOCATE (catalog[0].secfilt, SecFilt, 1);
-  catalog[0].Nsecfilt = GetPhotcodeNsecfilt ();
 }
Index: /trunk/Ohana/src/addstar/src/wcatalog.c
===================================================================
--- /trunk/Ohana/src/addstar/src/wcatalog.c	(revision 5228)
+++ /trunk/Ohana/src/addstar/src/wcatalog.c	(revision 5229)
@@ -5,4 +5,7 @@
   /* output CATMODE and CATFORMAT are set by mkcatalog 
      or by mode and format of existing data */
+
+  /* should this be moved into save_catalog?? */
+  fits_modify (&catalog[0].header, "ORDERED",  "%t", 1, catalog[0].ordered);
 
   if (!save_catalog (catalog, VERBOSE)) {
