Index: /branches/eam_branches/ipp-20150625/Ohana/src/addstar/Makefile
===================================================================
--- /branches/eam_branches/ipp-20150625/Ohana/src/addstar/Makefile	(revision 38592)
+++ /branches/eam_branches/ipp-20150625/Ohana/src/addstar/Makefile	(revision 38593)
@@ -40,6 +40,6 @@
 # programs in 'SERVER' use the client-server concept and are out of date
 
-INSTALL = addstar sedstar loadstarpar loadstarpar_client loadICRF loadICRF_client skycells mkcmf dumpskycells findskycell
-OTHERS  = load2mass loadwise loadtycho loadsupercos
+INSTALL = addstar sedstar loadstarpar loadstarpar_client loadICRF loadICRF_client load2mass skycells mkcmf dumpskycells findskycell
+OTHERS  = loadwise loadtycho loadsupercos
 SERVER  = addstar_client addstarc addstard addstart
 
@@ -51,19 +51,8 @@
 # all: addstar sedstar load2mass skycells
 
-# $(SRC)/find_matches.$(ARCH).o \
-# $(SRC)/find_matches_closest.$(ARCH).o \
-# $(SRC)/find_matches_refstars.$(ARCH).o \
-# $(SRC)/find_matches_closest_refstars.$(ARCH).o \
 # $(SRC)/find_subset.$(ARCH).o \
-# $(SRC)/getgsc.$(ARCH).o \
-# $(SRC)/getusno.$(ARCH).o \
-# $(SRC)/getusnob.$(ARCH).o \
-# $(SRC)/greference.$(ARCH).o \
-# $(SRC)/grefstars.$(ARCH).o \
 # $(SRC)/dump.$(ARCH).o \
 # $(SRC)/ReadStarsTEXT.$(ARCH).o \
 # $(SRC)/StarOps.$(ARCH).o \
-# $(SRC)/replace_match.$(ARCH).o \
-# 
 
 ADDSTAR = \
@@ -104,4 +93,14 @@
 $(SRC)/ReadStarsUKIRT.$(ARCH).o \
 $(SRC)/ReadXradFITS.$(ARCH).o \
+$(SRC)/find_matches.$(ARCH).o \
+$(SRC)/find_matches_closest.$(ARCH).o \
+$(SRC)/find_matches_refstars.$(ARCH).o \
+$(SRC)/find_matches_closest_refstars.$(ARCH).o \
+$(SRC)/getgsc.$(ARCH).o \
+$(SRC)/getusno.$(ARCH).o \
+$(SRC)/getusnob.$(ARCH).o \
+$(SRC)/greference.$(ARCH).o \
+$(SRC)/grefstars.$(ARCH).o \
+$(SRC)/replace_match.$(ARCH).o \
 $(SRC)/FilterStars.$(ARCH).o \
 $(SRC)/ImageOptions.$(ARCH).o \
@@ -243,5 +242,4 @@
 $(SRC)/load2mass.$(ARCH).o \
 $(SRC)/load2mass_as_rawdata.$(ARCH).o \
-$(SRC)/load2mass_catalog.$(ARCH).o \
 $(SRC)/get2mass_ops.$(ARCH).o \
 $(SRC)/get2mass_full.$(ARCH).o \
@@ -252,9 +250,10 @@
 $(SRC)/update_coords.$(ARCH).o \
 $(SRC)/SkyRegionUtils.$(ARCH).o \
-$(SRC)/StarOps.$(ARCH).o \
-$(SRC)/ConfigInit.$(ARCH).o \
-$(SRC)/Shutdown.$(ARCH).o \
-$(SRC)/SetSignals.$(ARCH).o \
-$(SRC)/psps_ids.$(ARCH).o
+$(SRC)/ConfigInit.$(ARCH).o \
+$(SRC)/Shutdown.$(ARCH).o \
+$(SRC)/SetSignals.$(ARCH).o \
+$(SRC)/psps_ids.$(ARCH).o
+
+# $(SRC)/load2mass_catalog.$(ARCH).o 
 
 LOAD-GALPHOT = \
Index: /branches/eam_branches/ipp-20150625/Ohana/src/addstar/include/2mass.h
===================================================================
--- /branches/eam_branches/ipp-20150625/Ohana/src/addstar/include/2mass.h	(revision 38592)
+++ /branches/eam_branches/ipp-20150625/Ohana/src/addstar/include/2mass.h	(revision 38593)
@@ -22,7 +22,8 @@
 
 SkyTable *get2mass_acc (SkyRegion *patch, char *path, char *accel);
-Stars    *get2mass_2DR_data (SkyRegion *region, char *filename, SkyRegion *patch, int photcode, int *nstars);
-Stars    *get2mass_AS_data (SkyRegion *region, char *filename, SkyRegion *patch, int phocode, int *nstars);
-Stars    *get2mass_AS_rawdata (SkyRegion *region, char *filename, SkyRegion *patch, int phocode, int *nstars);
+
+// Stars    *get2mass_2DR_data (SkyRegion *region, char *filename, SkyRegion *patch, int photcode, int *nstars);
+// Stars    *get2mass_AS_data (SkyRegion *region, char *filename, SkyRegion *patch, int phocode, int *nstars);
+// Stars    *get2mass_AS_rawdata (SkyRegion *region, char *filename, SkyRegion *patch, int phocode, int *nstars);
 
 SkyTable *scan2mass_acc (char *path, char *accel);
@@ -35,21 +36,23 @@
 int       load2mass_as_rawdata (SkyList *skytable, char *filename, AddstarClientOptions options);
 SkyTable *load2mass_acc (char *path, char *accel);
-int       get2mass_3star (Stars *star, char *line, int Nmax);
-int       load2mass_catalog (Catalog *catalog, Stars *stars, int Nstars);
+
+// int       get2mass_3star (Stars *star, char *line, int Nmax);
+// int       load2mass_catalog (Catalog *catalog, Stars *stars, int Nstars);
 
 int       get2mass_setup (int photcode);
 int       get2mass_coords (char *line, double *R, double *D, int Nmax);
-int       get2mass_star (Stars *star, char *line, int Nmax);
-int       get2mass_3star (Stars *star, char *line, int Nmax);
 
-int get2mass_3star_full (Stars **star, char *line, int Nmax);
+// int       get2mass_star (Stars *star, char *line, int Nmax);
+// int       get2mass_3star (Stars *star, char *line, int Nmax);
+
+int get2mass_3star_full (Measure *measure, char *line, int Nmax);
 char *next2MASSfield (char *line);
-int set2MASS_ph_qual (Stars *star, char qual);
-int set2MASS_rd_flag (Stars *star, char qual);
-int set2MASS_cc_flag (Stars *star, char qual);
-int set2MASS_bl_flag (Stars *star, char qual);
-int set2MASS_gal_flag (Stars *star, char qual);
-int set2MASS_mp_flag (Stars *star, char qual);
-int set2MASS_dup_flag (Stars *star, char qual);
-int set2MASS_use_flag (Stars *star, char qual);
+int set2MASS_ph_qual (Measure *measure, char qual);
+int set2MASS_rd_flag (Measure *measure, char qual);
+int set2MASS_cc_flag (Measure *measure, char qual);
+int set2MASS_bl_flag (Measure *measure, char qual);
+int set2MASS_gal_flag (Measure *measure, char qual);
+int set2MASS_mp_flag (Measure *measure, char qual);
+int set2MASS_dup_flag (Measure *measure, char qual);
+int set2MASS_use_flag (Measure *measure, char qual);
 int get2mass_sortStars (TMStars *tstars, int Ntstars);
Index: /branches/eam_branches/ipp-20150625/Ohana/src/addstar/include/addstar.h
===================================================================
--- /branches/eam_branches/ipp-20150625/Ohana/src/addstar/include/addstar.h	(revision 38592)
+++ /branches/eam_branches/ipp-20150625/Ohana/src/addstar/include/addstar.h	(revision 38593)
@@ -49,24 +49,4 @@
   int extnum_xrad;
 } HeaderSet;
-
-# if (0)
-typedef struct {
-  Average  average;
-  Measure  measure;
-  Lensing *lensing; // optionally carry out the lensing measurements
-  int found;
-} Stars;
-
-typedef struct {
-  unsigned int Nstars;
-  Stars *stars;
-  off_t Nimages;
-  Image *images;
-  Coords *mosaic;
-  SkyRegion *patch;
-  AddstarClientOptions *options;
-  char *refcat;
-} DVO_DATA;
-# endif
 
 # define IDTYPE int
@@ -222,26 +202,20 @@
 int        find_matches        	  PROTO((SkyRegion *region, Catalog *newcat, Catalog *catalog, AddstarClientOptions options));
 
-# if (0)
-int        find_matches_refstars  	 PROTO((SkyRegion *region, Stars **stars, unsigned int Nstars, Catalog *catalog, AddstarClientOptions options));
-int        find_matches_closest_refstars PROTO((SkyRegion *region, Stars **stars, unsigned int Nstars, Catalog *catalog, AddstarClientOptions options));
-
-int        dump_rawstars          PROTO((Stars *stars, unsigned int Nstars));
-
-Stars    **find_subset            PROTO((SkyRegion *region, Stars *stars, unsigned int Nstars, unsigned int *NSTARS));
+int        find_matches_refstars  	 PROTO((SkyRegion *region, Catalog *srccat, Catalog *tgtcat, AddstarClientOptions options));
+int        find_matches_closest_refstars PROTO((SkyRegion *region, Catalog *srccat, Catalog *tgtcat, AddstarClientOptions options));
+
+Catalog   *greference             PROTO((char *Refcat, SkyRegion *catstats, int photcode));
+
 int        gcatalog               PROTO((Catalog *catalog));
-Stars     *get2mass               PROTO((SkyRegion *patch, int photcode, int mode, unsigned int *NSTARS));
-
-Stars     *greference             PROTO((char *Refcat, SkyRegion *catstats, int photcode, unsigned int *nstars));
-Stars     *getgsc                 PROTO((SkyRegion *patch, unsigned int *NSTARS));
-Stars     *getusno                PROTO((SkyRegion *catstats, int photcode, unsigned int *Nstars));
-Stars     *getusnob               PROTO((SkyRegion *catstats, int photcode, unsigned int *Nstars));
+Catalog   *getgsc                 PROTO((SkyRegion *patch));
+Catalog   *getusno                PROTO((SkyRegion *catstats));
+Catalog   *getusnob               PROTO((SkyRegion *catstats));
 
 // load text-based stars (REF only in the sense of REF photcodes)
-Stars     *grefstars              PROTO((char *file, int photcode, unsigned int *Nstars));
-
-Stars     *rd_gsc                 PROTO((char *filename, unsigned int *nstars));
-
-int        replace_match          PROTO((Average *average, Measure *measure, Stars *star));
-# endif
+Catalog   *grefstars              PROTO((char *file, int photcode));
+
+Catalog   *rd_gsc                 PROTO((char *filename));
+
+int        replace_match          PROTO((Average *average, Measure *measure, Measure *newmeas, off_t *found));
 
 Catalog   *LoadStars              PROTO((char *file, Image **images, off_t *Nimages, AddstarClientOptions *options));
@@ -297,4 +271,5 @@
 
 SkyList   *SkyListExistingSubset  PROTO((SkyList *input, char *path));
+SkyList   *SkyListForStars	  PROTO((SkyTable *table, int depth, Catalog *catalog));
 
 // these are all for the addstar client/server which has not been maintained
@@ -311,5 +286,4 @@
 int 	   UpdateDatabase_Reflist PROTO((AddstarClientOptions *options, Stars *stars, unsigned int Nstars));
 int 	   UpdateDatabase_Refcat  PROTO((AddstarClientOptions *options, SkyRegion *UserPatch, char *refcat));
-SkyList   *SkyListForStars	  PROTO((SkyTable *table, int depth, Stars *stars, unsigned int Nstars));
 int        SkyListSetPath	  PROTO((SkyList *list, char *path));
 int 	   InitDataset		  PROTO((void));
Index: /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/SkyListForStars.c
===================================================================
--- /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/SkyListForStars.c	(revision 38592)
+++ /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/SkyListForStars.c	(revision 38593)
@@ -1,11 +1,10 @@
 # include "addstar.h"
 
-# if (0)
-void sort_stars_ra (Stars *stars, int N) {
+void sort_stars_ra (Catalog *catalog) {
 
-# define SWAPFUNC(A,B){ Stars tmp; tmp = stars[A]; stars[A] = stars[B]; stars[B] = tmp; }
-# define COMPARE(A,B)(stars[A].average.R < stars[B].average.R)
+# define SWAPFUNC(A,B){ Average tmp; tmp = catalog->average[A]; catalog->average[A] = catalog->average[B]; catalog->average[B] = tmp; }
+# define COMPARE(A,B)(catalog->average[A].R < catalog->average[B].R)
 
-  OHANA_SORT (N, COMPARE, SWAPFUNC);
+  OHANA_SORT (catalog->Naverage, COMPARE, SWAPFUNC);
 
 # undef SWAPFUNC
@@ -14,5 +13,5 @@
 }
 
-SkyList *SkyListForStars (SkyTable *table, int depth, Stars *stars, unsigned int Nstars) {
+SkyList *SkyListForStars (SkyTable *table, int depth, Catalog *catalog) {
   
   int i, j, Nr, NR;
@@ -28,16 +27,22 @@
   list[0].ownElements = FALSE; // free these elements when freeing the list
 
-  sort_stars_ra (stars, Nstars); /* sort by RA */
-  for (i = 0; i < Nstars; i++) {
-    if (stars[i].found == -2) continue;
-    here = SkyRegionByPoint (table, depth, stars[i].average.R, stars[i].average.D);
-    stars[i].found = -2;
+  sort_stars_ra (catalog); /* sort by RA */
+
+  ALLOCATE (catalog->found_t, off_t, catalog->Naverage);
+  for (i = 0; i < catalog->Naverage; i++) {
+    catalog->found_t[i] = 0;
+  }
+
+  for (i = 0; i < catalog->Naverage; i++) {
+    if (catalog->found_t[i] == -2) continue;
+    here = SkyRegionByPoint (table, depth, catalog->average[i].R, catalog->average[i].D);
+    catalog->found_t[i] = -2;
     /* search forward for all contained stars */
-    for (j = i; j < Nstars; j++) {
-      if (stars[j].average.R >= here[0].regions[0][0].Rmax) break;
-      if (stars[j].average.R <  here[0].regions[0][0].Rmin) break;
-      if (stars[j].average.D <  here[0].regions[0][0].Dmin) continue;
-      if (stars[j].average.D >= here[0].regions[0][0].Dmax) continue;
-      stars[j].found = -2;
+    for (j = i; j < catalog->Naverage; j++) {
+      if (catalog->average[j].R >= here[0].regions[0][0].Rmax) break;
+      if (catalog->average[j].R <  here[0].regions[0][0].Rmin) break;
+      if (catalog->average[j].D <  here[0].regions[0][0].Dmin) continue;
+      if (catalog->average[j].D >= here[0].regions[0][0].Dmax) continue;
+      catalog->found_t[j] = -2;
     }
     list[0].regions[Nr] = here[0].regions[0];
@@ -54,5 +59,6 @@
 
   /* reset to -1 for all stars: required start for find_match_refstars */
-  for (i = 0; i < Nstars; i++) stars[i].found = -1; 
+  free (catalog->found_t);
+  catalog->found_t = NULL;
   return (list);
 }
@@ -70,3 +76,2 @@
 
 */
-# endif
Index: /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/addstar.c
===================================================================
--- /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/addstar.c	(revision 38592)
+++ /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/addstar.c	(revision 38593)
@@ -57,5 +57,4 @@
       UpdateImageIDs (newcat, images, Nimages);
 
-      // if ((DUMP != NULL) && !strcmp (DUMP, "rawstars")) dump_rawstars (stars, Nstars);
       for (i = 0; i < Nimages; i++) {
 	newlist = SkyListByImage (sky, -1, &images[i]);
@@ -66,8 +65,7 @@
       ImageOptions (&options, images, Nimages);
       break;
-# if (0)
     case ADDSTAR_MODE_REFLIST:
-      stars = grefstars (argv[1], options.photcode, &Nstars);
-      skylist = SkyListForStars (sky, -1, stars, Nstars);
+      newcat = grefstars (argv[1], options.photcode);
+      skylist = SkyListForStars (sky, -1, newcat);
       break;
     case ADDSTAR_MODE_REFCAT:
@@ -80,5 +78,4 @@
       skylist[0].ownElements = FALSE;
       break;
-# endif
 
     default:
@@ -146,5 +143,4 @@
     switch (options.mode) {
       case ADDSTAR_MODE_IMAGE:
-	// Nsubset = Nstars;
 	if (options.closest) {
 	  Nmatch += find_matches_closest (skylist[0].regions[i], newcat, &catalog, options);
@@ -153,18 +149,15 @@
 	}
 	break;
-# if (0)
+
       case ADDSTAR_MODE_REFCAT:
-	stars = greference (argv[1], skylist[0].regions[i], options.photcode, &Nstars);
+	newcat = greference (argv[1], skylist[0].regions[i], options.photcode);
       case ADDSTAR_MODE_REFLIST: {
-	Stars **subset = find_subset (skylist[0].regions[i], stars, Nstars, &Nsubset);
 	if (options.closest) {
-	  Nmatch += find_matches_closest_refstars (skylist[0].regions[i], subset, Nsubset, &catalog, options);
+	  Nmatch += find_matches_closest_refstars (skylist[0].regions[i], newcat, &catalog, options);
 	} else {
-	  Nmatch += find_matches_refstars (skylist[0].regions[i], subset, Nsubset, &catalog, options);
+	  Nmatch += find_matches_refstars (skylist[0].regions[i], newcat, &catalog, options);
 	}
-	if (Nsubset) free (subset);
 	break;
       }
-# endif
       default:
 	abort();
Index: /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/find_matches.c
===================================================================
--- /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/find_matches.c	(revision 38592)
+++ /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/find_matches.c	(revision 38593)
@@ -3,5 +3,5 @@
 int find_matches (SkyRegion *region, Catalog *srccat, Catalog *tgtcat, AddstarClientOptions options) {
 
-  off_t i, j, n, N, J, Nstars, mSrc;
+  off_t i, j, J, Nstars, mSrc;
   double RADIUS, RADIUS2;
   double *X1, *Y1, *X2, *Y2;
@@ -9,7 +9,7 @@
   off_t *N1, *N2;
   off_t Nave, NAVE, Nmeas, NMEAS, Nmatch;
-  int Nsecfilt, Nsec, status;
   unsigned int objID, catID;
   Coords tcoords;
+  int Nsecfilt, Nsec;
 
   /* photcode data - must by of type DEP; options.photcode is equiv photcode for all input
@@ -58,16 +58,16 @@
   catID = tgtcat[0].catID;
 
-  /* project onto rectilinear grid with 1 arcsec pixels. the choice of ZEA projection has the
-   * advantage that every point in R,D has a mapping to a unique X,Y.  However, note that not all
-   * possible X,Y points map back to R,D and the local plate scale changes substantially far from
-   * the projection pole.  a better mapping might be ARC, not yet implemented (see
-   * coordops.update.c).  We use the center of the region (tgtcat) for crval1,2. 
+  /* project onto rectilinear grid with 1 arcsec pixels. the choice of ARC projection has
+   * the advantage that every point in R,D has a mapping to a unique X,Y.  However, note
+   * that not all possible X,Y points map back to R,D and the local plate scale changes
+   * substantially far from the projection pole.  We use the center of the region (tgtcat)
+   * for crval1,2.
    */
   InitCoords (&tcoords, "DEC--ARC");
   tcoords.crval1 = 0.5*(region[0].Rmin + region[0].Rmax);
-  if (region[0].Dmax < 90) {
+  if ((region[0].Dmax < 90) && (region[0].Dmin > -90)) {
     tcoords.crval2 = 0.5*(region[0].Dmin + region[0].Dmax);
   } else {
-    tcoords.crval2 = 90.0;
+    tcoords.crval2 = (region[0].Dmax >= 90) ? 90.0 : -90.0;
   }
   tcoords.cdelt1 = tcoords.cdelt2 = 1.0 / 3600.0;
@@ -76,5 +76,5 @@
   Nstars = 0;
   for (i = 0; i < srccat->Naverage; i++) {
-    status = RD_to_XY (&X1[Nstars], &Y1[Nstars], srccat->average[i].R, srccat->average[i].D, &tcoords);
+    int status = RD_to_XY (&X1[Nstars], &Y1[Nstars], srccat->average[i].R, srccat->average[i].D, &tcoords);
     if (!status) continue;
     N1[Nstars] = i;
@@ -101,6 +101,8 @@
   if (Nave > 1) sort_coords_index (X2, Y2, N2, Nave);
 
-  /* set up pointers for linked list of measure */
+  /* set up pointers for linked list of measurements */
   if (tgtcat[0].sorted && (tgtcat[0].Nmeasure == tgtcat[0].Nmeasure_disk)) {
+    // this version is only valid if we have done a full catalog load, and if the catalog
+    // is sorted while processed
     next_meas = init_measure_links (tgtcat[0].average, Nave, tgtcat[0].measure, Nmeas);
   } else {
@@ -109,8 +111,13 @@
 
   /* choose a radius for matches (defined in args.c or ImageOptions.c) */
-  RADIUS = options.radius;
+  if (options.radius == 0) {
+    RADIUS = 2.0; /* hardwired default for refstars */
+  } else {
+    RADIUS = options.radius; /* provided by config */
+  }
   RADIUS2 = RADIUS*RADIUS;
 
-  /** find matched stars **/
+  /****************** find matched stars ********************/
+
   for (i = j = 0; (i < Nstars) && (j < Nave); ) {
     if (!finite(X1[i]) || !finite(Y1[i])) { 
@@ -144,6 +151,6 @@
       /*** a match is found, add to average, measure ***/
       Nmatch ++;
-      n = N2[J];
-      N = N1[i];
+      off_t n = N2[J];
+      off_t N = N1[i];
 
       /* make sure there is space for next entry */
@@ -161,5 +168,5 @@
 	
 	/** add measurements for this star **/
-	
+
 	// set the new measurements
 	tgtcat[0].measure[Nmeas]          = srccat->measure[mSrc + mOff];
@@ -231,6 +238,4 @@
 	  tgtcat[0].found_t[n] = Nmeas;
 	}
-	/* Nm is updated, but not written out in -update mode (for existing entries)
-	   Nm is recalculated in build_meas_links if loaded table is not sorted */
 	tgtcat[0].average[n].Nmeasure ++;
 	Nmeas ++;
@@ -245,7 +250,7 @@
   }
 
-/* incorporate unmatched image stars, if this star is in field of this tgtcat */
-/* these new entries are all written out in UPDATE mode */ 
-  for (i = 0; (i < Nstars) && !options.only_match; i ++) {
+  /* incorporate unmatched image stars, if this star is in field of this tgtcat */
+  /* these new entries are all written out in UPDATE mode */ 
+  for (i = 0; (i < Nstars) && !options.only_match; i++) {
     /* make sure there is space for next entry */
     if (Nmeas >= NMEAS - srccat->average[i].Nmeasure) {
@@ -324,5 +329,5 @@
   }
 
-/* note stars which have been found in this tgtcat */
+  /* note stars which have been found in this tgtcat */
   for (i = 0; i < srccat->Nmeasure; i++) {
     if (srccat->found_t[i] > -1) {
@@ -331,5 +336,5 @@
   }
 
-/* check if the tgtcat has changed?  if no change, no need to write */
+  /* check if the tgtcat has changed?  if no change, no need to write */
   tgtcat[0].objID    = objID; // new max value, save on tgtcat close
   tgtcat[0].Naverage = Nave;
@@ -341,7 +346,7 @@
   free (Y1);
   free (N1);
-  free (N2);
   free (X2);
   free (Y2);
+  free (N2);
   free (next_meas);
 
Index: /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/find_matches_closest.c
===================================================================
--- /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/find_matches_closest.c	(revision 38592)
+++ /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/find_matches_closest.c	(revision 38593)
@@ -3,5 +3,5 @@
 int find_matches_closest (SkyRegion *region, Catalog *srccat, Catalog *tgtcat, AddstarClientOptions options) {
 
-  off_t i, j, n, N, J, Jmin, status, Nstars, mSrc;
+  off_t i, j, J, Jmin, status, Nstars, mSrc;
   double RADIUS, RADIUS2, Rmin;
   double *X1, *Y1, *X2, *Y2;
@@ -9,7 +9,7 @@
   off_t *N1, *N2;
   off_t Nave, NAVE, Nmeas, NMEAS, Nmatch, Nlens, NLENS;
-  int Nsecfilt, Nsec;
   unsigned int objID, catID;
   Coords tcoords;
+  int Nsecfilt, Nsec;
 
   /* photcode data - must by of type DEP; options.photcode is equiv photcode for all input
@@ -62,12 +62,13 @@
    * the advantage that every point in R,D has a mapping to a unique X,Y.  However, note
    * that not all possible X,Y points map back to R,D and the local plate scale changes
-   * far from the projection pole. We use the center of the region (tgtcat) for crval1,2.
+   * substantially far from the projection pole. We use the center of the region (tgtcat)
+   * for crval1,2.
    */
   InitCoords (&tcoords, "DEC--ARC");
   tcoords.crval1 = 0.5*(region[0].Rmin + region[0].Rmax);
-  if (region[0].Dmax < 90) {
+  if ((region[0].Dmax < 90) && (region[0].Dmin > -90)) {
     tcoords.crval2 = 0.5*(region[0].Dmin + region[0].Dmax);
   } else {
-    tcoords.crval2 = 90.0;
+    tcoords.crval2 = (region[0].Dmax >= 90) ? 90.0 : -90.0;
   }
   tcoords.cdelt1 = tcoords.cdelt2 = 1.0 / 3600.0;
@@ -114,5 +115,9 @@
 
   /* choose a radius for matches */
-  RADIUS = options.radius; /* provided by config */
+  if (options.radius == 0) {
+    RADIUS = 2.0; /* hardwired default for refstars */
+  } else {
+    RADIUS = options.radius; /* provided by config */
+  }
   RADIUS2 = RADIUS*RADIUS;
 
@@ -178,6 +183,6 @@
     /*** a match is found, add to average, measure ***/
     Nmatch ++;
-    n = N2[Jmin];
-    N = N1[i];
+    off_t n = N2[Jmin];
+    off_t N = N1[i];
 
     /* make sure there is space for next entry */
@@ -355,6 +360,4 @@
       next_meas[Nmeas-1] = (mSrc < srccat->average[i].Nmeasure - 1) ? Nmeas : -1;
     }
-    srccat->found_t[i] = Nave;
-
     // if we have lensing data, insert that as well
     if (srccat->lensing) {
@@ -374,4 +377,5 @@
       }
     }
+    srccat->found_t[i] = Nave;
     Nave ++;
   }
@@ -407,7 +411,7 @@
   free (Y1);
   free (N1);
-  free (N2);
   free (X2);
   free (Y2);
+  free (N2);
   free (next_meas);
   free (next_lens);
Index: /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/find_matches_closest_refstars.c
===================================================================
--- /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/find_matches_closest_refstars.c	(revision 38592)
+++ /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/find_matches_closest_refstars.c	(revision 38593)
@@ -1,20 +1,11 @@
 # include "addstar.h"
 
-/* differences with find_matches_closest():
- * accepts Stars **stars (vs Stars *stars)
- * NREFSTAR_GROUP vs NSTAR_GROUP
- * does not update lensing fields
- * allows option to replace existing entries
- * allows multiple photcodes
-
- */
-
-int find_matches_closest_refstars (SkyRegion *region, Stars **stars, unsigned int NstarsIn, Catalog *catalog, AddstarClientOptions options) {
-
-  off_t i, j, n, N, J, Jmin, status;
+int find_matches_closest_refstars (SkyRegion *region, Catalog *srccat, Catalog *tgtcat, AddstarClientOptions options) {
+
+  off_t i, j, J, Jmin, status, mSrc;
   double RADIUS, RADIUS2, Rmin;
   double *X1, *Y1, *X2, *Y2;
   double dX, dY, dR;
-  off_t *N1, *N2, *next_meas;
+  off_t *N1, *N2;
   off_t Nave, NAVE, Nmeas, NMEAS, Nstars, Nmatch;
   unsigned int objID, catID;
@@ -22,50 +13,55 @@
   int Nsecfilt;
 
-  switch (NREFSTAR_GROUP) {
-    case 1:
-    case 3:
-    case 4:
-    case 6:
-      break;
-    default:
-      fprintf (stderr, "ERROR: NREFSTAR_GROUP NOT SET!\n");
-      exit (1);
-  }
-
   /* photcode data -- should not have to modify secfilt / average */
   Nsecfilt = GetPhotcodeNsecfilt ();
 
-  /** allocate local arrays (stars) **/
-  ALLOCATE (X1, double, NstarsIn);
-  ALLOCATE (Y1, double, NstarsIn);
-  ALLOCATE (N1, off_t,  NstarsIn);
-
-  /** allocate local arrays (catalog) **/
-  NAVE = Nave = catalog[0].Naverage;
+  /** allocate local arrays (srccat) **/
+  ALLOCATE (X1, double, srccat->Naverage);
+  ALLOCATE (Y1, double, srccat->Naverage);
+  ALLOCATE (N1, off_t,  srccat->Naverage);
+
+  if (!srccat->found_t) {
+    ALLOCATE (srccat->found_t, off_t, srccat->Naverage);
+    for (i = 0; i < srccat->Naverage; i++) {
+      srccat->found_t[i] = -1;
+    }
+  }
+
+  /** allocate local arrays (tgtcat) **/
+  NAVE = Nave = tgtcat[0].Naverage;
   ALLOCATE (X2, double, NAVE);
   ALLOCATE (Y2, double, NAVE);
   ALLOCATE (N2, off_t,  NAVE);
-  ALLOCATE (catalog[0].found_t, off_t, NAVE);
+
+  if (!tgtcat->found_t) {
+    ALLOCATE (tgtcat[0].found_t, off_t, NAVE);
+    for (i = 0; i < NAVE; i++) {
+      tgtcat->found_t[i] = -1;
+    }
+  }
   /* for secfilt j and star i, secfilt[i*Nsecfilt+j] */
 
   /* internal counters */
   Nmatch = 0;
-  NMEAS = Nmeas = catalog[0].Nmeasure;
+  NMEAS = Nmeas = tgtcat[0].Nmeasure;
   
-  // current max obj ID for this catalog
-  objID = catalog[0].objID;
-  catID = catalog[0].catID;
+  off_t *next_meas = NULL;
+
+  // current max obj ID for this tgtcat
+  objID = tgtcat[0].objID;
+  catID = tgtcat[0].catID;
 
   /* project onto rectilinear grid with 1 arcsec pixels. the choice of ARC projection has
    * the advantage that every point in R,D has a mapping to a unique X,Y.  However, note
    * that not all possible X,Y points map back to R,D and the local plate scale changes
-   * far from the projection pole. We use the center of the region (catalog) for crval1,2.
+   * substantially far from the projection pole. We use the center of the region (tgtcat)
+   * for crval1,2.
    */
   InitCoords (&tcoords, "DEC--ARC");
   tcoords.crval1 = 0.5*(region[0].Rmin + region[0].Rmax);
-  if (region[0].Dmax < 90) {
+  if ((region[0].Dmax < 90) && (region[0].Dmin > -90)) {
     tcoords.crval2 = 0.5*(region[0].Dmin + region[0].Dmax);
   } else {
-    tcoords.crval2 = 90.0;
+    tcoords.crval2 = (region[0].Dmax >= 90) ? 90.0 : -90.0;
   }
   tcoords.cdelt1 = tcoords.cdelt2 = 1.0 / 3600.0;
@@ -73,6 +69,6 @@
   /* build spatial index (RA sort) referencing input array sequence */
   Nstars = 0;
-  for (i = 0; i < NstarsIn; i++) {
-    status = RD_to_XY (&X1[Nstars], &Y1[Nstars], stars[i][0].average.R, stars[i][0].average.D, &tcoords);
+  for (i = 0; i < srccat->Naverage; i++) {
+    status = RD_to_XY (&X1[Nstars], &Y1[Nstars], srccat->average[i].R, srccat->average[i].D, &tcoords);
     if (!status) continue;
     N1[Nstars] = i;
@@ -80,5 +76,5 @@
   }
   if (Nstars < 1) {
-    if (VERBOSE) fprintf (stderr, "skipping %s, no overlapping stars\n", catalog[0].filename);
+    if (VERBOSE) fprintf (stderr, "skipping %s, no overlapping stars\n", tgtcat[0].filename);
     free (X1);
     free (Y1);
@@ -93,17 +89,17 @@
   /* build spatial index (RA sort) */
   for (i = 0; i < Nave; i++) {
-    RD_to_XY (&X2[i], &Y2[i], catalog[0].average[i].R, catalog[0].average[i].D, &tcoords);
+    RD_to_XY (&X2[i], &Y2[i], tgtcat[0].average[i].R, tgtcat[0].average[i].D, &tcoords);
     N2[i] = i;
-    catalog[0].found_t[N2[i]] = -1;
+    tgtcat[0].found_t[N2[i]] = -1;
   }
   if (Nave > 1) sort_coords_index (X2, Y2, N2, Nave);
 
   /* set up pointers for linked list of measure */
-  if (catalog[0].sorted && (catalog[0].Nmeasure == catalog[0].Nmeasure_disk)) {
-    // this version is only valid if we have done a full catalog load, and if the catalog
+  if (tgtcat[0].sorted && (tgtcat[0].Nmeasure == tgtcat[0].Nmeasure_disk)) {
+    // this version is only valid if we have done a full tgtcat load, and if the tgtcat
     // is sorted while processed
-    next_meas = init_measure_links (catalog[0].average, Nave, catalog[0].measure, Nmeas);
+    next_meas = init_measure_links (tgtcat[0].average, Nave, tgtcat[0].measure, Nmeas);
   } else {
-    next_meas = build_measure_links (catalog[0].average, Nave, catalog[0].measure, Nmeas);
+    next_meas = build_measure_links (tgtcat[0].average, Nave, tgtcat[0].measure, Nmeas);
   }    
 
@@ -116,6 +112,6 @@
   RADIUS2 = RADIUS*RADIUS;
 
-  /** find matched stars **/
-  // XXX could use NREFSTAR_GROUP to do this match more quicky
+  /****************** find matched stars ********************/
+
   for (i = j = 0; (i < Nstars) && (j < Nave); ) {
     if (!finite(X1[i]) || !finite(Y1[i])) { 
@@ -140,6 +136,7 @@
     }
 
-    if (stars[N1[i]][0].found != -1) {
-        /* this star has already been assigned to an object in this or another catalog */
+    // XXX check that this is allocated
+    if (srccat->found_t[N1[i]] != -1) {
+        /* this star has already been assigned to an object in this or another tgtcat */
         i++;
         continue;
@@ -169,85 +166,90 @@
     /*** a match is found, add to average, measure ***/
     Nmatch ++;
-    n = N2[Jmin];
-    N = N1[i];
-
-    /** in replace mode, search for entry and replace values M, dM, R, D */
-    // XXX this fails for unsorted catalogs, right?
-    if (options.replace && replace_match (&catalog[0].average[n], catalog[0].measure, stars[N])) {
-	i++;
-	continue;
-    }
+    off_t n = N2[Jmin];
+    off_t N = N1[i];
 
     /* make sure there is space for next entry */
-    if (Nmeas >= NMEAS) {
-      NMEAS = Nmeas + 1000;
+    if (Nmeas >= NMEAS - srccat->average[N].Nmeasure) {
+      NMEAS = Nmeas + 1000 + srccat->average[N].Nmeasure;
       REALLOCATE (next_meas, off_t, NMEAS);
-      REALLOCATE (catalog[0].measure, Measure, NMEAS);
-    }
-
-    /* add to end of measurement list */
-    add_meas_link (&catalog[0].average[n], next_meas, Nmeas, NMEAS);
-	
+      REALLOCATE (tgtcat[0].measure, Measure, NMEAS);
+    }
+
     /** add measurements for this star **/
-
-    // set the new measurements
-    catalog[0].measure[Nmeas]          = stars[N][0].measure;
-
-    catalog[0].measure[Nmeas].dbFlags  = 0;
-    catalog[0].measure[Nmeas].averef   = n;
-    catalog[0].measure[Nmeas].objID    = catalog[0].average[n].objID;
-    catalog[0].measure[Nmeas].catID    = catalog[0].catID;
-
-    float dRoff = dvoOffsetR(&catalog[0].measure[Nmeas], &catalog[0].average[n]);
-
-    // rationalize dR:
-    if (dRoff > +180.0*3600.0) {
-      // average on high end of boundary, move star up
-      catalog[0].measure[Nmeas].R += 360.0;
-      dRoff -= 360.0*3600.0;
-    }
-    if (dRoff < -180.0*3600.0) {
-      // average on low end of boundary, move star down
-      catalog[0].measure[Nmeas].R -= 360.0;
-      dRoff += 360.0*3600.0;
-    }
-
-    // the reference data may not have per-object time specified
-    catalog[0].measure[Nmeas].t        = (TIMEREF == 0) ? stars[N][0].measure.t      : TIMEREF; /** careful : time_t vs e_time **/
-    catalog[0].measure[Nmeas].t_msec   = (TIMEREF == 0) ? stars[N][0].measure.t_msec : TIMEREF; /** careful : time_t vs e_time **/
-
-    // we can choose to accept the proper-motion and parallax from the reference catalog
-    if (ACCEPT_MOTION) {
-      catalog[0].average[n].dR         = stars[N][0].average.dR;
-      catalog[0].average[n].dD         = stars[N][0].average.dD;
-      catalog[0].average[n].uR         = stars[N][0].average.uR;
-      catalog[0].average[n].uD         = stars[N][0].average.uD;
-      catalog[0].average[n].duR        = stars[N][0].average.duR;
-      catalog[0].average[n].duD        = stars[N][0].average.duD;
-      catalog[0].average[n].P          = stars[N][0].average.P;
-      catalog[0].average[n].dP         = stars[N][0].average.dP;
-      catalog[0].average[n].Tmean      = stars[N][0].average.Tmean;
-    }
+    off_t mOff = srccat->average[N].measureOffset;
+    for (mSrc = 0; mSrc < srccat->average[N].Nmeasure; mSrc++) {
+      /** in replace mode, search for entry and replace values M, dM, R, D */
+      // XXX this fails for unsorted tgtcats, right?
+      if (options.replace && replace_match (&tgtcat[0].average[n], tgtcat[0].measure, &srccat->measure[mSrc + mOff], &srccat->found_t[N])) continue;
+
+      /* add to end of measurement list */
+      add_meas_link (&tgtcat[0].average[n], next_meas, Nmeas, NMEAS);
+      
+      // set the new measurements
+      tgtcat[0].measure[Nmeas]          = srccat->measure[mSrc + mOff];
+
+      // measure now carries R,D (not dR,dD) 
+      tgtcat[0].measure[Nmeas].dbFlags  = 0;
+      tgtcat[0].measure[Nmeas].averef   = n;
+      tgtcat[0].measure[Nmeas].objID    = tgtcat[0].average[n].objID;
+      tgtcat[0].measure[Nmeas].catID    = tgtcat[0].catID;
+
+      float dRoff = dvoOffsetR(&tgtcat[0].measure[Nmeas], &tgtcat[0].average[n]);
+
+      // rationalize dR:
+      if (dRoff > +180.0*3600.0) {
+	// average on high end of boundary, move star up
+	tgtcat[0].measure[Nmeas].R += 360.0;
+	dRoff -= 360.0*3600.0;
+      }
+      if (dRoff < -180.0*3600.0) {
+	// average on low end of boundary, move star down
+	tgtcat[0].measure[Nmeas].R -= 360.0;
+	dRoff += 360.0*3600.0;
+      }
+      if (fabs(dRoff) > 10*RADIUS) {
+	// take declination into account and check again.
+	double cosD = cos(RAD_DEG*tgtcat[0].average[n].D);
+	if (fabs(dRoff*cosD) > 10*RADIUS) {
+	  fprintf (stderr, "error: %10.6f,%10.6f vs %10.6f,%10.6f (%f,%f vs %f,%f)\n", 
+		   tgtcat[0].average[n].R, tgtcat[0].average[n].D, 
+		   srccat->average[N].R, srccat->average[N].D,
+		   X1[i], X2[Jmin], 
+		   Y1[i], Y2[Jmin]);
+	  // XXX abort on this? -- this is a bad failure...
+	}
+      }
+
+      // the reference data may not have per-object time specified
+      if (TIMEREF) {
+	tgtcat[0].measure[Nmeas].t        = TIMEREF;
+	tgtcat[0].measure[Nmeas].t_msec   = 0;
+      }
+
+      // we can choose to accept the proper-motion and parallax from the reference tgtcat
+      if (ACCEPT_MOTION) {
+	tgtcat[0].average[n].dR         = srccat->average[N].dR;
+	tgtcat[0].average[n].dD         = srccat->average[N].dD;
+	tgtcat[0].average[n].uR         = srccat->average[N].uR;
+	tgtcat[0].average[n].uD         = srccat->average[N].uD;
+	tgtcat[0].average[n].duR        = srccat->average[N].duR;
+	tgtcat[0].average[n].duD        = srccat->average[N].duD;
+	tgtcat[0].average[n].P          = srccat->average[N].P;
+	tgtcat[0].average[n].dP         = srccat->average[N].dP;
+	tgtcat[0].average[n].Tmean      = srccat->average[N].Tmean;
+      }
 
     /** don't update average / secfilt values for REF photcodes **/
 
-    /*** handle multiple stars */
-    /* this catalog star matches more than one image star */
-    // XXX should this be an average flag?
-    if (catalog[0].found_t[n] > -1) {
-      catalog[0].measure[catalog[0].found_t[n]].dbFlags |= ID_MEAS_BLEND_OBJ;
-      catalog[0].measure[Nmeas].dbFlags |= ID_MEAS_BLEND_OBJ;
-    } else {
-      catalog[0].found_t[n] = Nmeas;
-    }
-
-    stars[N][0].found = Nmeas;
-    catalog[0].average[n].Nmeasure ++;
-    Nmeas ++;
-
-    // make this optional:
-    // update_coords (&catalog[0].average[n], &catalog[0].measure[0], next_meas);
+      tgtcat[0].average[n].Nmeasure ++;
+      Nmeas ++;
+    }
+
+    srccat->found_t[N] = n;
+    tgtcat[0].found_t[n] = -1;
     i++;
   }
+
+  /*************** add unmatched stars *************************/
 
   /* Incorporate unmatched refcat stars.  Skip this step if we want to
@@ -255,44 +257,47 @@
      reference up-to-date with known stars only */
 
-  for (i = 0; (i < Nstars) && !options.only_match; i+=NREFSTAR_GROUP) {
+  for (i = 0; (i < Nstars) && !options.only_match; i++) {
     /* make sure there is space for next entry */
-    if (Nmeas >= NMEAS - NREFSTAR_GROUP) {
-      NMEAS = Nmeas + 1000;
+    if (Nmeas >= NMEAS - srccat->average[i].Nmeasure) {
+      NMEAS = Nmeas + 1000 + srccat->average[i].Nmeasure;
       REALLOCATE (next_meas, off_t, NMEAS);
-      REALLOCATE (catalog[0].measure, Measure, NMEAS);
+      REALLOCATE (tgtcat[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][0].found >= 0) continue;
-    if (!IN_REGION (stars[N][0].average.R, stars[N][0].average.D)) continue;
-
-    dvo_average_init (&catalog[0].average[Nave]);
-    catalog[0].average[Nave].R         	   = stars[N][0].average.R;
-    catalog[0].average[Nave].D         	   = stars[N][0].average.D;
-
-    catalog[0].average[Nave].Nmeasure      = NREFSTAR_GROUP;
-    catalog[0].average[Nave].measureOffset = Nmeas;
-    catalog[0].average[Nave].objID     	   = objID;
-    catalog[0].average[Nave].catID     	   = catID;
+      REALLOCATE (tgtcat[0].average, Average, NAVE);
+      REALLOCATE (tgtcat[0].found_t, off_t, NAVE);
+      if (tgtcat[0].secfilt) {
+	// we only update the secfilt table if it has been allocated for output
+	REALLOCATE (tgtcat[0].secfilt, SecFilt, NAVE*tgtcat[0].Nsecfilt);
+      }
+    }
+
+    if (srccat->found_t[i] != -1) continue;
+    if (!IN_REGION (srccat->average[i].R, srccat->average[i].D)) continue;
+
+    dvo_average_init (&tgtcat[0].average[Nave]);
+    tgtcat[0].average[Nave].R         	   = srccat->average[i].R;
+    tgtcat[0].average[Nave].D         	   = srccat->average[i].D;
+
+    tgtcat[0].average[Nave].Nmeasure  	   = srccat->average[i].Nmeasure;
+    tgtcat[0].average[Nave].measureOffset  = Nmeas;
+    tgtcat[0].average[Nave].objID     	   = objID;
+    tgtcat[0].average[Nave].catID     	   = catID;
 
     if (PSPS_ID) {
-        catalog[0].average[Nave].extID = CreatePSPSObjectID(catalog[0].average[Nave].R, catalog[0].average[Nave].D);
+        tgtcat[0].average[Nave].extID = CreatePSPSObjectID(tgtcat[0].average[Nave].R, tgtcat[0].average[Nave].D);
     }
 
     if (ACCEPT_MOTION) {
-      catalog[0].average[Nave].dR    	   = stars[N][0].average.dR;
-      catalog[0].average[Nave].dD    	   = stars[N][0].average.dD;
-      catalog[0].average[Nave].uR    	   = stars[N][0].average.uR;
-      catalog[0].average[Nave].uD    	   = stars[N][0].average.uD;
-      catalog[0].average[Nave].duR   	   = stars[N][0].average.duR;
-      catalog[0].average[Nave].duD   	   = stars[N][0].average.duD;
-      catalog[0].average[Nave].P     	   = stars[N][0].average.P;
-      catalog[0].average[Nave].dP    	   = stars[N][0].average.dP;
-      catalog[0].average[Nave].Tmean   	   = stars[N][0].average.Tmean;
+      tgtcat[0].average[Nave].dR    	   = srccat->average[i].dR;
+      tgtcat[0].average[Nave].dD    	   = srccat->average[i].dD;
+      tgtcat[0].average[Nave].uR    	   = srccat->average[i].uR;
+      tgtcat[0].average[Nave].uD    	   = srccat->average[i].uD;
+      tgtcat[0].average[Nave].duR   	   = srccat->average[i].duR;
+      tgtcat[0].average[Nave].duD   	   = srccat->average[i].duD;
+      tgtcat[0].average[Nave].P     	   = srccat->average[i].P;
+      tgtcat[0].average[Nave].dP    	   = srccat->average[i].dP;
+      tgtcat[0].average[Nave].Tmean   	   = srccat->average[i].Tmean;
     }
 
@@ -300,47 +305,52 @@
 
     for (j = 0; j < Nsecfilt; j++) {
-      dvo_secfilt_init (&catalog[0].secfilt[Nave*Nsecfilt+j], SECFILT_RESET_ALL);
-    }
-
-    for (j = 0; j < NREFSTAR_GROUP; j++) {
-      N = N1[i + j];
-
-      catalog[0].measure[Nmeas]          = stars[N][0].measure;
-      catalog[0].measure[Nmeas].dbFlags  = 0;
-      catalog[0].measure[Nmeas].averef   = Nave;
-      catalog[0].measure[Nmeas].objID    = catalog[0].average[Nave].objID;
-      catalog[0].measure[Nmeas].catID    = catalog[0].catID;
-
-      catalog[0].measure[Nmeas].t        = (stars[N][0].measure.t == 0) ? TIMEREF : stars[N][0].measure.t;      /** careful : time_t vs e_time **/
-      catalog[0].measure[Nmeas].t_msec   = (stars[N][0].measure.t == 0) ?       0 : stars[N][0].measure.t_msec; /** careful : time_t vs e_time **/
-
-      stars[N][0].found = Nmeas;
-      next_meas[Nmeas] = -1;
+      dvo_secfilt_init (&tgtcat[0].secfilt[Nave*Nsecfilt+j], SECFILT_RESET_ALL);
+    }
+
+    off_t mOff = srccat->average[i].measureOffset;
+    for (mSrc = 0; mSrc < srccat->average[i].Nmeasure; mSrc++) {
+      // supply the measurements from this detection
+      dvo_measure_init (&tgtcat[0].measure[Nmeas]);
+      tgtcat[0].measure[Nmeas] = srccat->measure[mSrc + mOff];
+
+      // the following measure elements cannot be set until here:
+      tgtcat[0].measure[Nmeas].dbFlags  = 0;
+      tgtcat[0].measure[Nmeas].averef   = Nave;
+      tgtcat[0].measure[Nmeas].objID    = tgtcat[0].average[Nave].objID;
+      tgtcat[0].measure[Nmeas].catID    = tgtcat[0].catID;
+
+      if (TIMEREF) {
+	tgtcat[0].measure[Nmeas].t      = TIMEREF;
+	tgtcat[0].measure[Nmeas].t_msec = 0;
+      }
+
       Nmeas ++;
-    }
-    for (j = 0; j < NREFSTAR_GROUP - 1; j++) {
-	next_meas[Nmeas - NREFSTAR_GROUP + j] = Nmeas - NREFSTAR_GROUP + j + 1;
-    }
+
+      // update the next_meas pointer for this entry (last one for this star is -1)
+      next_meas[Nmeas-1] = (mSrc < srccat->average[i].Nmeasure - 1) ? Nmeas : -1;
+    }
+    srccat->found_t[i] = Nave;
     Nave ++;
   }
       
-  REALLOCATE (catalog[0].average, Average, Nave);
-  REALLOCATE (catalog[0].measure, Measure, Nmeas);
+  REALLOCATE (tgtcat[0].average, Average, Nave);
+  REALLOCATE (tgtcat[0].measure, Measure, Nmeas);
 
   // XXX allow for unsorted output?
-  catalog[0].measure = sort_measure (catalog[0].average, Nave, catalog[0].measure, Nmeas, next_meas);
-  catalog[0].sorted = TRUE;
-
-  /* note stars which have been found in this catalog */
-  for (i = 0; i < Nstars; i++) {
-    if (stars[i][0].found > -1) {
-      stars[i][0].found = -2;
-    }
-  }
-
-  catalog[0].objID    = objID; // new max value, save on catalog close
-  catalog[0].Naverage = Nave;
-  catalog[0].Nmeasure = Nmeas;
-  catalog[0].Nsecfilt_mem = Nave*Nsecfilt;
+  tgtcat[0].measure = sort_measure (tgtcat[0].average, Nave, tgtcat[0].measure, Nmeas, next_meas);
+  tgtcat[0].sorted = TRUE;
+
+  /* note stars which have been found in this tgtcat */
+  for (i = 0; i < srccat->Naverage; i++) {
+    if (srccat->found_t[i] > -1) {
+      srccat->found_t[i] = -2;
+    }
+  }
+
+  /* check if the tgtcat has changed?  if no change, no need to write */
+  tgtcat[0].objID    = objID; // new max value, save on tgtcat close
+  tgtcat[0].Naverage = Nave;
+  tgtcat[0].Nmeasure = Nmeas;
+  tgtcat[0].Nsecfilt_mem = Nave*Nsecfilt;
   if (VERBOSE) fprintf (stderr, "Nstars, Nave, Nmeas: "OFF_T_FMT" "OFF_T_FMT" "OFF_T_FMT", ("OFF_T_FMT" matches)\n",  Nstars,  Nave,  Nmeas,  Nmatch);
 
@@ -348,9 +358,19 @@
   free (Y1);
   free (N1);
-  free (N2);
   free (X2);
   free (Y2);
+  free (N2);
   free (next_meas);
 
   return (Nmatch);
 }
+
+/* differences with find_matches_closest():
+ * accepts Stars **stars (vs Stars *stars)
+ * NREFSTAR_GROUP vs NSTAR_GROUP
+ * does not update lensing fields
+ * allows option to replace existing entries
+ * allows multiple photcodes
+
+ */
+
Index: /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/find_matches_refstars.c
===================================================================
--- /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/find_matches_refstars.c	(revision 38592)
+++ /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/find_matches_refstars.c	(revision 38593)
@@ -1,11 +1,12 @@
 # include "addstar.h"
 
-int find_matches_refstars (SkyRegion *region, Stars **stars, unsigned int Nstars, Catalog *catalog, AddstarClientOptions options) {
-
-  off_t i, j, n, N, J;
+// see bottom of this file for differences between find_matches_refstars.c and find_matches.c
+int find_matches_refstars (SkyRegion *region, Catalog *srccat, Catalog *tgtcat, AddstarClientOptions options) {
+
+  off_t i, j, J, Nstars, mSrc;
   double RADIUS, RADIUS2;
   double *X1, *Y1, *X2, *Y2;
   double dX, dY, dR;
-  off_t *N1, *N2,  *next_meas;
+  off_t *N1, *N2;
   off_t Nave, NAVE, Nmeas, NMEAS, Nmatch;
   unsigned int objID, catID;
@@ -13,70 +14,97 @@
   int Nsecfilt;
 
-  switch (NREFSTAR_GROUP) {
-    case 1:
-    case 3:
-    case 4:
-      break;
-    default:
-      fprintf (stderr, "ERROR: NREFSTAR_GROUP NOT SET!\n");
-      exit (1);
-  }
-
   /* photcode data -- should not have to modify secfilt / average */
   Nsecfilt = GetPhotcodeNsecfilt ();
 
   /** allocate local arrays (stars) **/
-  ALLOCATE (X1, double, Nstars);
-  ALLOCATE (Y1, double, Nstars);
-  ALLOCATE (N1, off_t,  Nstars);
-
-  /** allocate local arrays (catalog) **/
-  Nave = catalog[0].Naverage;
-  NAVE = Nave + 1000;
+  ALLOCATE (X1, double, srccat->Naverage);
+  ALLOCATE (Y1, double, srccat->Naverage);
+  ALLOCATE (N1, off_t,  srccat->Naverage);
+
+  myAbort ("figure out if found_t needs to be tracking Naverage or Nmeasure"); 
+  if (!srccat->found_t) {
+    ALLOCATE (srccat->found_t, off_t, srccat->Naverage);
+    for (i = 0; i < srccat->Naverage; i++) {
+      srccat->found_t[i] = -1;
+    }
+  }
+
+  /** allocate local arrays (tgtcat) **/
+  NAVE = Nave = tgtcat[0].Naverage;
   ALLOCATE (X2, double, NAVE);
   ALLOCATE (Y2, double, NAVE);
   ALLOCATE (N2, off_t,  NAVE);
-  ALLOCATE (catalog[0].found_t, off_t, NAVE);
-  REALLOCATE (catalog[0].average, Average, NAVE);
-  REALLOCATE (catalog[0].secfilt, SecFilt, NAVE*catalog[0].Nsecfilt);
+
+  if (!tgtcat->found_t) {
+    ALLOCATE (tgtcat[0].found_t, off_t, NAVE);
+    for (i = 0; i < NAVE; i++) {
+      tgtcat->found_t[i] = -1;
+    }
+  }
   /* for secfilt j and star i, secfilt[i*Nsecfilt+j] */
 
+  /* internal counters */
   Nmatch = 0;
-  NMEAS = Nmeas = catalog[0].Nmeasure;
+  NMEAS = Nmeas = tgtcat[0].Nmeasure;
   
-  // current max obj ID for this catalog
-  objID = catalog[0].objID;
-  catID = catalog[0].catID;
-
-  /* project onto rectilinear grid with 1 arcsec pixels, sort by X */
-  /* reference for coords is catalog center */
-  InitCoords (&tcoords, "DEC--ZEA");
+  off_t *next_meas = NULL;
+
+  // current max obj ID for this tgtcat
+  objID = tgtcat[0].objID;
+  catID = tgtcat[0].catID;
+
+  /* project onto rectilinear grid with 1 arcsec pixels. the choice of ARC projection has
+   * the advantage that every point in R,D has a mapping to a unique X,Y.  However, note
+   * that not all possible X,Y points map back to R,D and the local plate scale changes
+   * substantially far from the projection pole.  We use the center of the region (tgtcat)
+   * for crval1,2.
+   */
+  InitCoords (&tcoords, "DEC--ARC");
   tcoords.crval1 = 0.5*(region[0].Rmin + region[0].Rmax);
-  tcoords.crval2 = 0.5*(region[0].Dmin + region[0].Dmax);
+  if ((region[0].Dmax < 90) && (region[0].Dmin > -90)) {
+    tcoords.crval2 = 0.5*(region[0].Dmin + region[0].Dmax);
+  } else {
+    tcoords.crval2 = (region[0].Dmax >= 90) ? 90.0 : -90.0;
+  }
   tcoords.cdelt1 = tcoords.cdelt2 = 1.0 / 3600.0;
-  
-  for (i = 0; i < Nstars; i++) {
-    RD_to_XY (&X1[i], &Y1[i], stars[i][0].average.R, stars[i][0].average.D, &tcoords);
-    N1[i] = i;
+
+  /* build spatial index (RA sort) referencing input array sequence */
+  Nstars = 0;
+  for (i = 0; i < srccat->Naverage; i++) {
+    int status = RD_to_XY (&X1[Nstars], &Y1[Nstars], srccat->average[i].R, srccat->average[i].D, &tcoords);
+    if (!status) continue;
+    N1[Nstars] = i;
+    Nstars ++;
+  }
+  if (Nstars < 1) {
+    if (VERBOSE) fprintf (stderr, "skipping %s, no overlapping stars\n", tgtcat[0].filename);
+    free (X1);
+    free (Y1);
+    free (N1);
+    free (X2);
+    free (Y2);
+    free (N2);
+    return (0);
   }
   if (Nstars > 1) sort_coords_index (X1, Y1, N1, Nstars);
   
+  /* build spatial index (RA sort) */
   for (i = 0; i < Nave; i++) {
-    RD_to_XY (&X2[i], &Y2[i], catalog[0].average[i].R, catalog[0].average[i].D, &tcoords);
+    RD_to_XY (&X2[i], &Y2[i], tgtcat[0].average[i].R, tgtcat[0].average[i].D, &tcoords);
     N2[i] = i;
-    catalog[0].found_t[N2[i]] = -1;
+    tgtcat[0].found_t[N2[i]] = -1;
   }
   if (Nave > 1) sort_coords_index (X2, Y2, N2, Nave);
 
   /* set up pointers for linked list of measurements */
-  if (catalog[0].sorted && (catalog[0].Nmeasure == catalog[0].Nmeasure_disk)) {
+  if (tgtcat[0].sorted && (tgtcat[0].Nmeasure == tgtcat[0].Nmeasure_disk)) {
     // this version is only valid if we have done a full catalog load, and if the catalog
     // is sorted while processed
-    next_meas = init_measure_links (catalog[0].average, Nave, catalog[0].measure, Nmeas);
+    next_meas = init_measure_links (tgtcat[0].average, Nave, tgtcat[0].measure, Nmeas);
   } else {
-    next_meas = build_measure_links (catalog[0].average, Nave, catalog[0].measure, Nmeas);
+    next_meas = build_measure_links (tgtcat[0].average, Nave, tgtcat[0].measure, Nmeas);
   }    
 
-  /* choose a radius for matches */
+  /* choose a radius for matches (defined in args.c or ImageOptions.c) */
   if (options.radius == 0) {
     RADIUS = 2.0; /* hardwired default for refstars */
@@ -86,6 +114,6 @@
   RADIUS2 = RADIUS*RADIUS;
 
-  /** find matched stars **/
-  // XXX could use NREFSTAR_GROUP to do this match more quicky
+  /****************** find matched stars ********************/
+
   for (i = j = 0; (i < Nstars) && (j < Nave); ) {
     if (!finite(X1[i]) || !finite(Y1[i])) { 
@@ -97,5 +125,6 @@
       continue;
     }
-    
+
+    /* negative dX: j is too large */
     dX = X1[i] - X2[j];
     if (dX <= -1.02*RADIUS) {
@@ -103,4 +132,5 @@
       continue;
     }
+    /* positive dX, i is too large */
     if (dX >= 1.02*RADIUS) {
       j++;
@@ -108,5 +138,5 @@
     }
 
-    /* negative dX: j is too large, positive dX, i is too large */
+    /* within match range; look for matches */
     for (J = j; (dX > -1.02*RADIUS) && (J < Nave); J++) {
       dX = X1[i] - X2[J];
@@ -117,88 +147,104 @@
       /*** a match is found, add to average, measure ***/
       Nmatch ++;
-      n = N2[J];
-      N = N1[i];
-
-      /** in replace mode, search for entry and replace values M, dM, R, D */
-      if (options.replace && replace_match (&catalog[0].average[n], catalog[0].measure, stars[N])) continue;
-
-      if (Nmeas == NMEAS) {
-	NMEAS = Nmeas + 1000;
+      off_t n = N2[J];
+      off_t N = N1[i];
+
+      /* make sure there is space for next entry */
+      if (Nmeas >= NMEAS - srccat->average[N].Nmeasure) {
+	NMEAS = Nmeas + 1000 + srccat->average[N].Nmeasure;
 	REALLOCATE (next_meas, off_t, NMEAS);
-	REALLOCATE (catalog[0].measure, Measure, NMEAS);
+	REALLOCATE (tgtcat[0].measure, Measure, NMEAS);
       }
 
-      /* add to end of measurement list */
-      add_meas_link (&catalog[0].average[n], next_meas, Nmeas, NMEAS);
+      /** add measurements for this star **/
+      off_t mOff = srccat->average[N].measureOffset;
+      for (mSrc = 0; mSrc < srccat->average[N].Nmeasure; mSrc++) {
+	/** in replace mode, search for entry and replace values M, dM, R, D */
+	if (options.replace && replace_match (&tgtcat[0].average[n], tgtcat[0].measure, &srccat->measure[mSrc + mOff], &srccat->found_t[N])) continue;
+
+	/* add to end of measurement list */
+	add_meas_link (&tgtcat[0].average[n], next_meas, Nmeas, NMEAS);
 	
-      /** add measurements for this star **/
-
-      // set the new measurements
-      catalog[0].measure[Nmeas]          = stars[N][0].measure;
-
-      /** measure now stores R,D **/
-      catalog[0].measure[Nmeas].dbFlags  = 0;
-      catalog[0].measure[Nmeas].averef   = n;
-      catalog[0].measure[Nmeas].objID    = catalog[0].average[n].objID;
-      catalog[0].measure[Nmeas].catID    = catalog[0].catID;
-
-      float dRoff = dvoOffsetR(&catalog[0].measure[Nmeas], &catalog[0].average[n]);
-
-      // rationalize dR:
-      if (dRoff > +180.0*3600.0) {
+	/** add measurements for this star **/
+
+	// set the new measurements
+	tgtcat[0].measure[Nmeas]          = srccat->measure[mSrc + mOff];
+	
+	// the following measure elements cannot be set until here:
+	tgtcat[0].measure[Nmeas].dbFlags  = 0;
+	tgtcat[0].measure[Nmeas].averef   = n; // this must be an absolute sequence number, if partial average is loaded 
+	tgtcat[0].measure[Nmeas].objID    = tgtcat[0].average[n].objID;
+	tgtcat[0].measure[Nmeas].catID    = tgtcat[0].catID;
+
+	float dRoff = dvoOffsetR(&tgtcat[0].measure[Nmeas], &tgtcat[0].average[n]);
+
+	// rationalize R:
+	if (dRoff > +180.0*3600.0) {
 	  // average on high end of boundary, move star up
-	  catalog[0].measure[Nmeas].R += 360.0;
+	  tgtcat[0].measure[Nmeas].R += 360.0;
 	  dRoff -= 360.0*3600.0;
+	}
+	if (dRoff < -180.0*3600.0) {
+	  // average on low end of boundary, move star down
+	  tgtcat[0].measure[Nmeas].R -= 360.0;
+	  dRoff += 360.0*3600.0;
+	}
+	if (fabs(dRoff) > 10*RADIUS) {
+	  // take declination into account and check again.
+	  double cosD = cos(RAD_DEG*tgtcat[0].average[n].D);
+	  if (fabs(dRoff*cosD) > 10*RADIUS) {
+	    fprintf (stderr, "error: %10.6f,%10.6f vs %10.6f,%10.6f (%f,%f vs %f,%f)\n", 
+		     tgtcat[0].average[n].R, tgtcat[0].average[n].D, 
+		     srccat->average[N].R, srccat->average[N].D,
+		     X1[i], X2[J], 
+		     Y1[i], Y2[J]);
+	  }
+	}
+
+	if (TIMEREF) {
+	  tgtcat[0].measure[Nmeas].t        = TIMEREF; /** careful : time_t vs e_time **/
+	  tgtcat[0].measure[Nmeas].t_msec   = 0; 
+	}
+
+	if (ACCEPT_MOTION) {
+	  tgtcat[0].average[n].uR         = srccat->average[N].uR;
+	  tgtcat[0].average[n].uD         = srccat->average[N].uD;
+	  tgtcat[0].average[n].duR        = srccat->average[N].duR;
+	  tgtcat[0].average[n].duD        = srccat->average[N].duD;
+	  tgtcat[0].average[n].P          = srccat->average[N].P;
+	  tgtcat[0].average[n].dP         = srccat->average[N].dP;
+	}
+
+	/** don't update average / secfilt values for REF photcodes **/
+
+	myAbort ("fix logic on multiple detections");
+
+	/*** flag multiple stars */
+	/* this image star matches more than one tgtcat star */
+	if (srccat->found_t[N] > -1) {
+	  tgtcat[0].measure[srccat->found_t[N]].dbFlags |= ID_MEAS_BLEND_MEAS;
+	  tgtcat[0].measure[Nmeas].dbFlags |= ID_MEAS_BLEND_MEAS;
+	} 
+	if (srccat->found_t[N] == -2) { /* this image star matches a tgtcat star on a neighboring tgtcat */
+	  tgtcat[0].measure[Nmeas].dbFlags |= ID_MEAS_BLEND_MEAS_X;
+	} 
+	if (srccat->found_t[N] == -1) { /* this image star matches only this tgtcat star */
+	  srccat->found_t[N] = Nmeas;  /* save first match, in case coincidences are found */
+	}
+	/* this tgtcat star matches more than one image star */
+	if (tgtcat[0].found_t[n] > -1) {
+	  tgtcat[0].measure[tgtcat[0].found_t[n]].dbFlags |= ID_MEAS_BLEND_OBJ;
+	  tgtcat[0].measure[Nmeas].dbFlags |= ID_MEAS_BLEND_OBJ;
+	} else {
+	  tgtcat[0].found_t[n] = Nmeas;
+	}
+	tgtcat[0].average[n].Nmeasure ++;
+	Nmeas ++;
       }
-      if (dRoff < -180.0*3600.0) {
-	  // average on low end of boundary, move star down
-	  catalog[0].measure[Nmeas].R -= 360.0;
-	  dRoff += 360.0*3600.0;
-      }
-
-      catalog[0].measure[Nmeas].t        = (TIMEREF == 0) ? stars[N][0].measure.t      : TIMEREF; /** careful : time_t vs e_time **/
-      catalog[0].measure[Nmeas].t_msec   = (TIMEREF == 0) ? stars[N][0].measure.t_msec : TIMEREF; /** careful : time_t vs e_time **/
-
-      if (ACCEPT_MOTION) {
-	catalog[0].average[n].uR         = stars[N][0].average.uR;
-	catalog[0].average[n].uD         = stars[N][0].average.uD;
-	catalog[0].average[n].duR        = stars[N][0].average.duR;
-	catalog[0].average[n].duD        = stars[N][0].average.duD;
-	catalog[0].average[n].P          = stars[N][0].average.P;
-	catalog[0].average[n].dP         = stars[N][0].average.dP;
-      }
-
-      /** don't update average / secfilt values for REF photcodes **/
-
-      /*** handle multiple stars */
-      /* this image star matches more than one catalog star */
-      if (stars[N][0].found > -1) {
-	catalog[0].measure[stars[N][0].found].dbFlags |= ID_MEAS_BLEND_MEAS;
-	catalog[0].measure[Nmeas].dbFlags |= ID_MEAS_BLEND_MEAS;
-      } 
-      if (stars[N][0].found == -2) { /* this image star matches a catalog star on a neighboring catalog */
-	catalog[0].measure[Nmeas].dbFlags |= ID_MEAS_BLEND_MEAS_X;
-      } 
-      if (stars[N][0].found == -1) { /* this image star matches only this catalog star */
-	stars[N][0].found = Nmeas;  /* save first match, in case coincidences are found */
-      }
-      /* this catalog star matches more than one image star */
-      if (catalog[0].found_t[n] > -1) {
-	catalog[0].measure[catalog[0].found_t[n]].dbFlags |= ID_MEAS_BLEND_OBJ;
-	catalog[0].measure[Nmeas].dbFlags |= ID_MEAS_BLEND_OBJ;
-      } else {
-	catalog[0].found_t[n] = Nmeas;
-      }
-
-      catalog[0].average[n].Nmeasure ++;
-      Nmeas ++;
-
-      // update_coords (&catalog[0].average[n], &catalog[0].measure[0], next_meas);
+      
+      // update_coords (&tgtcat[0].average[n], &tgtcat[0].measure[0], next_meas);
     }
     i++;
   }
-
-  /* we don't add missed entries for refcat
-     (already in database, not refcat) */
 
   /* incorporate unmatched refcat stars */
@@ -207,92 +253,99 @@
      the reference up-to-date with known stars only */
 
-  for (i = 0; (i < Nstars) && !options.only_match; i+=NREFSTAR_GROUP) {
-    if (Nmeas >= NMEAS - NREFSTAR_GROUP) {
-      NMEAS = Nmeas + 1000;
+  for (i = 0; (i < Nstars) && !options.only_match; i++) {
+    /* make sure there is space for next entry */
+    if (Nmeas >= NMEAS - srccat->average[i].Nmeasure) {
+      NMEAS = Nmeas + 1000 + srccat->average[i].Nmeasure;
       REALLOCATE (next_meas, off_t, NMEAS);
-      REALLOCATE (catalog[0].measure, Measure, NMEAS);
-    }
-    if (Nave == NAVE) {
+      REALLOCATE (tgtcat[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 = i;
-    if (stars[N][0].found > -1) continue;
-    if (!IN_REGION (stars[N][0].average.R, stars[N][0].average.D)) continue;
-
-    dvo_average_init (&catalog[0].average[Nave]);
-    catalog[0].average[Nave].R         	   = stars[N][0].average.R;
-    catalog[0].average[Nave].D         	   = stars[N][0].average.D;
-
-    catalog[0].average[Nave].Nmeasure      = NREFSTAR_GROUP;
-    catalog[0].average[Nave].measureOffset = Nmeas;
-    catalog[0].average[Nave].objID     	   = objID;
-    catalog[0].average[Nave].catID     	   = catID;
+      REALLOCATE (tgtcat[0].average, Average, NAVE);
+      if (tgtcat[0].secfilt) {
+	// we only update the secfilt table if it has been allocated for output
+	REALLOCATE (tgtcat[0].secfilt, SecFilt, NAVE*tgtcat[0].Nsecfilt);
+      }
+    }
+
+    if (srccat->found_t[i] >= 0) continue;
+    if (!IN_REGION (srccat->average[i].R, srccat->average[i].D)) continue;
+
+    dvo_average_init (&tgtcat[0].average[Nave]);
+    tgtcat[0].average[Nave].R         	   = srccat->average[i].R;
+    tgtcat[0].average[Nave].D         	   = srccat->average[i].D;
+
+    tgtcat[0].average[Nave].Nmeasure       = srccat->average[i].Nmeasure;
+    tgtcat[0].average[Nave].measureOffset  = Nmeas;
+    tgtcat[0].average[Nave].objID     	   = objID;
+    tgtcat[0].average[Nave].catID     	   = catID;
 
     if (PSPS_ID) {
-        catalog[0].average[Nave].extID = CreatePSPSObjectID(catalog[0].average[Nave].R, catalog[0].average[Nave].D);
+      tgtcat[0].average[Nave].extID = CreatePSPSObjectID(tgtcat[0].average[Nave].R, tgtcat[0].average[Nave].D);
     }
 
     if (ACCEPT_MOTION) {
-      catalog[0].average[Nave].dR    	   = stars[N][0].average.dR;
-      catalog[0].average[Nave].dD    	   = stars[N][0].average.dD;
-      catalog[0].average[Nave].uR    	   = stars[N][0].average.uR;
-      catalog[0].average[Nave].uD    	   = stars[N][0].average.uD;
-      catalog[0].average[Nave].duR   	   = stars[N][0].average.duR;
-      catalog[0].average[Nave].duD   	   = stars[N][0].average.duD;
-      catalog[0].average[Nave].P     	   = stars[N][0].average.P;
-      catalog[0].average[Nave].dP    	   = stars[N][0].average.dP;
+      tgtcat[0].average[Nave].dR    	   = srccat->average[i].dR;
+      tgtcat[0].average[Nave].dD    	   = srccat->average[i].dD;
+      tgtcat[0].average[Nave].uR    	   = srccat->average[i].uR;
+      tgtcat[0].average[Nave].uD    	   = srccat->average[i].uD;
+      tgtcat[0].average[Nave].duR   	   = srccat->average[i].duR;
+      tgtcat[0].average[Nave].duD   	   = srccat->average[i].duD;
+      tgtcat[0].average[Nave].P     	   = srccat->average[i].P;
+      tgtcat[0].average[Nave].dP    	   = srccat->average[i].dP;
     }
 
     objID ++;
 
-    for (j = 0; j < Nsecfilt; j++) {
-      dvo_secfilt_init (&catalog[0].secfilt[Nave*Nsecfilt+j], SECFILT_RESET_ALL);
-    }
-
-    for (j = 0; j < NREFSTAR_GROUP; j++) {
-      N = i + j;
-
-      catalog[0].measure[Nmeas]          = stars[N][0].measure;
-
-      catalog[0].measure[Nmeas].t        = (stars[N][0].measure.t == 0) ? TIMEREF : stars[N][0].measure.t;      /** careful : time_t vs e_time **/
-      catalog[0].measure[Nmeas].t_msec   = (stars[N][0].measure.t == 0) ?       0 : stars[N][0].measure.t_msec; /** careful : time_t vs e_time **/
-      catalog[0].measure[Nmeas].dbFlags  = 0;
-      catalog[0].measure[Nmeas].averef   = Nave;
-      catalog[0].measure[Nmeas].objID    = catalog[0].average[Nave].objID;
-      catalog[0].measure[Nmeas].catID    = catalog[0].catID;
-
-      stars[N][0].found = Nmeas;
-      next_meas[Nmeas] = -1;  // initial value here, update below
-      Nmeas ++; 
-    }
-
-    for (j = 0; j < NREFSTAR_GROUP - 1; j++) {
-	next_meas[Nmeas - NREFSTAR_GROUP + j] = Nmeas - NREFSTAR_GROUP + j + 1;
+    for (j = 0; tgtcat[0].secfilt && (j < Nsecfilt); j++) {
+      dvo_secfilt_init (&tgtcat[0].secfilt[Nave*Nsecfilt+j], SECFILT_RESET_ALL);
+    }
+
+    off_t mOff = srccat->average[i].measureOffset;
+    for (mSrc = 0; mSrc < srccat->average[i].Nmeasure; mSrc++) {
+      // supply the measurments from this detection
+      dvo_measure_init (&tgtcat[0].measure[Nmeas]);
+      tgtcat[0].measure[Nmeas] = srccat->measure[mSrc + mOff];
+
+      // the following measure elements cannot be set until here:
+      tgtcat[0].measure[Nmeas].dbFlags   = 0;
+      tgtcat[0].measure[Nmeas].averef    = Nave; // XXX EAM : must be absolute Nave if partial read
+      tgtcat[0].measure[Nmeas].objID     = tgtcat[0].average[Nave].objID;
+      tgtcat[0].measure[Nmeas].catID     = tgtcat[0].catID;
+
+      if (TIMEREF) {
+	tgtcat[0].measure[Nmeas].t        = TIMEREF;
+	tgtcat[0].measure[Nmeas].t_msec   =       0; 
+      }
+
+      /* next[Nmeas] should always be -1 in this context (it is always the only
+	 measurement for the star) */
+      srccat->found_t[i] = Nmeas;
+      Nmeas ++;
+
+      // update the next_meas pointer for this entry (last one for this star is -1)
+      next_meas[Nmeas-1] = (mSrc < srccat->average[i].Nmeasure - 1) ? Nmeas : -1;
     }
     Nave ++;
   }
       
-  REALLOCATE (catalog[0].average, Average, Nave);
+  REALLOCATE (tgtcat[0].average, Average, Nave);
+  REALLOCATE (tgtcat[0].measure, Measure, Nmeas);
 
   // XXX allow for unsorted output?
-  catalog[0].measure = sort_measure (catalog[0].average, Nave, catalog[0].measure, Nmeas, next_meas);
-
-  /* note stars which have been found in this catalog */
-  for (i = 0; i < Nstars; i++) {
-    if (stars[i][0].found > -1) {
-      stars[i][0].found = -2;
-    } else {
-      stars[i][0].found = -3;
-    }
-  }
-
-  catalog[0].objID    = objID; // new max value, save on catalog close
-  catalog[0].Naverage = Nave;
-  catalog[0].Nmeasure = Nmeas;
-  catalog[0].Nsecfilt_mem = Nave*Nsecfilt;
-  if (VERBOSE) fprintf (stderr, "Nstars, Nave, Nmeas: %d "OFF_T_FMT" "OFF_T_FMT", ("OFF_T_FMT" matches)\n",  Nstars,  Nave,  Nmeas,  Nmatch);
+  tgtcat[0].measure = sort_measure (tgtcat[0].average, Nave, tgtcat[0].measure, Nmeas, next_meas);
+
+  /* note stars which have been found in this tgtcat */
+  for (i = 0; i < srccat->Nmeasure; i++) {
+    if (srccat->found_t[i] > -1) {
+      srccat->found_t[i] = -2;
+    }
+  }
+
+  tgtcat[0].objID    = objID; // new max value, save on tgtcat close
+  tgtcat[0].Naverage = Nave;
+  tgtcat[0].Nmeasure = Nmeas;
+  tgtcat[0].Nsecfilt_mem = Nave*Nsecfilt;
+  if (VERBOSE) fprintf (stderr, "Nstars, Nave, Nmeas: "OFF_T_FMT" "OFF_T_FMT" "OFF_T_FMT", ("OFF_T_FMT" matches)\n",  Nstars,  Nave,  Nmeas,  Nmatch);
 
   free (X1);
@@ -306,2 +359,10 @@
   return (Nmatch);
 }
+
+/** differences between find_matches_refstars.c and find_matches.c:
+ * refstars has replace_match
+ * refstars has TIMEREF and ACCEPT_MOTION
+ * refstars does NOT have AddToCalibration
+ * refstars does NOT have Nsec 
+ * refstars does NOT do update_coords
+ **/
Index: /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/get2mass_full.c
===================================================================
--- /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/get2mass_full.c	(revision 38592)
+++ /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/get2mass_full.c	(revision 38593)
@@ -6,5 +6,5 @@
 // fill in the data for a JHK triplet star.  takes a pointer to the start of the line the
 // RA and DEC have already been set
-int get2mass_3star_full (Stars **star, char *line, int Nmax) {
+int get2mass_3star_full (Measure *measure, char *line, int Nmax) {
 
   char *ptr;
@@ -17,64 +17,64 @@
   ptr = next2MASSfield (ptr); // dec (assumed to be already set)
   ptr = next2MASSfield (ptr); // err_maj
-  star[0][0].measure.FWx = ToShortPixels(strtod (ptr, NULL));
+  measure[0].FWx = ToShortPixels(strtod (ptr, NULL));
   ptr = next2MASSfield (ptr); // err_min
-  star[0][0].measure.FWy = ToShortPixels(strtod (ptr, NULL));
+  measure[0].FWy = ToShortPixels(strtod (ptr, NULL));
   ptr = next2MASSfield (ptr); // err_ang
-  star[0][0].measure.theta = ToShortPixels(strtod (ptr, NULL));
-
-  star[2][0].measure.FWx   = star[1][0].measure.FWx   = star[0][0].measure.FWx;
-  star[2][0].measure.FWy   = star[1][0].measure.FWy   = star[0][0].measure.FWy;
-  star[2][0].measure.theta = star[1][0].measure.theta = star[0][0].measure.theta;
+  measure[0].theta = ToShortPixels(strtod (ptr, NULL));
+
+  measure[2].FWx   = measure[1].FWx   = measure[0].FWx;
+  measure[2].FWy   = measure[1].FWy   = measure[0].FWy;
+  measure[2].theta = measure[1].theta = measure[0].theta;
 
   ptr = next2MASSfield (ptr); // designation (skip)
 
   ptr = next2MASSfield (ptr); // j_m
-  star[0][0].measure.M  = strtod (ptr, NULL);
+  measure[0].M  = strtod (ptr, NULL);
   ptr = next2MASSfield (ptr); // j_cmsig
-  star[0][0].measure.dM = strtod (ptr, NULL);
+  measure[0].dM = strtod (ptr, NULL);
   ptr = next2MASSfield (ptr); // j_msigcom
   dMfull = strtod (ptr, NULL);
-  star[0][0].measure.dMcal = sqrt (SQ(dMfull) - SQ(star[0][0].measure.dM));
+  measure[0].dMcal = sqrt (SQ(dMfull) - SQ(measure[0].dM));
   ptr = next2MASSfield (ptr); // j_snr (skip)
 
   ptr = next2MASSfield (ptr); // h_m
-  star[1][0].measure.M  = strtod (ptr, NULL);
+  measure[1].M  = strtod (ptr, NULL);
   ptr = next2MASSfield (ptr); // h_cmsig
-  star[1][0].measure.dM = strtod (ptr, NULL);
+  measure[1].dM = strtod (ptr, NULL);
   ptr = next2MASSfield (ptr); // h_msigcom
   dMfull = strtod (ptr, NULL);
-  star[1][0].measure.dMcal = sqrt (SQ(dMfull) - SQ(star[1][0].measure.dM));
+  measure[1].dMcal = sqrt (SQ(dMfull) - SQ(measure[1].dM));
   ptr = next2MASSfield (ptr); // h_snr (skip)
 
   ptr = next2MASSfield (ptr); // k_m
-  star[2][0].measure.M  = strtod (ptr, NULL);
+  measure[2].M  = strtod (ptr, NULL);
   ptr = next2MASSfield (ptr); // k_cmsig
-  star[2][0].measure.dM = strtod (ptr, NULL);
+  measure[2].dM = strtod (ptr, NULL);
   ptr = next2MASSfield (ptr); // k_msigcom
   dMfull = strtod (ptr, NULL);
-  star[2][0].measure.dMcal = sqrt (SQ(dMfull) - SQ(star[2][0].measure.dM));
+  measure[2].dMcal = sqrt (SQ(dMfull) - SQ(measure[2].dM));
   ptr = next2MASSfield (ptr); // k_snr (skip)
 
-  star[2][0].measure.photFlags = star[1][0].measure.photFlags = star[0][0].measure.photFlags = 0;
+  measure[2].photFlags = measure[1].photFlags = measure[0].photFlags = 0;
 
   ptr = next2MASSfield (ptr); // ph_qual
-  set2MASS_ph_qual (star[0], ptr[0]);
-  set2MASS_ph_qual (star[1], ptr[1]);
-  set2MASS_ph_qual (star[2], ptr[2]);
+  set2MASS_ph_qual (&measure[0], ptr[0]);
+  set2MASS_ph_qual (&measure[1], ptr[1]);
+  set2MASS_ph_qual (&measure[2], ptr[2]);
 
   ptr = next2MASSfield (ptr); // rd_flg
-  set2MASS_rd_flag (star[0], ptr[0]);
-  set2MASS_rd_flag (star[1], ptr[1]);
-  set2MASS_rd_flag (star[2], ptr[2]);
+  set2MASS_rd_flag (&measure[0], ptr[0]);
+  set2MASS_rd_flag (&measure[1], ptr[1]);
+  set2MASS_rd_flag (&measure[2], ptr[2]);
 
   ptr = next2MASSfield (ptr); // bl_flg
-  set2MASS_bl_flag (star[0], ptr[0]);
-  set2MASS_bl_flag (star[1], ptr[1]);
-  set2MASS_bl_flag (star[2], ptr[2]);
+  set2MASS_bl_flag (&measure[0], ptr[0]);
+  set2MASS_bl_flag (&measure[1], ptr[1]);
+  set2MASS_bl_flag (&measure[2], ptr[2]);
 
   ptr = next2MASSfield (ptr); // cc_flg
-  set2MASS_cc_flag (star[0], ptr[0]);
-  set2MASS_cc_flag (star[1], ptr[1]);
-  set2MASS_cc_flag (star[2], ptr[2]);
+  set2MASS_cc_flag (&measure[0], ptr[0]);
+  set2MASS_cc_flag (&measure[1], ptr[1]);
+  set2MASS_cc_flag (&measure[2], ptr[2]);
 
   ptr = next2MASSfield (ptr); // ndet (skip for now, XXX use somehow?)
@@ -84,12 +84,12 @@
 
   ptr = next2MASSfield (ptr); // gal_contam (one flag for all filters)
-  set2MASS_gal_flag (star[0], ptr[0]);
-  set2MASS_gal_flag (star[1], ptr[0]);
-  set2MASS_gal_flag (star[2], ptr[0]);
+  set2MASS_gal_flag (&measure[0], ptr[0]);
+  set2MASS_gal_flag (&measure[1], ptr[0]);
+  set2MASS_gal_flag (&measure[2], ptr[0]);
 
   ptr = next2MASSfield (ptr); // mp_flg (one flag for all filters)
-  set2MASS_mp_flag (star[0], ptr[0]);
-  set2MASS_mp_flag (star[1], ptr[0]);
-  set2MASS_mp_flag (star[2], ptr[0]);
+  set2MASS_mp_flag (&measure[0], ptr[0]);
+  set2MASS_mp_flag (&measure[1], ptr[0]);
+  set2MASS_mp_flag (&measure[2], ptr[0]);
 
   ptr = next2MASSfield (ptr); // pts_key (skip for now, XXX use somehow?)
@@ -101,29 +101,29 @@
 
   ptr = next2MASSfield (ptr); // x_scan
-  star[0][0].measure.Xccd = strtod (ptr, NULL);
-  star[2][0].measure.Xccd = star[1][0].measure.Xccd = star[0][0].measure.Xccd;
+  measure[0].Xccd = strtod (ptr, NULL);
+  measure[2].Xccd = measure[1].Xccd = measure[0].Xccd;
 
   ptr = next2MASSfield (ptr); // jdate (julian date)
   jd = strtod (ptr, NULL);
-  star[0][0].measure.t = ohana_jd_to_sec (jd);
-  star[2][0].measure.t = star[1][0].measure.t = star[0][0].measure.t;
+  measure[0].t = ohana_jd_to_sec (jd);
+  measure[2].t = measure[1].t = measure[0].t;
 
   ptr = next2MASSfield (ptr); // j_psfchi
-  star[0][0].measure.psfChisq = strtod (ptr, NULL);
+  measure[0].psfChisq = strtod (ptr, NULL);
   ptr = next2MASSfield (ptr); // h_psfchi
-  star[1][0].measure.psfChisq = strtod (ptr, NULL);
+  measure[1].psfChisq = strtod (ptr, NULL);
   ptr = next2MASSfield (ptr); // k_psfchi
-  star[2][0].measure.psfChisq = strtod (ptr, NULL);
+  measure[2].psfChisq = strtod (ptr, NULL);
 
   ptr = next2MASSfield (ptr); // j_m_stdap
-  star[0][0].measure.Map = strtod (ptr, NULL);
+  measure[0].Map = strtod (ptr, NULL);
   ptr = next2MASSfield (ptr); // j_msig_stdap (skip?)
 
   ptr = next2MASSfield (ptr); // h_m_stdap
-  star[1][0].measure.Map = strtod (ptr, NULL);
+  measure[1].Map = strtod (ptr, NULL);
   ptr = next2MASSfield (ptr); // h_msig_stdap (skip?)
 
   ptr = next2MASSfield (ptr); // k_m_stdap
-  star[2][0].measure.Map = strtod (ptr, NULL);
+  measure[2].Map = strtod (ptr, NULL);
   ptr = next2MASSfield (ptr); // k_msig_stdap (skip?)
 
@@ -133,24 +133,24 @@
 
   ptr = next2MASSfield (ptr); // dup_src (one flag for all filters)
-  set2MASS_dup_flag (star[0], ptr[0]);
-  set2MASS_dup_flag (star[1], ptr[0]);
-  set2MASS_dup_flag (star[2], ptr[0]);
+  set2MASS_dup_flag (&measure[0], ptr[0]);
+  set2MASS_dup_flag (&measure[1], ptr[0]);
+  set2MASS_dup_flag (&measure[2], ptr[0]);
 
   ptr = next2MASSfield (ptr); // use_src (one flag for all filters)
-  set2MASS_use_flag (star[0], ptr[0]);
-  set2MASS_use_flag (star[1], ptr[0]);
-  set2MASS_use_flag (star[2], ptr[0]);
-
-  star[0][0].measure.photcode  = TM_J;
-  star[0][0].measure.detID   = 0;
-  star[0][0].measure.imageID = 0;
-
-  star[1][0].measure.photcode  = TM_H;
-  star[1][0].measure.detID   = 0;
-  star[1][0].measure.imageID = 0;
-
-  star[2][0].measure.photcode  = TM_K;
-  star[2][0].measure.detID   = 0;
-  star[2][0].measure.imageID = 0;
+  set2MASS_use_flag (&measure[0], ptr[0]);
+  set2MASS_use_flag (&measure[1], ptr[0]);
+  set2MASS_use_flag (&measure[2], ptr[0]);
+
+  measure[0].photcode  = TM_J;
+  measure[0].detID   = 0;
+  measure[0].imageID = 0;
+
+  measure[1].photcode  = TM_H;
+  measure[1].detID   = 0;
+  measure[1].imageID = 0;
+
+  measure[2].photcode  = TM_K;
+  measure[2].detID   = 0;
+  measure[2].imageID = 0;
 
   return TRUE;
@@ -170,15 +170,15 @@
 }
 
-int set2MASS_ph_qual (Stars *star, char qual) {
-
-  switch (qual) {
-    case 'A': star[0].measure.photFlags |= 0x00000001; break; // was: 0x0004
-    case 'B': star[0].measure.photFlags |= 0x00000002; break; // was: 0x0005
-    case 'C': star[0].measure.photFlags |= 0x00000004; break; // was: 0x0006
-    case 'D': star[0].measure.photFlags |= 0x00000008; break; // was: 0x0007
-    case 'E': star[0].measure.photFlags |= 0x00000010; break; // was: 0x0003
-    case 'F': star[0].measure.photFlags |= 0x00000020; break; // was: 0x0002
-    case 'U': star[0].measure.photFlags |= 0x00000040; break; // was: 0x0001
-    case 'X': star[0].measure.photFlags |= 0x00000080; break; // was: 0x0000
+int set2MASS_ph_qual (Measure *measure, char qual) {
+
+  switch (qual) {
+    case 'A': measure[0].photFlags |= 0x00000001; break; // was: 0x0004
+    case 'B': measure[0].photFlags |= 0x00000002; break; // was: 0x0005
+    case 'C': measure[0].photFlags |= 0x00000004; break; // was: 0x0006
+    case 'D': measure[0].photFlags |= 0x00000008; break; // was: 0x0007
+    case 'E': measure[0].photFlags |= 0x00000010; break; // was: 0x0003
+    case 'F': measure[0].photFlags |= 0x00000020; break; // was: 0x0002
+    case 'U': measure[0].photFlags |= 0x00000040; break; // was: 0x0001
+    case 'X': measure[0].photFlags |= 0x00000080; break; // was: 0x0000
     default: 
       fprintf (stderr, "error!\n");
@@ -188,14 +188,14 @@
 }
 
-int set2MASS_rd_flag (Stars *star, char qual) {
-
-  switch (qual) {
-    case '0': star[0].measure.photFlags |= 0x00000100; break; // was: 0x0000 
-    case '1': star[0].measure.photFlags |= 0x00000200; break; // was: 0x0010 
-    case '2': star[0].measure.photFlags |= 0x00000400; break; // was: 0x0020 
-    case '3': star[0].measure.photFlags |= 0x00000800; break; // was: 0x0030 
-    case '4': star[0].measure.photFlags |= 0x00001000; break; // was: 0x0040 
-    case '6': star[0].measure.photFlags |= 0x00002000; break; // was: 0x0050 
-    case '9': star[0].measure.photFlags |= 0x00004000; break; // was: 0x0060 
+int set2MASS_rd_flag (Measure *measure, char qual) {
+
+  switch (qual) {
+    case '0': measure[0].photFlags |= 0x00000100; break; // was: 0x0000 
+    case '1': measure[0].photFlags |= 0x00000200; break; // was: 0x0010 
+    case '2': measure[0].photFlags |= 0x00000400; break; // was: 0x0020 
+    case '3': measure[0].photFlags |= 0x00000800; break; // was: 0x0030 
+    case '4': measure[0].photFlags |= 0x00001000; break; // was: 0x0040 
+    case '6': measure[0].photFlags |= 0x00002000; break; // was: 0x0050 
+    case '9': measure[0].photFlags |= 0x00004000; break; // was: 0x0060 
     default: 
       fprintf (stderr, "error!\n");
@@ -205,13 +205,13 @@
 }
 
-int set2MASS_cc_flag (Stars *star, char qual) {
-
-  switch (qual) {
-    case 'p': star[0].measure.photFlags |= 0x00010000; break; // was: 0x0000
-    case 'c': star[0].measure.photFlags |= 0x00020000; break; // was: 0x0100
-    case 'd': star[0].measure.photFlags |= 0x00040000; break; // was: 0x0200
-    case 's': star[0].measure.photFlags |= 0x00080000; break; // was: 0x0300
-    case 'b': star[0].measure.photFlags |= 0x00010000; break; // was: 0x0400
-    case '0': star[0].measure.photFlags |= 0x00020000; break; // was: 0x0500
+int set2MASS_cc_flag (Measure *measure, char qual) {
+
+  switch (qual) {
+    case 'p': measure[0].photFlags |= 0x00010000; break; // was: 0x0000
+    case 'c': measure[0].photFlags |= 0x00020000; break; // was: 0x0100
+    case 'd': measure[0].photFlags |= 0x00040000; break; // was: 0x0200
+    case 's': measure[0].photFlags |= 0x00080000; break; // was: 0x0300
+    case 'b': measure[0].photFlags |= 0x00010000; break; // was: 0x0400
+    case '0': measure[0].photFlags |= 0x00020000; break; // was: 0x0500
     default: 
       fprintf (stderr, "error!\n");
@@ -221,21 +221,21 @@
 }
 
-int set2MASS_bl_flag (Stars *star, char qual) {
-
-  switch (qual) {
-    case '0': star[0].measure.photFlags &= ~0x00300000; break; // was: ~0x0008
-    case '1': star[0].measure.photFlags |=  0x00100000; break; // was: ~0x0008
-    default:  star[0].measure.photFlags |=  0x00200000; break; // was:  0x0008
-  }      
-  return (TRUE);
-}
-
-int set2MASS_gal_flag (Stars *star, char qual) {
-
-  switch (qual) {
-    case '0': star[0].measure.photFlags &= ~0x00c00000; break; // was: ~0x0080 
-    case '1': star[0].measure.photFlags |=  0x00400000; break; // was: ~0x0080 
-    default:  star[0].measure.photFlags |=  0x00800000;	       // was:  0x0080
-      star[0].measure.extNsigma = 100.0;
+int set2MASS_bl_flag (Measure *measure, char qual) {
+
+  switch (qual) {
+    case '0': measure[0].photFlags &= ~0x00300000; break; // was: ~0x0008
+    case '1': measure[0].photFlags |=  0x00100000; break; // was: ~0x0008
+    default:  measure[0].photFlags |=  0x00200000; break; // was:  0x0008
+  }      
+  return (TRUE);
+}
+
+int set2MASS_gal_flag (Measure *measure, char qual) {
+
+  switch (qual) {
+    case '0': measure[0].photFlags &= ~0x00c00000; break; // was: ~0x0080 
+    case '1': measure[0].photFlags |=  0x00400000; break; // was: ~0x0080 
+    default:  measure[0].photFlags |=  0x00800000;	       // was:  0x0080
+      measure[0].extNsigma = 100.0;
       break;
   }      
@@ -243,29 +243,29 @@
 }
 
-int set2MASS_mp_flag (Stars *star, char qual) {
-
-  switch (qual) {
-    case '0': star[0].measure.photFlags &= ~0x03000000; break; // was: ~0x0800
-    case '1': star[0].measure.photFlags |=  0x01000000; break; // was: ~0x0800
-    default:  star[0].measure.photFlags |=  0x02000000; break; // was:  0x0800
-  }      
-  return (TRUE);
-}
-
-int set2MASS_dup_flag (Stars *star, char qual) {
-
-  switch (qual) {
-    case '0': star[0].measure.photFlags &= ~0x0c000000; break; // was: ~0x1000
-    case '1': star[0].measure.photFlags |=  0x04000000; break; // was: ~0x1000
-    default:  star[0].measure.photFlags |=  0x08000000; break; // was:  0x1000
-  }      
-  return (TRUE);
-}
-
-int set2MASS_use_flag (Stars *star, char qual) {
-
-  switch (qual) {
-    case '0': star[0].measure.photFlags &= ~0x10000000; break; // was: ~0x2000
-    case '1': star[0].measure.photFlags |=  0x10000000; break; // was:  0x2000
+int set2MASS_mp_flag (Measure *measure, char qual) {
+
+  switch (qual) {
+    case '0': measure[0].photFlags &= ~0x03000000; break; // was: ~0x0800
+    case '1': measure[0].photFlags |=  0x01000000; break; // was: ~0x0800
+    default:  measure[0].photFlags |=  0x02000000; break; // was:  0x0800
+  }      
+  return (TRUE);
+}
+
+int set2MASS_dup_flag (Measure *measure, char qual) {
+
+  switch (qual) {
+    case '0': measure[0].photFlags &= ~0x0c000000; break; // was: ~0x1000
+    case '1': measure[0].photFlags |=  0x04000000; break; // was: ~0x1000
+    default:  measure[0].photFlags |=  0x08000000; break; // was:  0x1000
+  }      
+  return (TRUE);
+}
+
+int set2MASS_use_flag (Measure *measure, char qual) {
+
+  switch (qual) {
+    case '0': measure[0].photFlags &= ~0x10000000; break; // was: ~0x2000
+    case '1': measure[0].photFlags |=  0x10000000; break; // was:  0x2000
     default:  abort();
   }      
Index: /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/get2mass_ops.c
===================================================================
--- /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/get2mass_ops.c	(revision 38592)
+++ /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/get2mass_ops.c	(revision 38593)
@@ -36,4 +36,5 @@
 }
 
+# if (0)
 // fill in the data for a single star.  takes a pointer to the start of the line
 int get2mass_star (Stars *star, char *line, int Nmax) {
@@ -136,4 +137,5 @@
   return TRUE;
 }
+# endif
 
 // fill in the coords for a single star.  takes a pointer to the start of the line
Index: /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/getgsc.c
===================================================================
--- /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/getgsc.c	(revision 38592)
+++ /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/getgsc.c	(revision 38593)
@@ -4,12 +4,11 @@
 # define DNSTARS 1000
 
-static short GSC_M;
 static SkyTable *sky = NULL;
 
-Stars *getgsc (SkyRegion *patch, unsigned int *NSTARS) {
+static short int GSC_M;
+
+Catalog *getgsc (SkyRegion *patch) {
   
-  unsigned int i, Ngsc, Nstars; 
-  Stars *gsc;
-  Stars *stars;
+  unsigned int i; 
   SkyList *skylist;
 
@@ -23,36 +22,57 @@
   skylist = SkyListByPatch (sky, -1, patch);
   
-  Nstars = 0;
-  ALLOCATE (stars, Stars, 1);
-  
+  Catalog *catalog = NULL;
+  ALLOCATE (catalog, Catalog, 1);
+  dvo_catalog_init (catalog, TRUE);
+  ALLOCATE (catalog->average, Average, 1);
+  ALLOCATE (catalog->measure, Measure, 1);
+  ALLOCATE (catalog->lensing, Lensing, 1);
+
+  SkyRegion region;
+  region.Rmin =   0.0;
+  region.Rmax = 360.0;
+  region.Dmin = -90.0;
+  region.Dmax = +90.0;
+
   for (i = 0; i < skylist[0].Nregions; i++) {
-    gsc = rd_gsc (skylist[0].filename[i], &Ngsc);
+    Catalog *newcat = rd_gsc (skylist[0].filename[i]);
 
-    REALLOCATE (stars, Stars, MAX (1, Nstars + Ngsc));
-    memcpy (&stars[Nstars], gsc, Ngsc*sizeof(Stars));
-    Nstars += Ngsc;
-
-    free (gsc);
+    AddstarClientOptions matchOptions;
+    matchOptions.radius = 0.4; // tight radius at this stage
+    matchOptions.calibrate = FALSE;
+    matchOptions.only_match = FALSE;
+    matchOptions.nosort = FALSE;
+    matchOptions.photcode = 0; // use an invalid photcode to avoid touching secfilt
+    
+    find_matches_closest (&region, newcat, catalog, matchOptions);
+    
+    if (newcat) {
+      dvo_catalog_free (newcat);
+      free (newcat);
+    }
   }
   
-  // XXX don't free because we only load it once and save it
   SkyListFree (skylist);
-  // SkyTableFree (sky);
 
-  if (VERBOSE) fprintf (stderr, "%d stars from HST GSC\n", Nstars);
-  *NSTARS = Nstars;
-  return (stars);
+  if (VERBOSE) fprintf (stderr, "%d stars from HST GSC\n", (int) catalog->Naverage);
+  return (catalog);
 }  
 
-Stars *rd_gsc (char *filename, unsigned int *nstars) {
+Catalog *rd_gsc (char *filename) {
   
-  int i, NSTARS, Nstars, Nbytes, nbytes, Nline, Nbyte;
+  int i, Nbytes, nbytes, Nline, Nbyte;
   char *buffer;
   FILE *f;
-  Stars *stars;
 
-  Nstars = 0;
-  NSTARS = 1000;
-  ALLOCATE (stars, Stars, NSTARS);
+  int Nave = 0;
+  int Nmeas = 0;
+  int NAVE = 1000;
+  int NMEAS = 1000;
+
+  Catalog *catalog = NULL;
+  ALLOCATE (catalog, Catalog, 1);
+  dvo_catalog_init (catalog, TRUE);
+  ALLOCATE (catalog->average, Average, NAVE);
+  ALLOCATE (catalog->measure, Measure, NMEAS);
 
   f = fopen (filename, "r");
@@ -68,31 +88,36 @@
     for (i = 0; i < Nline; i++) {
 
-      InitStar (&stars[Nstars]);
+      dvo_average_init (&catalog->average[Nave]);
+      dvo_measure_init (&catalog->measure[Nmeas]);
 
       Nbyte = i*BYTES_STAR;
-      dparse (&stars[Nstars].average.R, 1, &buffer[Nbyte]);
-      dparse (&stars[Nstars].average.D, 2, &buffer[Nbyte]);
+      dparse (&catalog->average[Nave].R, 1, &buffer[Nbyte]);
+      dparse (&catalog->average[Nave].D, 2, &buffer[Nbyte]);
 
-      if (stars[Nstars].average.R < UserPatch.Rmin) continue;
-      if (stars[Nstars].average.R > UserPatch.Rmax) continue;
-      if (stars[Nstars].average.D < UserPatch.Dmin) continue;
-      if (stars[Nstars].average.D > UserPatch.Dmax) continue;
+      if (catalog->average[Nave].R < UserPatch.Rmin) continue;
+      if (catalog->average[Nave].R > UserPatch.Rmax) continue;
+      if (catalog->average[Nave].D < UserPatch.Dmin) continue;
+      if (catalog->average[Nave].D > UserPatch.Dmax) continue;
 
-      stars[Nstars].measure.R = stars[Nstars].average.R;
-      stars[Nstars].measure.D = stars[Nstars].average.D;
+      catalog->measure[Nmeas].R = catalog->average[Nave].R;
+      catalog->measure[Nmeas].D = catalog->average[Nave].D;
 
-      fparse (&stars[Nstars].measure.M, 3, &buffer[Nbyte]);
-      stars[Nstars].measure.dM 	      = NAN;
-      stars[Nstars].measure.photcode  = GSC_M;
-      stars[Nstars].measure.t  	      = 0;
+      fparse (&catalog->measure[Nmeas].M, 3, &buffer[Nbyte]);
+      catalog->measure[Nmeas].dM = NAN;
+      catalog->measure[Nmeas].photcode = GSC_M;
+      catalog->measure[Nmeas].t = 0;
 
-      Nstars ++;
-      CHECK_REALLOCATE (stars, Stars, NSTARS, Nstars, 1000);
+      catalog->average[Nave].Nmeasure = 1;
+      catalog->average[Nave].measureOffset = Nmeas;
+
+      Nave ++;
+      Nmeas ++;
+
+      CHECK_REALLOCATE (catalog->average, Average, NAVE,  Nave,  1000);
+      CHECK_REALLOCATE (catalog->measure, Measure, NMEAS, Nmeas, 1000);
     }
   }
   fclose (f);
   free (buffer);
-  REALLOCATE (stars, Stars, Nstars);
-  *nstars = Nstars;
-  return (stars);
+  return (catalog);
 }
Index: /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/getusno.c
===================================================================
--- /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/getusno.c	(revision 38592)
+++ /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/getusno.c	(revision 38593)
@@ -4,5 +4,5 @@
 # define NELEM  3
 
-Stars *getusno (SkyRegion *catstats, int photcode, unsigned int *nstars) {
+Catalog *getusno (SkyRegion *catstats) {
 
   off_t offset;
@@ -15,6 +15,4 @@
   double dec;
   int spd, spd_start, spd_end;
-  int NUSNO, Nusno;
-  Stars *stars;
   short int USNO_RED, USNO_BLUE;
 
@@ -22,8 +20,4 @@
   NAMED_PHOTCODE (USNO_RED, "USNO_RED");
   NAMED_PHOTCODE (USNO_BLUE, "USNO_BLUE");
-  if (photcode == USNO_RED) goto good_code;
-  if (photcode == USNO_BLUE) goto good_code;
-  Shutdown ("USNO photcode not specified");
-good_code:
 
   /* identify ra & dec range of interest */
@@ -43,7 +37,14 @@
   }
 
-  Nusno = 0;
-  NUSNO = 5000;
-  ALLOCATE (stars, Stars, NUSNO);
+  int Nave = 0;
+  int Nmeas = 0;
+  int NAVE = 1000;
+  int NMEAS = 1000;
+
+  Catalog *catalog = NULL;
+  ALLOCATE (catalog, Catalog, 1);
+  dvo_catalog_init (catalog, TRUE);
+  ALLOCATE (catalog->average, Average, NAVE);
+  ALLOCATE (catalog->measure, Measure, NMEAS);
 
   for (spd = spd_start; spd < spd_end; spd += 75) {
@@ -110,32 +111,40 @@
       if (buf[1] > iDEC1) continue;
 
-      InitStar (&stars[Nusno]);
+      dvo_average_init (&catalog->average[Nave]);
+      dvo_measure_init (&catalog->measure[Nmeas+0]);
+      dvo_measure_init (&catalog->measure[Nmeas+1]);
 
-      stars[Nusno].average.R     = buf[0]/360000.0;
-      stars[Nusno].average.D     = buf[1]/360000.0 - 90.0;
-      stars[Nusno].measure.R     = stars[Nusno].average.R;
-      stars[Nusno].measure.D     = stars[Nusno].average.D;
-      stars[Nusno].measure.dM    = NAN;
+      catalog->average[Nave].R     = buf[0]/360000.0;
+      catalog->average[Nave].D     = buf[1]/360000.0 - 90.0;
 
-      /* one pass of addstar does either r or b */
-      if (photcode == USNO_RED) {
-	stars[Nusno].measure.photcode = USNO_RED;
-	stars[Nusno].measure.M        = fabs (0.1*(buf[2] - 1000*((int)(buf[2]/1000))));
-      } 
-      if (photcode == USNO_BLUE) {	
-	stars[Nusno].measure.photcode = USNO_BLUE;
-	stars[Nusno].measure.M        = fabs (0.1*((int)(buf[2] - 1000000*((int)(buf[2]/1000000))) / 1000));
-      }
-      Nusno ++;
-      CHECK_REALLOCATE (stars, Stars, NUSNO, Nusno, 5000);
+      catalog->measure[Nmeas+0].R  = catalog->average[Nave].R;
+      catalog->measure[Nmeas+0].D  = catalog->average[Nave].D;
+      catalog->measure[Nmeas+0].dM = NAN;
+      catalog->measure[Nmeas+1].R  = catalog->average[Nave].R;
+      catalog->measure[Nmeas+1].D  = catalog->average[Nave].D;
+      catalog->measure[Nmeas+1].dM = NAN;
+
+      catalog->measure[Nmeas+0].photcode = USNO_RED;
+      catalog->measure[Nmeas+0].M        = fabs (0.1*(buf[2] - 1000*((int)(buf[2]/1000))));
+      catalog->measure[Nmeas+1].photcode = USNO_BLUE;
+      catalog->measure[Nmeas+1].M        = fabs (0.1*((int)(buf[2] - 1000000*((int)(buf[2]/1000000))) / 1000));
+
+      catalog->average[Nave].Nmeasure = 2;
+      catalog->average[Nave].measureOffset = Nmeas;
+
+      Nave ++;
+      Nmeas += 2;
+
+      CHECK_REALLOCATE (catalog->average, Average, NAVE,  Nave,  1000);
+      CHECK_REALLOCATE (catalog->measure, Measure, NMEAS, Nmeas, 1000);
     }
     free (buffer);
     fclose (f);
   }
-  REALLOCATE (stars, Stars, Nusno);
+  catalog->Naverage = Nave;
+  catalog->Nmeasure = Nmeas;
 
-  *nstars = Nusno;
-  if (VERBOSE) fprintf (stderr, "%d stars from USNO 1.0\n", Nusno);
-  return (stars);
+  if (VERBOSE) fprintf (stderr, "%d stars from USNO 1.0\n", Nave);
+  return (catalog);
 }
 
Index: /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/getusnob.c
===================================================================
--- /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/getusnob.c	(revision 38592)
+++ /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/getusnob.c	(revision 38593)
@@ -3,8 +3,8 @@
 # define NELEM  20
 
-Stars *getusnob (SkyRegion *catstats, int photcode, unsigned int *nstars) {
+Catalog *getusnob (SkyRegion *catstats) {
 
   off_t offset;
-  int i, bin, first, last, nitems, Nitems, Nbins, Nitemsum;
+  int i, j, bin, first, last, nitems, Nitems, Nbins, Nitemsum;
   float hours[100];
   int start[100], number[100], *buffer, *buf;
@@ -15,8 +15,6 @@
   int iDEC0, iDEC1, iRA0, iRA1;
   int spd, spd_start, spd_end;
-  int NUSNO, Nusno, Nstars;
   short int USNO_RED, USNO_BLUE, USNO_N;
   e_time USNOepoch;
-  Stars *stars;
 
   m1 = m2 = 0.0;
@@ -26,9 +24,4 @@
   NAMED_PHOTCODE (USNO_BLUE, "USNO_BLUE");
   NAMED_PHOTCODE (USNO_N,    "USNO_N");
-  if (photcode == USNO_RED)  goto good_code;
-  if (photcode == USNO_BLUE) goto good_code;
-  if (photcode == USNO_N)    goto good_code;
-  Shutdown ("USNO photcode not specified");
-good_code:
 
   fprintf (stderr, "loading USNO-B 1.0\n");
@@ -52,7 +45,15 @@
 
   Nitemsum = 0;
-  Nusno = 0;
-  NUSNO = 5000;
-  ALLOCATE (stars, Stars, NUSNO);
+
+  int Nave = 0;
+  int Nmeas = 0;
+  int NAVE = 1000;
+  int NMEAS = 1000;
+
+  Catalog *catalog = NULL;
+  ALLOCATE (catalog, Catalog, 1);
+  dvo_catalog_init (catalog, TRUE);
+  ALLOCATE (catalog->average, Average, NAVE);
+  ALLOCATE (catalog->measure, Measure, NMEAS);
 
   for (spd = spd_start; spd < spd_end; spd ++) {
@@ -96,5 +97,5 @@
 
     /* sum the number of stars in data segment of interest */
-    Nstars = 0;
+    int Nstars = 0;
     for (bin = first; bin < last; bin++) {
       Nstars += number[bin];
@@ -125,48 +126,35 @@
       /* USNO coords are reported for J2000 / epoch 2000.0 */
       /* extract the basic stellar data */
-      InitStar (&stars[Nusno]);
+      dvo_average_init (&catalog->average[Nave]);
+      dvo_measure_init (&catalog->measure[Nmeas+0]);
+      dvo_measure_init (&catalog->measure[Nmeas+1]);
 
-      stars[Nusno].average.R   = buf[0]/360000.0;
-      stars[Nusno].average.D   = buf[1]/360000.0 - 90.0;
+      catalog->average[Nave].R   = buf[0]/360000.0;
+      catalog->average[Nave].D   = buf[1]/360000.0 - 90.0;
 
       /* XXX uR cos(D) or just uR ??? */
-      stars[Nusno].average.uR  = 2.0 * ((buf[2]       % 10000) - 5000);
-      stars[Nusno].average.uD  = 2.0 * ((buf[2]/10000 % 10000) - 5000);
+      catalog->average[Nave].uR  = 2.0 * ((buf[2]       % 10000) - 5000);
+      catalog->average[Nave].uD  = 2.0 * ((buf[2]/10000 % 10000) - 5000);
 
-      stars[Nusno].average.duR = (buf[3]      % 1000);
-      stars[Nusno].average.duD = (buf[3]/1000 % 1000);
-
-      stars[Nusno].average.dR  = 0.001 * (buf[4]      % 1000);
-      stars[Nusno].average.dD  = 0.001 * (buf[4]/1000 % 1000);
-
-      stars[Nusno].average.P   = 0;
-      stars[Nusno].average.dP  = 0;
-
-      stars[Nusno].measure.R   = stars[Nusno].average.R;
-      stars[Nusno].measure.D   = stars[Nusno].average.D;
-
-      /* USNO magnitude errors are reported as a fixed 0.3 mag */
-      stars[Nusno].measure.dM  = 0.3;
+      catalog->average[Nave].duR = (buf[3]      % 1000);
+      catalog->average[Nave].duD = (buf[3]/1000 % 1000);
+      catalog->average[Nave].dR  = 0.001 * (buf[4]      % 1000);
+      catalog->average[Nave].dD  = 0.001 * (buf[4]/1000 % 1000);
+      catalog->average[Nave].P   = 0;
+      catalog->average[Nave].dP  = 0;
 
       /* USNO-B uses J2000 equinox and 2000.0 epoch for coordinates */
       /* the magnitudes have no temporal information */ 
-      stars[Nusno].measure.t   = USNOepoch;
 
-      /* one pass of addstar does r, b, or n */
-      if (photcode == USNO_BLUE) {
-	  m1 = fabs(0.01 * (buf[5] % 10000)); /* 1st blue mag */
-	  m2 = fabs(0.01 * (buf[7] % 10000)); /* 1st blue mag */
+      for (j = 0; j < 3; j++) {
+	catalog->measure[Nmeas+j].R  = catalog->average[Nave].R;
+	catalog->measure[Nmeas+j].D  = catalog->average[Nave].D;
+	catalog->measure[Nmeas+j].dM = 0.3; /* USNO magnitude errors are reported as a fixed 0.3 mag */
+	catalog->measure[Nmeas+j].t  = USNOepoch;
       }
-      if (photcode == USNO_RED) {
-	  m1 = fabs(0.01 * (buf[6] % 10000)); /* 1st red mag */
-	  m2 = fabs(0.01 * (buf[8] % 10000)); /* 2nd red mag */
-      }
-      if (photcode == USNO_N) {
-	  m1 = fabs(0.01 * (buf[9] % 10000)); /* N (IR) survey */
-	  m2 = 0;
-      }
-      stars[Nusno].measure.photcode = photcode;
 
-      /* if two mags are available, get an average */
+      catalog->measure[Nmeas+0].photcode = USNO_BLUE;
+      m1 = fabs(0.01 * (buf[5] % 10000)); /* 1st blue mag */
+      m2 = fabs(0.01 * (buf[7] % 10000)); /* 2nd blue mag */
       if (m1 && m2) {
 	mag = 0.5*(m1 + m2);
@@ -174,19 +162,37 @@
 	mag = (m1) ? m1 : m2;
       }
-      stars[Nusno].measure.M = (mag == 0.0) ? 32.0 : mag;
+      catalog->measure[Nmeas+0].M = (mag == 0.0) ? 32.0 : mag;
 
-      Nusno ++;
-      CHECK_REALLOCATE (stars, Stars, NUSNO, Nusno, 5000);
+      catalog->measure[Nmeas+1].photcode = USNO_RED;
+      m1 = fabs(0.01 * (buf[6] % 10000)); /* 1st red mag */
+      m2 = fabs(0.01 * (buf[8] % 10000)); /* 2nd red mag */
+      if (m1 && m2) {
+	mag = 0.5*(m1 + m2);
+      } else {
+	mag = (m1) ? m1 : m2;
+      }
+      catalog->measure[Nmeas+1].M = (mag == 0.0) ? 32.0 : mag;
+      
+      catalog->measure[Nmeas+2].photcode = USNO_N;
+      catalog->measure[Nmeas+2].M = fabs(0.01 * (buf[9] % 10000)); /* N (IR) survey */
+
+      catalog->average[Nave].Nmeasure = 3;
+      catalog->average[Nave].measureOffset = Nmeas;
+
+      Nave ++;
+      Nmeas += 3;
+
+      CHECK_REALLOCATE (catalog->average, Average, NAVE,  Nave,  1000);
+      CHECK_REALLOCATE (catalog->measure, Measure, NMEAS, Nmeas, 1000);
     }
     free (buffer);
     Nitemsum += Nitems;
-    if (VERBOSE) fprintf (stderr, "Nusno: %d, Nitems: %d, Nitemsum : %d, Nbytes stars: %d\n", Nusno, Nitems, Nitemsum, (unsigned int) (Nusno*sizeof(Stars)));
+    if (VERBOSE) fprintf (stderr, "Naverage: %d, Nitems: %d, Nitemsum : %d\n", Nave, Nitems, Nitemsum);
     fclose (f);
   }
+  catalog->Naverage = Nave;
+  catalog->Nmeasure = Nmeas;
 
-  REALLOCATE (stars, Stars, MAX (1, Nusno));
-
-  *nstars = Nusno;
-  if (VERBOSE) fprintf (stderr, "%d stars from USNO-B 1.0\n", Nusno);
-  return (stars);
+  if (VERBOSE) fprintf (stderr, "%d stars from USNO-B 1.0\n", Nave);
+  return (catalog);
 }
Index: /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/greference.c
===================================================================
--- /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/greference.c	(revision 38592)
+++ /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/greference.c	(revision 38593)
@@ -3,28 +3,28 @@
 # define LOAD_DR2    1
 
-Stars *greference (char *Refcat, SkyRegion *region, int photcode, unsigned int *nstars) {
+Catalog *greference (char *Refcat, SkyRegion *region, int photcode) {
 
-  unsigned int Nstars;
-  Stars *stars;
+  Catalog *catalog;
 
   if (VERBOSE) fprintf (stderr, "loading reference catalog data from %s\n", Refcat); 
   if (VERBOSE) fprintf (stderr, "full region: %f - %f, %f - %f\n", region[0].Rmin, region[0].Rmax, region[0].Dmin, region[0].Dmax);
 
-  Nstars = 0;
-  stars = NULL;
-
+  /* get stars from HST GSC for the given region */
+  if (!strcasecmp (Refcat, "GSC")) {
+    catalog = getgsc (region);
+  }
+  
   /* get stars from USNO for the given region */
   if (!strcasecmp (Refcat, "USNO")) {
-    stars = getusno (region, photcode, &Nstars);
+    catalog = getusno (region);
   }
 
   /* get stars from the USNO B catalog for the given region */
   if (!strcasecmp (Refcat, "USNOB")) {
-    stars = getusnob (region, photcode, &Nstars);
+    catalog = getusnob (region);
   }
 
   /* get stars from the Tycho catalog for the given region */
   if (!strcasecmp (Refcat, "TYCHO")) {
-    // stars = gettycho2 (region, photcode, &Nstars);
     fprintf (stderr, "Tycho load via addstar is deprecated: use loadtycho\n");
     exit (2);
@@ -33,17 +33,10 @@
   /* get stars from the Tycho catalog for the given region (old ingest) */
   if (!strcasecmp (Refcat, "TYCHO_OLD")) {
-    // stars = gettycho (region, photcode, &Nstars);
     fprintf (stderr, "Tycho load via addstar is deprecated: use loadtycho\n");
     exit (2);
   }
 
-  /* get stars from HST GSC for the given region */
-  if (!strcasecmp (Refcat, "GSC")) {
-    stars = getgsc (region, &Nstars);
-  }
-  
   /* get stars from 2MASS for the given region */
   if (!strcasecmp (Refcat, "2MASS")) {
-    // stars = get2mass (region, photcode, LOAD_ALLSKY, &Nstars);
     fprintf (stderr, "2MASS load via addstar is deprecated: use load2mass\n");
     exit (2);
@@ -52,5 +45,4 @@
   /* get stars from 2MASS for the given region */
   if (!strcasecmp (Refcat, "2MASS-ALLSKY")) {
-    // stars = get2mass (region, photcode, LOAD_ALLSKY, &Nstars);
     fprintf (stderr, "2MASS load via addstar is deprecated: use load2mass\n");
     exit (2);
@@ -59,13 +51,10 @@
   /* get stars from 2MASS for the given region */
   if (!strcasecmp (Refcat, "2MASS-DR2")) {
-    // stars = get2mass (region, photcode, LOAD_DR2, &Nstars);
     fprintf (stderr, "2MASS load via addstar is deprecated: use load2mass\n");
     exit (2);
   }
   
-  if (VERBOSE && (Nstars == 0)) fprintf (stderr, "no ref objects in region %s\n", region[0].name);
+  if (VERBOSE && (catalog->Naverage == 0)) fprintf (stderr, "no ref objects in region %s\n", region[0].name);
 
-  *nstars = Nstars;
-  return (stars);
-
+  return (catalog);
 }
Index: /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/grefstars.c
===================================================================
--- /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/grefstars.c	(revision 38592)
+++ /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/grefstars.c	(revision 38593)
@@ -2,9 +2,8 @@
 
 /* read ASCII file with ref star data */
-Stars *grefstars (char *file, int photcode, unsigned int *Nstars) {
+Catalog *grefstars (char *file, int photcode) {
 
   FILE *f;
-  int N, NSTARS;
-  Stars *stars;
+  int NSTARS;
   char line[256];
 
@@ -13,34 +12,47 @@
   if (f == NULL) Shutdown ("can't read data from %s", file);
 
-  NSTARS = 100;
-  ALLOCATE (stars, Stars, NSTARS);
+  NSTARS = 1000;
+
+  Catalog *catalog = NULL;
+  ALLOCATE (catalog, Catalog, 1);
+  dvo_catalog_init (catalog, TRUE);
+  ALLOCATE (catalog->average, Average, NSTARS);
+  ALLOCATE (catalog->measure, Measure, NSTARS);
 
   /* read in stars line-by-line */
-  for (N = 0; scan_line (f, line) != EOF; N++) {
+  int N = 0;
+  while (scan_line (f, line) != EOF) {
     stripwhite (line);
     if (line[0] == 0) continue;
     if (line[0] == '#') continue;
 
-    InitStar (&stars[N]);
+    dvo_average_init (&catalog->average[N]);
+    dvo_measure_init (&catalog->measure[N]);
 
     int status = sscanf (line, "%lf %lf %f %f %x", 
-		     &stars[N].average.R,  &stars[N].average.D,  
-		     &stars[N].measure.M, &stars[N].measure.dM, 
-		     &stars[N].measure.photFlags);
+			 &catalog->average[N].R, &catalog->average[N].D,  
+			 &catalog->measure[N].M, &catalog->measure[N].dM, 
+			 &catalog->measure[N].photFlags);
+
     if ((status != 4) && (status != 5)) {
       fprintf (stderr, "error reading line: %s\n", line);
-      N --;
       continue;
     }
-    stars[N].average.R = ohana_normalize_angle (stars[N].average.R);
+    catalog->average[N].R = ohana_normalize_angle (catalog->average[N].R);
 
-    stars[N].measure.R = stars[N].average.R;
-    stars[N].measure.D = stars[N].average.D;
+    catalog->measure[N].R = catalog->average[N].R;
+    catalog->measure[N].D = catalog->average[N].D;
 
-    stars[N].measure.photcode = photcode;
+    catalog->measure[N].photcode = photcode;
 
-    CHECK_REALLOCATE (stars, Stars, NSTARS, N+1, 100);
+    catalog->average[N].Nmeasure = 1;
+    catalog->average[N].measureOffset = N;
+
+    N++;
+    CHECK_REALLOCATE (catalog->average, Average, NSTARS, N, 1000);
+    CHECK_REALLOCATE (catalog->measure, Measure, NSTARS, N, 1000);
   }
-  *Nstars = N;
-  return (stars);
+  catalog->Naverage = N;
+  catalog->Nmeasure = N;
+  return (catalog);
 }
Index: /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/load2mass_as_rawdata.c
===================================================================
--- /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/load2mass_as_rawdata.c	(revision 38592)
+++ /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/load2mass_as_rawdata.c	(revision 38593)
@@ -13,5 +13,5 @@
   
   int i, j, verbose;
-  int Nstars, NSTARS, Ntstars, NTSTARS;
+  int Ntstars, NTSTARS;
   int Nbyte, Nextra, offset;
 
@@ -21,5 +21,4 @@
   char *buffer, *p, *q;
 
-  Stars **stars; // this is an array of pointers to be consistent with input to find_match_refstars
   TMStars *tstars;
   SkyList *skylist;
@@ -117,8 +116,14 @@
       if (DEBUG) fprintf (stderr, "writing to %s\n", skylist[0].filename[0]);
 
-      // collect array of (Stars *) stars in a new output catalog
-      Nstars = 0;
-      NSTARS = 3000;
-      ALLOCATE (stars, Stars *, NSTARS);
+      int Nave = 0;
+      int Nmeas = 0;
+      int NAVE = 1000;
+      int NMEAS = 3000;
+
+      Catalog *newcat = NULL;
+      ALLOCATE (newcat, Catalog, 1);
+      dvo_catalog_init (newcat, TRUE);
+      ALLOCATE (newcat->average, Average, NAVE);
+      ALLOCATE (newcat->measure, Measure, NMEAS);
 
       // loop over stars in this 2mass region that are also in this output region
@@ -140,35 +145,34 @@
 	offset = tstars[j].offset;
 
-	ALLOCATE (stars[Nstars+0], Stars, 1);
-	ALLOCATE (stars[Nstars+1], Stars, 1);
-	ALLOCATE (stars[Nstars+2], Stars, 1);
-
-	InitStar (stars[Nstars+0]);
-	InitStar (stars[Nstars+1]);
-	InitStar (stars[Nstars+2]);
-
-	stars[Nstars+0][0].average.R = tstars[j].R;
-	stars[Nstars+0][0].average.D = tstars[j].D;
-	stars[Nstars+1][0].average.R = tstars[j].R;
-	stars[Nstars+1][0].average.D = tstars[j].D;
-	stars[Nstars+2][0].average.R = tstars[j].R;
-	stars[Nstars+2][0].average.D = tstars[j].D;
-	get2mass_3star_full (&stars[Nstars], &buffer[offset], Nbyte - offset);
+	dvo_average_init (&newcat->average[Nave]);
+	dvo_measure_init (&newcat->measure[Nmeas+0]);
+	dvo_measure_init (&newcat->measure[Nmeas+1]);
+	dvo_measure_init (&newcat->measure[Nmeas+2]);
+
+	newcat->average[Nave].R = tstars[j].R;
+	newcat->average[Nave].D = tstars[j].D;
+	get2mass_3star_full (&newcat->measure[Nmeas], &buffer[offset], Nbyte - offset);
 
 	tstars[j].flag = TRUE;
 
-	Nstars += 3;
-	if (Nstars >= NSTARS - 3) {
-	  NSTARS += 3000;
-	  REALLOCATE (stars, Stars *, NSTARS);
-	}
-      }
-
-      if (!Nstars) {
-	free (stars);
+	newcat->average[Nave].Nmeasure = 3;
+	newcat->average[Nave].measureOffset = Nmeas;
+
+	Nave ++;
+	Nmeas += 3;
+
+	CHECK_REALLOCATE (newcat->average, Average, NAVE,  Nave,  1000);
+	CHECK_REALLOCATE (newcat->measure, Measure, NMEAS, Nmeas, 3000);
+      }
+      newcat->Naverage = Nave;
+      newcat->Nmeasure = Nmeas;
+
+      if (!newcat->Naverage) {
+	dvo_catalog_free (newcat);
+	free (newcat);
 	continue;
       }
 
-      if (DEBUG) fprintf (stderr, "selected %d stars (%10.6f - %10.6f, %10.6f - %10.6f)\n", Nstars, 
+      if (DEBUG) fprintf (stderr, "selected %d stars (%10.6f - %10.6f, %10.6f - %10.6f)\n", (int) newcat->Naverage, 
 			  region[0].Rmin, region[0].Rmax, region[0].Dmin, region[0].Dmax);
 
@@ -193,18 +197,14 @@
 	// assume no input star matches an existing star 
 	// simply add to the existing table
-	// load2mass_catalog (&catalog, stars, Nstars);
-	find_matches_refstars (skylist[0].regions[0], stars, Nstars, &catalog, options);
-	// load2mass_catalog (&catalog, stars, Nstars);
+	find_matches_refstars (skylist[0].regions[0], newcat, &catalog, options);
 
 	dvo_catalog_save (&catalog, VERBOSE);
 	dvo_catalog_unlock (&catalog);
 	dvo_catalog_free (&catalog);
-	// free (catalog.filename);
-	// XXX don't free this! it points to an element of the skytable
       }
 
       SkyListFree (skylist);
-      for (j = 0; j < Nstars; j++) free (stars[j]);
-      free (stars);
+      dvo_catalog_free (newcat);
+      free (newcat);
       VERBOSE = verbose;
     }
Index: /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/loadwise_star_full.c
===================================================================
--- /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/loadwise_star_full.c	(revision 38592)
+++ /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/loadwise_star_full.c	(revision 38593)
@@ -2,16 +2,16 @@
 # include "WISE.h"
 
-int setWISE_ph_qual (Stars *star, char qual);
-int setWISE_var_flag_allsky (Stars *star, char qual);
-int setWISE_ext_flag_allsky (Stars **star, char ptr);
-int setWISE_var_flag_prelim (Stars *star, char qual);
-int setWISE_ext_flag_prelim (Stars **star, char ptr);
-int setWISE_cc_flag (Stars *star, char qual);
-int setWISE_sat_flag (Stars *star, char *ptr);
-int setWISE_blend_flag (Stars **star, char *ptr);
+int setWISE_ph_qual (Measure *measure, char qual);
+int setWISE_var_flag_allsky (Measure *measure, char qual);
+int setWISE_ext_flag_allsky (Measure *measure, char ptr);
+int setWISE_var_flag_prelim (Measure *measure, char qual);
+int setWISE_ext_flag_prelim (Measure *measure, char ptr);
+int setWISE_cc_flag (Measure *measure, char qual);
+int setWISE_sat_flag (Measure *measure, char *ptr);
+int setWISE_blend_flag (Measure *measure, char *ptr);
 
 // fill in the data for a WISE quad star.  takes a pointer to the start of the line the
 // RA and DEC have already been set
-int loadwise_star_allwise (Stars **star, char *line, int Nmax) {
+int loadwise_star_allwise (Measure *measure, char *line, int Nmax) {
 
   int i;
@@ -23,30 +23,30 @@
 
   // I can assign dRA and dDEC to dX and dY if I can consistently set posangle and pltscale
-  star[0][0].measure.posangle = 0.0;
-  star[0][0].measure.pltscale = 1.0;
+  measure[0].posangle = 0.0;
+  measure[0].pltscale = 1.0;
 
   ptr = skipNbounds (ptr, '|', 3, Nmax); // skip: desig, ra, dec,
-  star[0][0].measure.dXccd = ToShortPixels((strtod (ptr, NULL) + 0.005)); // sig_ra -- add 5/1000 to avoid truncation
+  measure[0].dXccd = ToShortPixels((strtod (ptr, NULL) + 0.005)); // sig_ra -- add 5/1000 to avoid truncation
   ptr = nextWISEfield (ptr);
-  star[0][0].measure.dYccd = ToShortPixels((strtod (ptr, NULL) + 0.005)); // sig_dec
+  measure[0].dYccd = ToShortPixels((strtod (ptr, NULL) + 0.005)); // sig_dec
   ptr = nextWISEfield (ptr);
 
   // we only know a single set of values for all 4 bands 
   for (i = 1; i < 4; i++) {
-      star[i][0].measure.dXccd    = star[0][0].measure.dXccd;
-      star[i][0].measure.dYccd    = star[0][0].measure.dYccd;
-      star[i][0].measure.posangle = star[0][0].measure.posangle;
-      star[i][0].measure.pltscale = star[0][0].measure.pltscale;
+      measure[i].dXccd    = measure[0].dXccd;
+      measure[i].dYccd    = measure[0].dYccd;
+      measure[i].posangle = measure[0].posangle;
+      measure[i].pltscale = measure[0].pltscale;
   }
   ptr = skipNbounds (ptr, '|', 5, Nmax); // skip: sig_radec, glon, glat, elon, elat
 
-  star[0][0].measure.Xccd = strtod (ptr, NULL); // wx
+  measure[0].Xccd = strtod (ptr, NULL); // wx
   ptr = nextWISEfield (ptr); // skip wx
-  star[0][0].measure.Yccd = strtod (ptr, NULL); // wy
+  measure[0].Yccd = strtod (ptr, NULL); // wy
   ptr = nextWISEfield (ptr); // skip wy
 
   for (i = 1; i < 4; i++) {
-      star[i][0].measure.Xccd    = star[0][0].measure.Xccd;
-      star[i][0].measure.Yccd    = star[0][0].measure.Yccd;
+      measure[i].Xccd    = measure[0].Xccd;
+      measure[i].Yccd    = measure[0].Yccd;
   }
   ptr = skipNbounds (ptr, '|', 4, Nmax); // skip: cntr, source_id, coadd_id, src
@@ -55,20 +55,20 @@
   for (i = 0; i < 4; i++) {
     char *endpoint;
-      star[i][0].measure.M  = strtod (ptr, &endpoint); // w?mpro
+      measure[i].M  = strtod (ptr, &endpoint); // w?mpro
       if (endpoint == ptr) {
-	star[i][0].measure.M  = NAN;
+	measure[i].M  = NAN;
       }
       ptr = nextWISEfield (ptr);
-      star[i][0].measure.dM = strtod (ptr, &endpoint); // w?sigmpro
+      measure[i].dM = strtod (ptr, &endpoint); // w?sigmpro
       if (endpoint == ptr) {
-	star[i][0].measure.dM  = NAN;
+	measure[i].dM  = NAN;
       }
       ptr = skipNbounds (ptr, '|', 2, Nmax); // skip: w?sigmpro, w?snr
-      star[i][0].measure.psfChisq = strtod (ptr, NULL); // w?rchi2
-      star[i][0].measure.psfQF = strtod (ptr, NULL); // w?rchi2
+      measure[i].psfChisq = strtod (ptr, NULL); // w?rchi2
+      measure[i].psfQF = strtod (ptr, NULL); // w?rchi2
       ptr = nextWISEfield (ptr); // skip : w1rchi2
 
       // init the photFlags field
-      star[i][0].measure.photFlags = 0;
+      measure[i].photFlags = 0;
   }
 
@@ -76,9 +76,9 @@
 
   // set blend flags for all 4 measures
-  setWISE_blend_flag (star, ptr); // nb & na both used here
+  setWISE_blend_flag (measure, ptr); // nb & na both used here
   ptr = skipNbounds (ptr, '|', 2, Nmax); // skip: nb, na
 
   for (i = 0; i < 4; i++) {
-      setWISE_sat_flag (star[i], ptr); // w1sat
+      setWISE_sat_flag (&measure[i], ptr); // w1sat
       ptr = nextWISEfield (ptr); 
   }
@@ -88,5 +88,5 @@
 
   for (i = 0; i < 4; i++) {
-      setWISE_cc_flag (star[i], ptr[i]); // cc_flags
+      setWISE_cc_flag (&measure[i], ptr[i]); // cc_flags
   }
   ptr = nextWISEfield (ptr); // skip cc_flags
@@ -94,14 +94,14 @@
 
   // set ext flags for all 4 measures
-  setWISE_ext_flag_allsky (star, ptr[0]); // ext_flg
+  setWISE_ext_flag_allsky (measure, ptr[0]); // ext_flg
   ptr = nextWISEfield (ptr); // skip ext_flags
 
   for (i = 0; i < 4; i++) {
-      setWISE_var_flag_allsky (star[i], ptr[i]); // var_flg
+      setWISE_var_flag_allsky (&measure[i], ptr[i]); // var_flg
   }
   ptr = nextWISEfield (ptr); // skip var_flags
 
   for (i = 0; i < 4; i++) {
-      setWISE_ph_qual (star[i], ptr[i]); // ph_qual
+      setWISE_ph_qual (&measure[i], ptr[i]); // ph_qual
   }
 
@@ -123,25 +123,25 @@
     // the release is based on data taken in the period 14 January 2010 to 29 April 2010
     if (mjdmean == 0.0) {
-      star[i][0].measure.t = 0;
+      measure[i].t = 0;
     } else {
-      star[i][0].measure.t = ohana_mjd_to_sec (mjdmean);
+      measure[i].t = ohana_mjd_to_sec (mjdmean);
     }
   }
 
-  star[0][0].measure.photcode  = WISE_W1;
-  star[0][0].measure.detID   = 0;
-  star[0][0].measure.imageID = 0;
-
-  star[1][0].measure.photcode  = WISE_W2;
-  star[1][0].measure.detID   = 0;
-  star[1][0].measure.imageID = 0;
-
-  star[2][0].measure.photcode  = WISE_W3;
-  star[2][0].measure.detID   = 0;
-  star[2][0].measure.imageID = 0;
-
-  star[3][0].measure.photcode  = WISE_W4;
-  star[3][0].measure.detID   = 0;
-  star[3][0].measure.imageID = 0;
+  measure[0].photcode  = WISE_W1;
+  measure[0].detID   = 0;
+  measure[0].imageID = 0;
+
+  measure[1].photcode  = WISE_W2;
+  measure[1].detID   = 0;
+  measure[1].imageID = 0;
+
+  measure[2].photcode  = WISE_W3;
+  measure[2].detID   = 0;
+  measure[2].imageID = 0;
+
+  measure[3].photcode  = WISE_W4;
+  measure[3].detID   = 0;
+  measure[3].imageID = 0;
 
   return TRUE;
@@ -156,5 +156,5 @@
 // fill in the data for a WISE quad star.  takes a pointer to the start of the line the
 // RA and DEC have already been set
-int loadwise_star_allsky (Stars **star, char *line, int Nmax) {
+int loadwise_star_allsky (Measure *measure, char *line, int Nmax) {
 
   int i;
@@ -166,30 +166,30 @@
 
   // I can assign dRA and dDEC to dX and dY if I can consistently set posangle and pltscale
-  star[0][0].measure.posangle = 0.0;
-  star[0][0].measure.pltscale = 1.0;
+  measure[0].posangle = 0.0;
+  measure[0].pltscale = 1.0;
 
   ptr = skipNbounds (ptr, '|', 3, Nmax); // skip: desig, ra, dec,
-  star[0][0].measure.dXccd = ToShortPixels(strtod (ptr, NULL)); // sig_ra
+  measure[0].dXccd = ToShortPixels(strtod (ptr, NULL)); // sig_ra
   ptr = nextWISEfield (ptr);
-  star[0][0].measure.dYccd = ToShortPixels(strtod (ptr, NULL)); // sig_dec
+  measure[0].dYccd = ToShortPixels(strtod (ptr, NULL)); // sig_dec
   ptr = nextWISEfield (ptr);
 
   // we only know a single set of values for all 4 bands 
   for (i = 1; i < 4; i++) {
-      star[i][0].measure.dXccd    = star[0][0].measure.dXccd;
-      star[i][0].measure.dYccd    = star[0][0].measure.dYccd;
-      star[i][0].measure.posangle = star[0][0].measure.posangle;
-      star[i][0].measure.pltscale = star[0][0].measure.pltscale;
+      measure[i].dXccd    = measure[0].dXccd;
+      measure[i].dYccd    = measure[0].dYccd;
+      measure[i].posangle = measure[0].posangle;
+      measure[i].pltscale = measure[0].pltscale;
   }
   ptr = skipNbounds (ptr, '|', 5, Nmax); // skip: sig_radec, glon, glat, elon, elat
 
-  star[0][0].measure.Xccd = strtod (ptr, NULL); // wx
+  measure[0].Xccd = strtod (ptr, NULL); // wx
   ptr = nextWISEfield (ptr); // skip wx
-  star[0][0].measure.Yccd = strtod (ptr, NULL); // wy
+  measure[0].Yccd = strtod (ptr, NULL); // wy
   ptr = nextWISEfield (ptr); // skip wy
 
   for (i = 1; i < 4; i++) {
-      star[i][0].measure.Xccd    = star[0][0].measure.Xccd;
-      star[i][0].measure.Yccd    = star[0][0].measure.Yccd;
+      measure[i].Xccd    = measure[0].Xccd;
+      measure[i].Yccd    = measure[0].Yccd;
   }
   ptr = skipNbounds (ptr, '|', 4, Nmax); // skip: cntr, source_id, coadd_id, src
@@ -198,19 +198,19 @@
   for (i = 0; i < 4; i++) {
     char *endpoint;
-      star[i][0].measure.M  = strtod (ptr, &endpoint); // w?mpro
+      measure[i].M  = strtod (ptr, &endpoint); // w?mpro
       if (endpoint == ptr) {
-	star[i][0].measure.M  = NAN;
+	measure[i].M  = NAN;
       }
       ptr = nextWISEfield (ptr);
-      star[i][0].measure.dM = strtod (ptr, &endpoint); // w?sigmpro
+      measure[i].dM = strtod (ptr, &endpoint); // w?sigmpro
       if (endpoint == ptr) {
-	star[i][0].measure.dM  = NAN;
+	measure[i].dM  = NAN;
       }
       ptr = skipNbounds (ptr, '|', 2, Nmax); // skip: w?sigmpro, w?snr
-      star[i][0].measure.psfChisq = strtod (ptr, NULL); // w?rchi2
+      measure[i].psfChisq = strtod (ptr, NULL); // w?rchi2
       ptr = nextWISEfield (ptr); // skip : w1rchi2
 
       // init the photFlags field
-      star[i][0].measure.photFlags = 0;
+      measure[i].photFlags = 0;
   }
 
@@ -218,9 +218,9 @@
 
   // set blend flags for all 4 measures
-  setWISE_blend_flag (star, ptr); // nb & na both used here
+  setWISE_blend_flag (measure, ptr); // nb & na both used here
   ptr = skipNbounds (ptr, '|', 2, Nmax); // skip: nb, na
 
   for (i = 0; i < 4; i++) {
-      setWISE_sat_flag (star[i], ptr); // w1sat
+      setWISE_sat_flag (&measure[i], ptr); // w1sat
       ptr = nextWISEfield (ptr); 
   }
@@ -228,14 +228,14 @@
 
   for (i = 0; i < 4; i++) {
-      setWISE_cc_flag (star[i], ptr[i]); // cc_flg
+      setWISE_cc_flag (&measure[i], ptr[i]); // cc_flg
   }
   ptr = nextWISEfield (ptr); // skip cc_flags
 
   // set ext flags for all 4 measures
-  setWISE_ext_flag_allsky (star, ptr[0]); // ext_flg
+  setWISE_ext_flag_allsky (measure, ptr[0]); // ext_flg
   ptr = nextWISEfield (ptr); // skip ext_flags
 
   for (i = 0; i < 4; i++) {
-      setWISE_var_flag_allsky (star[i], ptr[i]); // var_flg
+      setWISE_var_flag_allsky (&measure[i], ptr[i]); // var_flg
   }
   ptr = nextWISEfield (ptr); // skip var_flags
@@ -261,25 +261,25 @@
     // the release is based on data taken in the period 14 January 2010 to 29 April 2010
     if (mjdmean == 0.0) {
-      star[i][0].measure.t = 0;
+      measure[i].t = 0;
     } else {
-      star[i][0].measure.t = ohana_mjd_to_sec (mjdmean);
+      measure[i].t = ohana_mjd_to_sec (mjdmean);
     }
   }
 
-  star[0][0].measure.photcode  = WISE_W1;
-  star[0][0].measure.detID   = 0;
-  star[0][0].measure.imageID = 0;
-
-  star[1][0].measure.photcode  = WISE_W2;
-  star[1][0].measure.detID   = 0;
-  star[1][0].measure.imageID = 0;
-
-  star[2][0].measure.photcode  = WISE_W3;
-  star[2][0].measure.detID   = 0;
-  star[2][0].measure.imageID = 0;
-
-  star[3][0].measure.photcode  = WISE_W4;
-  star[3][0].measure.detID   = 0;
-  star[3][0].measure.imageID = 0;
+  measure[0].photcode  = WISE_W1;
+  measure[0].detID   = 0;
+  measure[0].imageID = 0;
+
+  measure[1].photcode  = WISE_W2;
+  measure[1].detID   = 0;
+  measure[1].imageID = 0;
+
+  measure[2].photcode  = WISE_W3;
+  measure[2].detID   = 0;
+  measure[2].imageID = 0;
+
+  measure[3].photcode  = WISE_W4;
+  measure[3].detID   = 0;
+  measure[3].imageID = 0;
 
   return TRUE;
@@ -288,5 +288,5 @@
 // fill in the data for a WISE quad star.  takes a pointer to the start of the line the
 // RA and DEC have already been set
-int loadwise_star_prelim (Stars **star, char *line, int Nmax) {
+int loadwise_star_prelim (Measure *measure, char *line, int Nmax) {
 
   int i;
@@ -298,30 +298,30 @@
 
   // I can assign dRA and dDEC to dX and dY if I can consistently set posangle and pltscale
-  star[0][0].measure.posangle = 0.0;
-  star[0][0].measure.pltscale = 1.0;
+  measure[0].posangle = 0.0;
+  measure[0].pltscale = 1.0;
 
   ptr = skipNbounds (ptr, '|', 3, Nmax); // skip: desig, ra, dec,
-  star[0][0].measure.dXccd = ToShortPixels(strtod (ptr, NULL)); // sig_ra
+  measure[0].dXccd = ToShortPixels(strtod (ptr, NULL)); // sig_ra
   ptr = nextWISEfield (ptr);
-  star[0][0].measure.dYccd = ToShortPixels(strtod (ptr, NULL)); // sig_dec
+  measure[0].dYccd = ToShortPixels(strtod (ptr, NULL)); // sig_dec
   ptr = nextWISEfield (ptr);
 
   // we only know a single set of values for all 4 bands 
   for (i = 1; i < 4; i++) {
-      star[i][0].measure.dXccd    = star[0][0].measure.dXccd;
-      star[i][0].measure.dYccd    = star[0][0].measure.dYccd;
-      star[i][0].measure.posangle = star[0][0].measure.posangle;
-      star[i][0].measure.pltscale = star[0][0].measure.pltscale;
+      measure[i].dXccd    = measure[0].dXccd;
+      measure[i].dYccd    = measure[0].dYccd;
+      measure[i].posangle = measure[0].posangle;
+      measure[i].pltscale = measure[0].pltscale;
   }
   ptr = skipNbounds (ptr, '|', 5, Nmax); // skip: sig_radec, glon, glat, elon, elat
 
-  star[0][0].measure.Xccd = strtod (ptr, NULL); // wx
+  measure[0].Xccd = strtod (ptr, NULL); // wx
   ptr = nextWISEfield (ptr); // skip wx
-  star[0][0].measure.Yccd = strtod (ptr, NULL); // wy
+  measure[0].Yccd = strtod (ptr, NULL); // wy
   ptr = nextWISEfield (ptr); // skip wy
 
   for (i = 1; i < 4; i++) {
-      star[i][0].measure.Xccd    = star[0][0].measure.Xccd;
-      star[i][0].measure.Yccd    = star[0][0].measure.Yccd;
+      measure[i].Xccd    = measure[0].Xccd;
+      measure[i].Yccd    = measure[0].Yccd;
   }
   ptr = skipNbounds (ptr, '|', 4, Nmax); // skip: cntr, source_id, coadd_id, src
@@ -329,13 +329,13 @@
   // W1
   for (i = 0; i < 4; i++) {
-      star[i][0].measure.M  = strtod (ptr, NULL); // w?mpro
+      measure[i].M  = strtod (ptr, NULL); // w?mpro
       ptr = nextWISEfield (ptr);
-      star[i][0].measure.dM = strtod (ptr, NULL); // w?sigmpro
+      measure[i].dM = strtod (ptr, NULL); // w?sigmpro
       ptr = skipNbounds (ptr, '|', 2, Nmax); // skip: w?sigmpro, w?snr
-      star[i][0].measure.psfChisq = strtod (ptr, NULL); // w?rchi2
+      measure[i].psfChisq = strtod (ptr, NULL); // w?rchi2
       ptr = nextWISEfield (ptr); // skip : w1rchi2
 
       // init the photFlags field
-      star[i][0].measure.photFlags = 0;
+      measure[i].photFlags = 0;
   }
 
@@ -372,24 +372,24 @@
   double jd = 2455263.0; // NOTE : WISE prelim release does not contain per-detection time info. 
   // the release is based on data taken in the period 14 January 2010 to 29 April 2010
-  star[0][0].measure.t = ohana_jd_to_sec (jd);
-  star[1][0].measure.t = star[0][0].measure.t;
-  star[2][0].measure.t = star[0][0].measure.t;
-  star[3][0].measure.t = star[0][0].measure.t;
-
-  star[0][0].measure.photcode  = WISE_W1;
-  star[0][0].measure.detID   = 0;
-  star[0][0].measure.imageID = 0;
-
-  star[1][0].measure.photcode  = WISE_W2;
-  star[1][0].measure.detID   = 0;
-  star[1][0].measure.imageID = 0;
-
-  star[2][0].measure.photcode  = WISE_W3;
-  star[2][0].measure.detID   = 0;
-  star[2][0].measure.imageID = 0;
-
-  star[3][0].measure.photcode  = WISE_W4;
-  star[3][0].measure.detID   = 0;
-  star[3][0].measure.imageID = 0;
+  measure[0].t = ohana_jd_to_sec (jd);
+  measure[1].t = measure[0].t;
+  measure[2].t = measure[0].t;
+  measure[3].t = measure[0].t;
+
+  measure[0].photcode  = WISE_W1;
+  measure[0].detID   = 0;
+  measure[0].imageID = 0;
+
+  measure[1].photcode  = WISE_W2;
+  measure[1].detID   = 0;
+  measure[1].imageID = 0;
+
+  measure[2].photcode  = WISE_W3;
+  measure[2].detID   = 0;
+  measure[2].imageID = 0;
+
+  measure[3].photcode  = WISE_W4;
+  measure[3].detID   = 0;
+  measure[3].imageID = 0;
 
   return TRUE;
@@ -436,5 +436,5 @@
 # define FLAG_VARIABLE_LEVEL3 0x40000000 // var_flg == 8 or 9
 
-int setWISE_blend_flag (Stars **star, char *ptr) {
+int setWISE_blend_flag (Measure *measure, char *ptr) {
 
     int nb = atoi (ptr);
@@ -445,38 +445,38 @@
 
     if (na == 0) {
-	star[0][0].measure.photFlags |= FLAG_BLEND_ACTIVE;
-	star[1][0].measure.photFlags |= FLAG_BLEND_ACTIVE;
-	star[2][0].measure.photFlags |= FLAG_BLEND_ACTIVE;
-	star[3][0].measure.photFlags |= FLAG_BLEND_ACTIVE;
+	measure[0].photFlags |= FLAG_BLEND_ACTIVE;
+	measure[1].photFlags |= FLAG_BLEND_ACTIVE;
+	measure[2].photFlags |= FLAG_BLEND_ACTIVE;
+	measure[3].photFlags |= FLAG_BLEND_ACTIVE;
     } else {
-	star[0][0].measure.photFlags |= FLAG_BLEND_PASSIVE;
-	star[1][0].measure.photFlags |= FLAG_BLEND_PASSIVE;
-	star[2][0].measure.photFlags |= FLAG_BLEND_PASSIVE;
-	star[3][0].measure.photFlags |= FLAG_BLEND_PASSIVE;
+	measure[0].photFlags |= FLAG_BLEND_PASSIVE;
+	measure[1].photFlags |= FLAG_BLEND_PASSIVE;
+	measure[2].photFlags |= FLAG_BLEND_PASSIVE;
+	measure[3].photFlags |= FLAG_BLEND_PASSIVE;
     }
     return TRUE;
 }
 
-int setWISE_sat_flag (Stars *star, char *ptr) {
+int setWISE_sat_flag (Measure *measure, char *ptr) {
 
     float sat = strtod (ptr, NULL);
     if (sat > 0.0) {
-	star[0].measure.photFlags |= FLAG_SATURATED_PIX;
+	measure[0].photFlags |= FLAG_SATURATED_PIX;
     }
     return TRUE;
 }
 
-int setWISE_cc_flag (Stars *star, char qual) {
+int setWISE_cc_flag (Measure *measure, char qual) {
 
   switch (qual) {
-    case 'p': star[0].measure.photFlags |= FLAG_CC_PERSIST; break;
-    case 'h': star[0].measure.photFlags |= FLAG_CC_HALO;    break;
-    case 'd': star[0].measure.photFlags |= FLAG_CC_SPIKE;   break;
-    case 'o': star[0].measure.photFlags |= FLAG_CC_GHOST;   break;
-
-    case 'P': star[0].measure.photFlags |= FLAG_CC_PERSIST | FLAG_CC_SPURIOUS; break;
-    case 'H': star[0].measure.photFlags |= FLAG_CC_HALO    | FLAG_CC_SPURIOUS; break;
-    case 'D': star[0].measure.photFlags |= FLAG_CC_SPIKE   | FLAG_CC_SPURIOUS; break;
-    case 'O': star[0].measure.photFlags |= FLAG_CC_GHOST   | FLAG_CC_SPURIOUS; break;
+    case 'p': measure[0].photFlags |= FLAG_CC_PERSIST; break;
+    case 'h': measure[0].photFlags |= FLAG_CC_HALO;    break;
+    case 'd': measure[0].photFlags |= FLAG_CC_SPIKE;   break;
+    case 'o': measure[0].photFlags |= FLAG_CC_GHOST;   break;
+
+    case 'P': measure[0].photFlags |= FLAG_CC_PERSIST | FLAG_CC_SPURIOUS; break;
+    case 'H': measure[0].photFlags |= FLAG_CC_HALO    | FLAG_CC_SPURIOUS; break;
+    case 'D': measure[0].photFlags |= FLAG_CC_SPIKE   | FLAG_CC_SPURIOUS; break;
+    case 'O': measure[0].photFlags |= FLAG_CC_GHOST   | FLAG_CC_SPURIOUS; break;
 
     case '0': break;
@@ -487,5 +487,5 @@
 }
 
-int setWISE_ext_flag_allsky (Stars **star, char value) {
+int setWISE_ext_flag_allsky (Measure *measure, char value) {
 
   switch (value) {
@@ -493,32 +493,32 @@
       return TRUE;
     case '1':
-      star[0][0].measure.photFlags |= FLAG_EXTENDED;
-      star[1][0].measure.photFlags |= FLAG_EXTENDED;
-      star[2][0].measure.photFlags |= FLAG_EXTENDED;
-      star[3][0].measure.photFlags |= FLAG_EXTENDED;
+      measure[0].photFlags |= FLAG_EXTENDED;
+      measure[1].photFlags |= FLAG_EXTENDED;
+      measure[2].photFlags |= FLAG_EXTENDED;
+      measure[3].photFlags |= FLAG_EXTENDED;
       return TRUE;
     case '2':
-      star[0][0].measure.photFlags |= FLAG_EXT_IN_XSC;
-      star[1][0].measure.photFlags |= FLAG_EXT_IN_XSC;
-      star[2][0].measure.photFlags |= FLAG_EXT_IN_XSC;
-      star[3][0].measure.photFlags |= FLAG_EXT_IN_XSC;
+      measure[0].photFlags |= FLAG_EXT_IN_XSC;
+      measure[1].photFlags |= FLAG_EXT_IN_XSC;
+      measure[2].photFlags |= FLAG_EXT_IN_XSC;
+      measure[3].photFlags |= FLAG_EXT_IN_XSC;
       return TRUE;
     case '3':
-      star[0][0].measure.photFlags |= FLAG_EXTENDED | FLAG_EXT_IN_XSC;
-      star[1][0].measure.photFlags |= FLAG_EXTENDED | FLAG_EXT_IN_XSC;
-      star[2][0].measure.photFlags |= FLAG_EXTENDED | FLAG_EXT_IN_XSC;
-      star[3][0].measure.photFlags |= FLAG_EXTENDED | FLAG_EXT_IN_XSC;
+      measure[0].photFlags |= FLAG_EXTENDED | FLAG_EXT_IN_XSC;
+      measure[1].photFlags |= FLAG_EXTENDED | FLAG_EXT_IN_XSC;
+      measure[2].photFlags |= FLAG_EXTENDED | FLAG_EXT_IN_XSC;
+      measure[3].photFlags |= FLAG_EXTENDED | FLAG_EXT_IN_XSC;
       return TRUE;
     case '4':
-      star[0][0].measure.photFlags |= FLAG_EXT_BY_XSC;
-      star[1][0].measure.photFlags |= FLAG_EXT_BY_XSC;
-      star[2][0].measure.photFlags |= FLAG_EXT_BY_XSC;
-      star[3][0].measure.photFlags |= FLAG_EXT_BY_XSC;
+      measure[0].photFlags |= FLAG_EXT_BY_XSC;
+      measure[1].photFlags |= FLAG_EXT_BY_XSC;
+      measure[2].photFlags |= FLAG_EXT_BY_XSC;
+      measure[3].photFlags |= FLAG_EXT_BY_XSC;
       return TRUE;
     case '5':
-      star[0][0].measure.photFlags |= FLAG_EXTENDED | FLAG_EXT_BY_XSC;
-      star[1][0].measure.photFlags |= FLAG_EXTENDED | FLAG_EXT_BY_XSC;
-      star[2][0].measure.photFlags |= FLAG_EXTENDED | FLAG_EXT_BY_XSC;
-      star[3][0].measure.photFlags |= FLAG_EXTENDED | FLAG_EXT_BY_XSC;
+      measure[0].photFlags |= FLAG_EXTENDED | FLAG_EXT_BY_XSC;
+      measure[1].photFlags |= FLAG_EXTENDED | FLAG_EXT_BY_XSC;
+      measure[2].photFlags |= FLAG_EXTENDED | FLAG_EXT_BY_XSC;
+      measure[3].photFlags |= FLAG_EXTENDED | FLAG_EXT_BY_XSC;
       return TRUE;
     default: 
@@ -529,5 +529,5 @@
 }
 
-int setWISE_ext_flag_prelim (Stars **star, char value) {
+int setWISE_ext_flag_prelim (Measure *measure, char value) {
 
   switch (value) {
@@ -535,8 +535,8 @@
       return TRUE;
     case '1':
-      star[0][0].measure.photFlags |= FLAG_EXTENDED;
-      star[1][0].measure.photFlags |= FLAG_EXTENDED;
-      star[2][0].measure.photFlags |= FLAG_EXTENDED;
-      star[3][0].measure.photFlags |= FLAG_EXTENDED;
+      measure[0].photFlags |= FLAG_EXTENDED;
+      measure[1].photFlags |= FLAG_EXTENDED;
+      measure[2].photFlags |= FLAG_EXTENDED;
+      measure[3].photFlags |= FLAG_EXTENDED;
       return TRUE;
     default: 
@@ -548,5 +548,5 @@
 
 // NOTE: var flag definition changed slightly between prelim & allsky
-int setWISE_var_flag_allsky (Stars *star, char qual) {
+int setWISE_var_flag_allsky (Measure *measure, char qual) {
 
   switch (qual) {
@@ -559,13 +559,13 @@
     case '4':
     case '5':
-	star[0].measure.photFlags |= FLAG_VARIABLE_LEVEL1;
+	measure[0].photFlags |= FLAG_VARIABLE_LEVEL1;
 	return TRUE;
     case '6':
     case '7':
-	star[0].measure.photFlags |= FLAG_VARIABLE_LEVEL2;
+	measure[0].photFlags |= FLAG_VARIABLE_LEVEL2;
 	return TRUE;
     case '8':
     case '9':
-      star[0].measure.photFlags |= FLAG_VARIABLE_LEVEL3;
+      measure[0].photFlags |= FLAG_VARIABLE_LEVEL3;
       return TRUE;
     default: 
@@ -575,5 +575,5 @@
 }
 
-int setWISE_var_flag_prelim (Stars *star, char qual) {
+int setWISE_var_flag_prelim (Measure *measure, char qual) {
 
   switch (qual) {
@@ -584,14 +584,14 @@
     case '3':
     case '4':
-	star[0].measure.photFlags |= FLAG_VARIABLE_LEVEL1;
+	measure[0].photFlags |= FLAG_VARIABLE_LEVEL1;
 	return TRUE;
     case '5':
     case '6':
     case '7':
-	star[0].measure.photFlags |= FLAG_VARIABLE_LEVEL2;
+	measure[0].photFlags |= FLAG_VARIABLE_LEVEL2;
 	return TRUE;
     case '8':
     case '9':
-      star[0].measure.photFlags |= FLAG_VARIABLE_LEVEL3;
+      measure[0].photFlags |= FLAG_VARIABLE_LEVEL3;
       return TRUE;
     default: 
@@ -601,13 +601,13 @@
 }
 
-int setWISE_ph_qual (Stars *star, char qual) {
+int setWISE_ph_qual (Measure *measure, char qual) {
 
   switch (qual) {
-    case 'A': star[0].measure.photFlags |= FLAG_PH_A; break;
-    case 'B': star[0].measure.photFlags |= FLAG_PH_B; break;
-    case 'C': star[0].measure.photFlags |= FLAG_PH_C; break;
-    case 'U': star[0].measure.photFlags |= FLAG_PH_U; break;
-    case 'X': star[0].measure.photFlags |= FLAG_PH_X; break;
-    case 'Z': star[0].measure.photFlags |= FLAG_PH_Z; break;
+    case 'A': measure[0].photFlags |= FLAG_PH_A; break;
+    case 'B': measure[0].photFlags |= FLAG_PH_B; break;
+    case 'C': measure[0].photFlags |= FLAG_PH_C; break;
+    case 'U': measure[0].photFlags |= FLAG_PH_U; break;
+    case 'X': measure[0].photFlags |= FLAG_PH_X; break;
+    case 'Z': measure[0].photFlags |= FLAG_PH_Z; break;
     default: 
       fprintf (stderr, "error in ph_flag: %c\n", qual);
Index: /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/replace_match.c
===================================================================
--- /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/replace_match.c	(revision 38592)
+++ /branches/eam_branches/ipp-20150625/Ohana/src/addstar/src/replace_match.c	(revision 38593)
@@ -1,5 +1,5 @@
 # include "addstar.h"
 
-int replace_match (Average *average, Measure *measure, Stars *star) {
+int replace_match (Average *average, Measure *measure, Measure *newmeas, off_t *found) {
 
   int i, j, m;
@@ -11,10 +11,10 @@
   for (i = 0; i < average[0].Nmeasure; i++) {
     j = i + m;
-    if (measure[j].photcode != star[0].measure.photcode) continue;
-    measure[j].R = star[0].average.R;
-    measure[j].D = star[0].average.D;
-    measure[j].M  = star[0].measure.M;
-    measure[j].dM = star[0].measure.dM;
-    star[0].found = average[0].measureOffset + i;
+    if (measure[j].photcode != newmeas->photcode) continue;
+    measure[j].R  = newmeas->R;
+    measure[j].D  = newmeas->D;
+    measure[j].M  = newmeas->M;
+    measure[j].dM = newmeas->dM;
+    *found = average[0].measureOffset + i;
     return (TRUE);
   }
