Index: /trunk/Ohana/src/addstar/Makefile
===================================================================
--- /trunk/Ohana/src/addstar/Makefile	(revision 3375)
+++ /trunk/Ohana/src/addstar/Makefile	(revision 3376)
@@ -17,5 +17,5 @@
 #  
 INCS	= 	-I$(INC) -I$(LINC) -I$(XINC)
-LIBS	= 	-L$(LLIB) -lFITS -lohana -lm 
+LIBS	= 	-L$(LLIB) -lFITS -lohana -lz -lm
 CFLAGS	=	$(INCS)
 LFLAGS	=	$(LIBS) 
@@ -24,5 +24,4 @@
 $(SRC)/addstar.$(ARCH).o \
 $(SRC)/airmass.$(ARCH).o \
-$(SRC)/aregion.$(ARCH).o \
 $(SRC)/args.$(ARCH).o \
 $(SRC)/calibrate.$(ARCH).o \
@@ -80,4 +79,9 @@
 INSTALL = addstar
 
+gztest                : $(BIN)/gztest.$(ARCH)
+$(BIN)/gztest.$(ARCH) : $(SRC)/gztest.$(ARCH).o
+
+INSTALL = addstar
+
 # dependancy rules for binary code #########################
 .PRECIOUS: %.$(ARCH).o
Index: /trunk/Ohana/src/addstar/include/addstar.h
===================================================================
--- /trunk/Ohana/src/addstar/include/addstar.h	(revision 3375)
+++ /trunk/Ohana/src/addstar/include/addstar.h	(revision 3376)
@@ -4,4 +4,5 @@
 # include <sys/time.h>
 # include <time.h>
+# include <zlib.h>
 
 /* used in find_matches, find_matches_refstars */
@@ -12,5 +13,5 @@
 /* grab named photcode */
 # define NAMED_PHOTCODE(CODE,NAME) \
-  CODE = GetPhotcodebyName (NAME); \
+  CODE = GetPhotcodeCodebyName (NAME); \
   if (!CODE) { \
     fprintf (stderr, "ERROR:  photcode %s not found in photcode table\n", NAME); \
@@ -47,4 +48,7 @@
 char   GSCFILE[256];
 char   CATDIR[256];
+char   TWO_MASS_DIR[256];
+char   GSCDIR[256];
+char   CDROM[256];
 double DEFAULT_RADIUS, NSIGMA, SNLIMIT;
 double ZeroPt;
@@ -57,5 +61,5 @@
 
 PhotCode *thiscode;
-GSCRegion patch;
+GSCRegion UserPatch;
 
 char DateKeyword[64];
@@ -86,5 +90,5 @@
 
 int main (int argc, char **argv);
-int Shutdown ();  
+int Shutdown (char *message, ...);  
 void TrapSignal (int sig);
 int SetSignals ();
@@ -122,4 +126,6 @@
 void fsort (float *X, int N);
 void fsort2 (float *X, float *Y, int N);
+void sort_stars (Stars *stars, int N);
+void sort_regions (GSCRegion *region, int N);
 
 char *sec_to_date (time_t second);
@@ -147,5 +153,5 @@
 Stars *get2mass (GSCRegion *patch, int *NSTARS);
 TM_Region *get2mass_acc (GSCRegion *patch, int *nfiles);
-Stars *get2mass_data (char *filename, GSCRegion *patch, int *nstars);
+Stars *get2mass_data (TM_Region *region, GSCRegion *patch, int *nstars);
 GSCRegion *gregion_stars (Stars *stars, int Nstars, int *Nregion);
 Stars *grefstars (char *file, int *Nstars);
@@ -180,5 +186,4 @@
 int replace_match (Average *average, Measure *measure, Stars *star);
 FILE *GetDB (int *state);
-int Shutdown ();
 void lock_image_db ();
 void unlock_image_db (Image *image);
Index: /trunk/Ohana/src/addstar/src/ConfigInit.c
===================================================================
--- /trunk/Ohana/src/addstar/src/ConfigInit.c	(revision 3375)
+++ /trunk/Ohana/src/addstar/src/ConfigInit.c	(revision 3376)
@@ -26,29 +26,33 @@
   XMIN = XMAX = YMIN = YMAX = 0;
   ScanConfig (config, "NSIGMA",                 "%lf", 0, &NSIGMA);
-  ScanConfig (config, "XOVERSCAN",              "%d", 0, &XOVERSCAN);
-  ScanConfig (config, "YOVERSCAN",              "%d", 0, &YOVERSCAN);
-  ScanConfig (config, "ADDSTAR_XMIN",           "%d", 0, &XMIN);
-  ScanConfig (config, "ADDSTAR_XMAX",           "%d", 0, &XMAX);
-  ScanConfig (config, "ADDSTAR_YMIN",           "%d", 0, &YMIN);
-  ScanConfig (config, "ADDSTAR_YMAX",           "%d", 0, &YMAX);
+  ScanConfig (config, "XOVERSCAN",              "%d",  0, &XOVERSCAN);
+  ScanConfig (config, "YOVERSCAN",              "%d",  0, &YOVERSCAN);
+  ScanConfig (config, "ADDSTAR_XMIN",           "%d",  0, &XMIN);
+  ScanConfig (config, "ADDSTAR_XMAX",           "%d",  0, &XMAX);
+  ScanConfig (config, "ADDSTAR_YMIN",           "%d",  0, &YMIN);
+  ScanConfig (config, "ADDSTAR_YMAX",           "%d",  0, &YMAX);
 
-  ScanConfig (config, "IMAGE_CATALOG",          "%s", 0, ImageCat);
-  ScanConfig (config, "IMAGE_CATALOG_TEMPLATE", "%s", 0, ImageTemplate);
-  ScanConfig (config, "CATALOG_TEMPLATE",       "%s", 0, CatTemplate);
-  ScanConfig (config, "GSCFILE",                "%s", 0, GSCFILE);
-  ScanConfig (config, "CATDIR",                 "%s", 0, CATDIR);
+  ScanConfig (config, "2MASS_DIR",              "%s",  0, TWO_MASS_DIR);
+  ScanConfig (config, "GSCDIR",                 "%s",  0, GSCDIR);
+  ScanConfig (config, "USNO_CDROM",             "%s",  0, CDROM);
+
+  ScanConfig (config, "IMAGE_CATALOG",          "%s",  0, ImageCat);
+  ScanConfig (config, "IMAGE_CATALOG_TEMPLATE", "%s",  0, ImageTemplate);
+  ScanConfig (config, "CATALOG_TEMPLATE",       "%s",  0, CatTemplate);
+  ScanConfig (config, "GSCFILE",                "%s",  0, GSCFILE);
+  ScanConfig (config, "CATDIR",                 "%s",  0, CATDIR);
   ScanConfig (config, "MIN_SN_FSTAT",           "%lf", 0, &SNLIMIT);
-  ScanConfig (config, "PHOTCODE_FILE",          "%s", 0, PhotCodeFile);
+  ScanConfig (config, "PHOTCODE_FILE",          "%s",  0, PhotCodeFile);
 
   /* used by parse_time to find time-related keywords */
-  ScanConfig (config, "DATE-KEYWORD",           "%s", 0, DateKeyword);
-  ScanConfig (config, "DATE-MODE",              "%s", 0, DateMode);
-  ScanConfig (config, "UT-KEYWORD",             "%s", 0, UTKeyword);
-  ScanConfig (config, "MJD-KEYWORD",            "%s", 0, MJDKeyword);
-  ScanConfig (config, "JD-KEYWORD",             "%s", 0, JDKeyword);
+  ScanConfig (config, "DATE-KEYWORD",           "%s",  0, DateKeyword);
+  ScanConfig (config, "DATE-MODE",              "%s",  0, DateMode);
+  ScanConfig (config, "UT-KEYWORD",             "%s",  0, UTKeyword);
+  ScanConfig (config, "MJD-KEYWORD",            "%s",  0, MJDKeyword);
+  ScanConfig (config, "JD-KEYWORD",             "%s",  0, JDKeyword);
 
-  ScanConfig (config, "EXPTIME-KEYWORD",        "%s", 0, ExptimeKeyword);
-  ScanConfig (config, "AIRMASS-KEYWORD",        "%s", 0, AirmassKeyword);
-  ScanConfig (config, "CCDNUM-KEYWORD",         "%s", 0, CCDNumKeyword);
+  ScanConfig (config, "EXPTIME-KEYWORD",        "%s",  0, ExptimeKeyword);
+  ScanConfig (config, "AIRMASS-KEYWORD",        "%s",  0, AirmassKeyword);
+  ScanConfig (config, "CCDNUM-KEYWORD",         "%s",  0, CCDNumKeyword);
 
   ScanConfig (config, "ST-KEYWORD",             "%s",  0, STKeyword);
@@ -57,5 +61,5 @@
 
   if (!LoadPhotcodes (PhotCodeFile)) {
-    fprintf (stderr, "error loading photcodes\n");
+    fprintf (stderr, "error loading photcode file %s\n", PhotCodeFile);
     exit (1);
   }
@@ -65,2 +69,14 @@
 
 }
+
+void GetConfig (char *config, char *field, char *format, int N, void *ptr) {
+
+  char *status;
+
+  status = ScanConfig (config, field, format, N, ptr);
+  if (status == NULL) {
+    fprintf (stderr, "error in config, cannot find %s\n", field);
+    exit (1);
+  }
+  return;
+}
Index: /trunk/Ohana/src/addstar/src/RegionOps.c
===================================================================
--- /trunk/Ohana/src/addstar/src/RegionOps.c	(revision 3375)
+++ /trunk/Ohana/src/addstar/src/RegionOps.c	(revision 3376)
@@ -1,32 +1,33 @@
 # include "addstar.h"
-# define NBANDS
+
+# define NBANDS 24
+
 double DecBands[] = {
--90.0, -82.5, -75.0, -67.5, -60.0, 
--52.5, -45.0, -37.5, -30.0, -22.5, 
--15.0, -07.5, +00.0, +07.5, +15.0, 
-+22.5, +30.0, +37.5, +45.0, +52.5, 
-+60.0, +67.5, +75.0, +82.5, +90.0
+  -90.0, -82.5, -75.0, -67.5, -60.0, 
+  -52.5, -45.0, -37.5, -30.0, -22.5, 
+  -15.0, -07.5, +00.0, +07.5, +15.0, 
+  +22.5, +30.0, +37.5, +45.0, +52.5, 
+  +60.0, +67.5, +75.0, +82.5, +90.0
 };
 
 char *DecNames[] = {
-"S8230", "S7500", "S6730", "S6000", "S5230"
-"S4500", "S3730", "S3000", "S2230", "S1500", 
-"S0730", "S0000", "N0000", "N0730", "N1500", 
-"N2230", "N3000", "N3730", "N4500", "N5230", 
-"N6000", "N6730", "N7500", "N8230", 
+  "s8230", "s7500", "s6730", "s6000", "s5230",
+  "s4500", "s3730", "s3000", "s2230", "s1500", 
+  "s0730", "s0000", "n0000", "n0730", "n1500", 
+  "n2230", "n3000", "n3730", "n4500", "n5230", 
+  "n6000", "n6730", "n7500", "n8230", 
 };
 
 GSCRegion *LoadRegions (int *nregions) {
   
+  int Nregions, i, N, NDec, Nx, Ny;
+  char buffer[28800], temp[50], file[256];
+  double RA0, RA1, DEC0, DEC1, D0, D1;
+  FILE *f;
+  GSCRegion *regions;
   Header header;
   Header theader;
   Matrix matrix;
   FTable table;
- 
-  char buffer[28800], temp[50], file[256];
-  double RA0, RA1, DEC0, DEC1;
-  int i, N, NDec, Nx, Ny;
-
-  FILE *f;
   
   f = fopen (GSCFILE, "r");
@@ -37,7 +38,8 @@
 
   /* init & load in table data */
-  if (!fits_fread_header (f, &header))           escape (UNLOCK, "ERROR: can't read primary header"); 
-  if (!fits_fread_matrix (f, &matrix, &header))  escape (UNLOCK, "ERROR: can't read primary matrix");
-  if (!fits_fread_ftable (f, &table, "REGIONS")) escape (UNLOCK, "ERROR: can't read table");
+  table.header = &theader;
+  if (!fits_fread_header (f, &header))           Shutdown ("can't read primary header for GSC Region table"); 
+  if (!fits_fread_matrix (f, &matrix, &header))  Shutdown ("can't read primary matrix for GSC Region table");
+  if (!fits_fread_ftable (f, &table, "REGIONS")) Shutdown ("can't read GSC Region table");
 
   fits_scan (table.header, "NAXIS1", "%d", 1, &Nx);
@@ -45,15 +47,16 @@
 
   Nregions = 0;
-  ALLOCATE (regions, GSCRegion, Ny);
+  ALLOCATE (regions, GSCRegion, Ny + 2);  /* allow room for N & S poles */
 
   /* pole region is artificial - not in table */
   sprintf (file, "%s/n8230/pole.cpt", CATDIR);
-  region[Nregions].DEC[0] = 86.25;
-  region[Nregions].DEC[1] = 93.75;
-  region[Nregions].RA[0] =  0.0;
-  region[Nregions].RA[1] =  360.0;
-  strcpy (region[Nregions].filename, file);
+  regions[Nregions].DEC[0] = 86.25;
+  regions[Nregions].DEC[1] = 93.75;
+  regions[Nregions].RA[0] =  0.0;
+  regions[Nregions].RA[1] =  360.0;
+  strcpy (regions[Nregions].filename, file);
   Nregions ++;
 
+  /* fill out GSCRegion structure */
   for (i = 0; i < Ny; i++) {
     strncpy (temp, &table.buffer[i*48], 48);
@@ -76,18 +79,9 @@
 
     /** convert DEC0, DEC1 to NBigDec **/
-    NDec = -1;
-    for (N = 0; N < NBANDS; N++) {
-      if (DEC0 >= DecBand[N]) {
-	NDec = N;
-	break;
-      }
-    }
-    if (NDec < 0) {
-      fprintf (stderr, "programming / table error\n");
-      exit (0);
-    }
+    NDec = FindDecBand (0.5*(DEC0 + DEC1), &D0, &D1);
+    if (NDec == -1) Shutdown ("programming / table error");
 
     temp[5] = 0;
-    sprintf (file, "%s/%s/%s.cpt", CATDIR, Dec2Sections[NBigDec], &temp[1]);
+    sprintf (file, "%s/%s/%s.cpt", CATDIR, DecNames[NDec], &temp[1]);
 
     strcpy (regions[Nregions].filename, file);
@@ -100,7 +94,89 @@
 }
 
-int FindRegionByPoint (GSCRegion *regions, double ra, double dec, GSCRegion *gsc, int Ngsc) {
+/* given dec value, find upper and lower bounds of enclosing dec band */
+int FindDecBand (double dec, double *DEC0, double *DEC1) {
+
+  int i;
+
+  for (i = 0; i < NBANDS; i++) {
+    if (DecBands[i + 0] >  dec) continue;
+    if (DecBands[i + 1] <= dec) continue;
+    *DEC0 = DecBands[i+0];
+    *DEC1 = DecBands[i+1];
+    return (i);
+  }
+  return (-1);
+}
+
+/* note that region.DEC[0] is sorted, but not necessarily DEC[1] */
+int FindRegionDecBandStart (GSCRegion *region, int Nregion, double dec) {
+
+  int N, Nlo, Nhi;
+  double D0, D1;
+
+  /* D0, D1 are upper lower band boundaries */
+  /* all regions in this band have DEC[0] >= D0 */
+  N = FindDecBand (dec, &D0, &D1);
+  if (N == -1) Shutdown ("programming / table error");
+
+  /* bracket value of interest */
+  Nlo = 0; Nhi = Nregion;
+  while (Nhi - Nlo > 10) {
+    N = 0.5*(Nlo + Nhi);
+    if (region[N].DEC[0] < D0) {
+      Nlo = N;
+    } else {
+      Nhi = N;
+    }
+  }
+  /* Nlo - Nhi bracket the transition across dec */
+  /* v[Nlo] < v <= v[Nhi] */ 
+
+  /* find the last entry < dec */
+  for (N = Nhi; N >= Nlo; N--) {
+    if (region[N].DEC[0] < D0) return (N);
+  }
+  return (-1);
+  /* this will fail if transition value is not in the data range */
+}
+
+/* note that region.DEC[0] is sorted, but not necessarily DEC[1] */
+int FindRegionDecBandStop (GSCRegion *region, int Nregion, double dec) {
+
+  int N, Nlo, Nhi;
+  double D0, D1;
+
+  /* D0, D1 are upper lower band boundaries */
+  /* all regions in this band have DEC[0] < D1 */
+  N = FindDecBand (dec, &D0, &D1);
+  if (N == -1) Shutdown ("programming / table error");
+
+  /* bracket value of interest */
+  Nlo = 0; Nhi = Nregion;
+  while (Nhi - Nlo > 10) {
+    N = 0.5*(Nlo + Nhi);
+    if (region[N].DEC[0] > D1) {
+      Nhi = N;
+    } else {
+      Nlo = N;
+    }
+  }
+  /* Nlo - Nhi bracket the transition across dec */
+  /* v[Nlo] <= v < v[Nhi] */ 
+
+  /* find the last entry < dec */
+  for (N = Nlo; N < Nhi; N++) {
+    if (region[N].DEC[0] > D1) return (N);
+  }
+  return (-1);
+  /* this will fail if transition value is not in the data range */
+}
+
+int FindRegionByPoint (GSCRegion *region, double ra, double dec, GSCRegion *gsc, int Ngsc) {
+
+  int i, Ns;
 
   Ns = FindRegionDecBandStart (gsc, Ngsc, dec);
+  if (Ns < 0) return (FALSE);
 
   for (i = Ns; i < Ngsc; i++) {
@@ -115,54 +191,4 @@
 }
 
-int FindRegionDecBandStart (GSCRegion *region, int Nregion, double dec) {
-
-  int N, Nlo, Nhi, N1, N2;
-
-  /* bracket value of interest */
-  Nlo = 0; Nhi = Nregion;
-  while (Nhi - Nlo > 10) {
-    N = 0.5*(Nlo + Nhi);
-    if (region[N].DEC[0] < dec) {
-      Nlo = N;
-    } else {
-      Nhi = N;
-    }
-  }
-  /* Nlo - Nhi bracket the transition across dec */
-  /* v[Nlo] < v <= v[Nhi] */ 
-
-  /* find the last entry < dec */
-  for (N = N2; N >= N1; N--) {
-    if (region[N].DEC[0] < dec) return (N);
-  }
-  return (-1);
-  /* this will fail if transition value is not in the data range */
-}
-
-int FindRegionDecBandStop (GSCRegion *region, int Nregion, double dec) {
-
-  int N, Nlo, Nhi, N1, N2;
-
-  /* bracket value of interest */
-  Nlo = 0; Nhi = Nregion;
-  while (Nhi - Nlo > 10) {
-    N = 0.5*(Nlo + Nhi);
-    if (region[N].DEC[1] > dec) {
-      Nhi = N;
-    } else {
-      Nlo = N;
-    }
-  }
-  /* Nlo - Nhi bracket the transition across dec */
-  /* v[Nlo] <= v < v[Nhi] */ 
-
-  /* find the last entry < dec */
-  for (N = N1; N < N2; N++) {
-    if (region[N].DEC[1] > dec) return (N);
-  }
-  return (-1);
-  /* this will fail if transition value is not in the data range */
-}
-
 /* bracket search:
 
Index: /trunk/Ohana/src/addstar/src/SetSignals.c
===================================================================
--- /trunk/Ohana/src/addstar/src/SetSignals.c	(revision 3375)
+++ /trunk/Ohana/src/addstar/src/SetSignals.c	(revision 3376)
@@ -5,5 +5,5 @@
 
 void TrapSignal (int sig) {
-    fprintf (stderr, "trapped signal %d, exiting gracefully\n", sig);
+    fprintf (stderr, "trapped signal %d\n", sig);
     if (sig == 11) {
       fprintf (stderr, "seg fault\n");
@@ -15,10 +15,10 @@
       return;
     }
-    Shutdown ();
+    Shutdown ("halted by signal (trapped)");
 }    
 
 void SetProtect (int mode) {
   Protect = mode;
-  if (Trapped && !Protect) Shutdown ();
+  if (Trapped && !Protect) Shutdown ("halted by signal (protect)");
 }
 
Index: /trunk/Ohana/src/addstar/src/addstar.c
===================================================================
--- /trunk/Ohana/src/addstar/src/addstar.c	(revision 3375)
+++ /trunk/Ohana/src/addstar/src/addstar.c	(revision 3376)
@@ -32,5 +32,5 @@
     break;
   case M_REFCAT:
-    regions = gregion_patch (&patch, &Nregions);
+    regions = gregion_patch (&UserPatch, &Nregions);
     break;
   }
@@ -44,8 +44,9 @@
     switch (MODE) {
     case M_IMAGE:
+      Nsubset = Nstars;
       find_matches (&regions[i], stars, Nstars, &catalog, &image, overlap, Noverlap);
       break;
     case M_REFCAT:
-      stars = grefcat (argv[1], regions, &Nstars);
+      stars = grefcat (argv[1], &regions[i], &Nstars);
     case M_REFLIST:
       subset = find_subset (&regions[i], stars, Nstars, &Nsubset);
@@ -54,5 +55,9 @@
       break;
     }
-    save_pt_catalog (&catalog);
+    if (Nsubset == 0) {
+      unlock_catalog (&catalog);
+    } else {
+      save_pt_catalog (&catalog);
+    }
   }
 
Index: /trunk/Ohana/src/addstar/src/args.c
===================================================================
--- /trunk/Ohana/src/addstar/src/args.c	(revision 3375)
+++ /trunk/Ohana/src/addstar/src/args.c	(revision 3376)
@@ -37,14 +37,18 @@
   /*** provide additional data ***/ 
   /* restrict to a portion of the sky? (REFCAT only) */
-  patch.RA[0] = 0;
-  patch.RA[1] = 360;
-  patch.DEC[0] = -90;
-  patch.DEC[1] = +90;
+  UserPatch.RA[0] = 0;
+  UserPatch.RA[1] = 360;
+  UserPatch.DEC[0] = -90;
+  UserPatch.DEC[1] = +90;
   if ((N = get_argument (argc, argv, "-region"))) {
     remove_argument (N, &argc, argv);
-    patch.RA[0] = atof (argv[N]);
-    patch.RA[1] = atof (argv[N]);
-    patch.DEC[0] = atof (argv[N]);
-    patch.DEC[1] = atof (argv[N]);
+    UserPatch.RA[0] = atof (argv[N]);
+    remove_argument (N, &argc, argv);
+    UserPatch.RA[1] = atof (argv[N]);
+    remove_argument (N, &argc, argv);
+    UserPatch.DEC[0] = atof (argv[N]);
+    remove_argument (N, &argc, argv);
+    UserPatch.DEC[1] = atof (argv[N]);
+    remove_argument (N, &argc, argv);
   }
   /* override any header PHOTCODE values */
@@ -125,5 +129,10 @@
 
   if (argc != 2) {
-    fprintf (stderr, "USAGE: addstar (filename) [-dump] [-image] [-v] [-p photcode] [-accept] [-cal code1 code2]\n");
+    fprintf (stderr, "USAGE: addstar (filename)\n");
+    fprintf (stderr, "USAGE: addstar -cat (catalog)\n");
+    fprintf (stderr, "USAGE: addstar -ref (filename)\n");
+    fprintf (stderr, "  cur: %s ", argv[0]);
+    for (i = 0; i < argc; i++) { fprintf (stderr, "%s ", argv[i]); }
+    fprintf (stderr, "\n");  
     exit (2);
   }
Index: /trunk/Ohana/src/addstar/src/conversions.c
===================================================================
--- /trunk/Ohana/src/addstar/src/conversions.c	(revision 3375)
+++ /trunk/Ohana/src/addstar/src/conversions.c	(revision 3376)
@@ -308,5 +308,5 @@
   bzero (&now, sizeof(now));
 
-  scanf (date, "%2d%2d%2d", &now.tm_year, &now.tm_mon, &now.tm_mday);
+  sscanf (date, "%2d%2d%2d", &now.tm_year, &now.tm_mon, &now.tm_mday);
 
   if (now.tm_year >   51) now.tm_year +=   0;
Index: /trunk/Ohana/src/addstar/src/find_matches.c
===================================================================
--- /trunk/Ohana/src/addstar/src/find_matches.c	(revision 3375)
+++ /trunk/Ohana/src/addstar/src/find_matches.c	(revision 3376)
@@ -15,7 +15,9 @@
   short int Mrel, *Mval;
 
-  /* photcode data */
+  /* photcode data - must by of type DEP, (PRI, SEC) - probably should restrict to DEP */
   Nsecfilt = GetPhotcodeNsecfilt ();
-  Nsec = GetPhotcodeNsec (thiscode[0].code);
+  Nsec = (thiscode[0].type == PHOT_DEP) ?
+    GetPhotcodeNsec (thiscode[0].equiv) :
+    GetPhotcodeNsec (thiscode[0].code);
   /* this function requires incoming stars to have the same photcode */
 
@@ -114,5 +116,5 @@
       dY = Y1[i] - Y2[J];
       dR = dX*dX + dY*dY;
-      if (dR < RADIUS2) continue;
+      if (dR > RADIUS2) continue;
 
       Nmatch ++;
@@ -153,4 +155,5 @@
       catalog[0].measure[Nmeas].theta    = MIN ((255/360)*stars[N].df, NO_ERR);
 	
+      /*** this should probably use the mag lookup functions - zeropoints are incorrectly applied ***/
       /* it is not valid to pass PRI/SEC/REF photcodes to this routine */
       /* check for entries in the secfilt lists */
@@ -365,4 +368,5 @@
   }
 
+  /* check if the catalog has changed?  if no change, no need to write */
   catalog[0].Naverage = Nave;
   catalog[0].Nmeasure = Nmeas;
Index: /trunk/Ohana/src/addstar/src/get2mass.c
===================================================================
--- /trunk/Ohana/src/addstar/src/get2mass.c	(revision 3375)
+++ /trunk/Ohana/src/addstar/src/get2mass.c	(revision 3376)
@@ -1,3 +1,5 @@
 # include "addstar.h"
+
+static short TM_J, TM_H, TM_K;
 
 Stars *get2mass (GSCRegion *patch, int *NSTARS) {
@@ -7,10 +9,15 @@
   Stars     *refcat;
   TM_Region *regions;
-  short int TM_J, TM_H, TM_K;
 
   NAMED_PHOTCODE (TM_J, "2MASS_J");
   NAMED_PHOTCODE (TM_H, "2MASS_H");
   NAMED_PHOTCODE (TM_K, "2MASS_K");
+  if (thiscode == NULL) Shutdown ("photcode not specified");
+  if (thiscode[0].code == TM_J) goto good_code;
+  if (thiscode[0].code == TM_H) goto good_code;
+  if (thiscode[0].code == TM_K) goto good_code;
+  Shutdown ("2MASS photcode not specified");
 
+good_code:
   regions = get2mass_acc (patch, &Nregions);
   
@@ -19,5 +26,5 @@
   
   for (i = 0; i < Nregions; i++) {
-    refcat = get2mass_data (regions[i].name, patch, &Nrefcat);
+    refcat = get2mass_data (&regions[i], patch, &Nrefcat);
 
     REALLOCATE (stars, Stars, MAX (1, Nstars + Nrefcat));
@@ -34,15 +41,15 @@
 
 /* watch for patch which cross 0,360 boundary */
-TM_Region *get2mass_acc (GSCRegion *patch, int *nfiles) {
+TM_Region *get2mass_acc (GSCRegion *patch, int *nregions) {
 
-  int       Nregions
+  int Nregions, NREGIONS, Nrec;
   TM_Region *regions;
+  char accel[1024], line[128], filename[128];
+  FILE     *f;
+  double Rs, Re;
 
   sprintf (accel, "%s/idr2.acc", TWO_MASS_DIR);
   f = fopen (accel, "r");
-  if (f == NULL) {
-    fprintf (stderr, "ERROR: can't read data from %s\n", file);
-    Shutdown ();
-  }
+  if (f == NULL) Shutdown ("can't read data from accelerator %s", accel);
 
   Nregions = 0;
@@ -51,12 +58,14 @@
 
   /* read in stars line-by-line */
-  for (N = 0; scan_line (f, line) != EOF; N++) {
+  while (scan_line (f, line) != EOF) {
     stripwhite (line);
     if (line[0] == 0) continue;
     if (line[0] == '#') continue;
-    scanf (line, "%s %lf %lf %d", filename, &Rs, &Re, &Nrec);
+    sscanf (line, "%s %lf %lf %d", filename, &Rs, &Re, &Nrec);
+    Rs *= 15.0;
+    Re *= 15.0;
     if (Rs > patch[0].RA[1]) continue;
     if (Re < patch[0].RA[0]) continue;
-    strcpy (regions[Nregions].filename, "%s/%s", TWO_MASS_DIR, filename);
+    sprintf (regions[Nregions].filename, "%s/%s", TWO_MASS_DIR, filename);
     regions[Nregions].RA[0] = Rs;
     regions[Nregions].RA[1] = Re;
@@ -71,18 +80,24 @@
 
 # define NBYTE 302
-# define NLINE 100
+# define NLINE 30000
 
-Stars *get2mass_data (char *filename, GSCRegion *patch, int *nstars) {
+Stars *get2mass_data (TM_Region *region, GSCRegion *patch, int *nstars) {
   
-  int Nstars;
+  int i, Nstars, NSTARS, Nbyte, Nline, Nval;
   Stars *stars;
   gzFile gf;
-  char buffer[NLINE*NBYTE];
+  char *filename, buffer[NLINE*NBYTE], datestr[64];
+  double RA, DEC, J, H, K, dJ, dH, dK;
+  e_time time;
+  double RA0, RA1, DEC0, DEC1;
 
+  RA0  = MAX (patch[0].RA[0],  UserPatch.RA[0]);
+  RA1  = MIN (patch[0].RA[1],  UserPatch.RA[1]);
+  DEC0 = MAX (patch[0].DEC[0], UserPatch.DEC[0]);
+  DEC1 = MIN (patch[0].DEC[1], UserPatch.DEC[1]);
+
+  filename = region[0].filename;
   gf = gzopen (filename, "rb");
-  if (gf == NULL) {
-    fprintf (stderr, "ERROR: can't read data from %s\n", file);
-    Shutdown ();
-  }
+  if (gf == NULL) Shutdown ("can't read 2mass data file: %s", filename);
 
   Nstars = 0;
@@ -90,70 +105,76 @@
   ALLOCATE (stars, Stars, NSTARS);
 
-  /* z_off_t gzseek (gzFile file, z_off_t offset, int whence); */
+  /* don't bother to seek ahead : position is not sufficiently predictable 
+     and gzseek is as expensive as gzread */
+  /* 
+  Noffset = region[0].Nrec * (patch[0].DEC[0] + 90) / 180.0;
+  gzseek (gf, Noffset * NBYTE, SEEK_SET);
+  Nbyte = gzread (gf, buffer, NLINE*NBYTE);
+  */
 
   while ((Nbyte = gzread (gf, buffer, NLINE*NBYTE)) != 0) {
-
-    if (Nbyte == -1) {
-      fprintf (stderr, "error reading from gzipped file %s\n", filename);
-      Shutdown ();
-    }
-
-    Nfrac = Nbyte % NBYTE;
-    if (Nfrac) {
-      fprintf (stderr, "error reading complete line from gzipped file %s\n", filename);
-      Shutdown ();
-    }
-
+    if (Nbyte ==  0) Shutdown ("error reading from gzipped file %s", filename);
+    if (Nbyte == -1) Shutdown ("error reading from gzipped file %s", filename);
+    if (Nbyte % NBYTE) Shutdown ("error reading complete line from gzipped file %s", filename);
     Nline = Nbyte / NBYTE;
 
+    /* skip past block not yet in range */
+    sscanf (&buffer[NBYTE*(Nline - 1)], "%lf %lf", &RA, &DEC);
+    if (DEC < DEC0) continue;
+
     for (i = 0; i < Nline; i++) {
-      Nval  = scanf (&buffer[NBYTE*i + 	 0], "%lf %lf", &RA, &DEC);
-      if (RA < patch[0].RA[0]) continue;
-      if (RA > patch[0].RA[1]) continue;
-      if (DEC < patch[0].DEC[0]) continue;
-      if (DEC < patch[0].DEC[1]) continue;
+      
+      dparse (&RA,  1, &buffer[NBYTE*i+  0]);
+      dparse (&DEC, 2, &buffer[NBYTE*i+  0]);
 
-      Nval += scanf (&buffer[NBYTE*i + 	53], "%lf %lf", &J, &dJ);
-      Nval += scanf (&buffer[NBYTE*i + 	72], "%lf %lf", &H, &dH);
-      Nval += scanf (&buffer[NBYTE*i + 	91], "%lf %lf", &K, &dK);
-      Nval += scanf (&buffer[NBYTE*i + 164], "%s", datestr);
-      if (Nval != 9) {
-	fprintf (stderr, "error in 2mass data line\n");
-	exit (1);
+      if (DEC > DEC1) goto finished;
+      if (DEC < DEC0) continue;
+      if (RA <  RA0) continue;
+      if (RA >  RA1) continue;
+      
+      stars[Nstars].R  	  = RA;
+      stars[Nstars].D  	  = DEC;
+      stars[Nstars].t  	  = short_date_to_sec (&buffer[NBYTE*i + 164]);
+      stars[Nstars].found = -1;
+
+      if (thiscode[0].code == TM_J) {
+	dparse (&J,  1, &buffer[NBYTE*i + 53]);
+	dparse (&dJ, 2, &buffer[NBYTE*i + 53]);
+	stars[Nstars].M    = J;
+	stars[Nstars].dM   = dJ;
+	stars[Nstars].code = TM_J;
       }
-
-      time = short_date_to_set (datestr);
-
-      stars[Nstars].R  	 = RA;
-      stars[Nstars].D  	 = DEC;
-      stars[Nstars].M  	 = J;
-      stars[Nstars].dM 	 = dJ;
-      stars[Nstars].t  	 = time;
-      stars[Nstars].code = TM_J;
+      if (thiscode[0].code == TM_H) {
+	dparse (&H,  1, &buffer[NBYTE*i + 72]);
+	dparse (&dH, 2, &buffer[NBYTE*i + 72]);
+	stars[Nstars].M    = H;
+	stars[Nstars].dM   = dH;
+	stars[Nstars].code = TM_H;
+      }
+      if (thiscode[0].code == TM_K) {
+	dparse (&K,  1, &buffer[NBYTE*i + 91]);
+	dparse (&dK, 2, &buffer[NBYTE*i + 91]);
+	stars[Nstars].M    = K;
+	stars[Nstars].dM   = dK;
+	stars[Nstars].code = TM_K;
+      }
       Nstars ++;
-
-      stars[Nstars].R 	 = RA;
-      stars[Nstars].D 	 = DEC;
-      stars[Nstars].M 	 = H;
-      stars[Nstars].dM	 = dH;
-      stars[Nstars].t 	 = time;
-      stars[Nstars].code = TM_H;
-      Nstars ++;
-
-      stars[Nstars].R 	 = RA;
-      stars[Nstars].D 	 = DEC;
-      stars[Nstars].M 	 = K;
-      stars[Nstars].dM	 = dK;
-      stars[Nstars].t 	 = time;
-      stars[Nstars].code = TM_K;
-      Nstars ++;
-      
-      CHECK_REALLOCATE (stars, Stars, NSTARS, Nstars - 2, 300);
-    }      
-  }    
+      CHECK_REALLOCATE (stars, Stars, NSTARS, Nstars, 300);
+    }
+  }  
+finished:
+  gzclose (gf);
 
   *nstars = Nstars;
   return (stars);
 }
+
+/*
+      Nval  = sscanf (&buffer[NBYTE*i + 	 0], "%lf %lf", &RA, &DEC);
+      Nval += sscanf (&buffer[NBYTE*i + 	53], "%lf %lf", &J, &dJ);
+      Nval += sscanf (&buffer[NBYTE*i + 	72], "%lf %lf", &H, &dH);
+      Nval += sscanf (&buffer[NBYTE*i + 	91], "%lf %lf", &K, &dK);
+      Nval += sscanf (&buffer[NBYTE*i + 164], "%s", datestr);
+*/
 
     /* this just scans along in the file.  file is sorted by dec, so we 
Index: /trunk/Ohana/src/addstar/src/getgsc.c
===================================================================
--- /trunk/Ohana/src/addstar/src/getgsc.c	(revision 3375)
+++ /trunk/Ohana/src/addstar/src/getgsc.c	(revision 3376)
@@ -4,15 +4,22 @@
 # define DNSTARS 1000
 
+static short GSC_M;
+
 Stars *getgsc (GSCRegion *patch, int *NSTARS) {
   
   int i, j, k, Ns, Ngsc, Nregions, Nstars; 
-  StarData *gsc;
-  StarData *stars;
-  GSCRegions *regions;
-  short int GSC_M;
+  Stars *gsc;
+  Stars *stars;
+  GSCRegion *regions;
+  char *tmp;
 
   NAMED_PHOTCODE (GSC_M, "GSC_M");
 
+  /* sort of sleaze way to get the right GSC files */
+  tmp = strcreate (CATDIR);
+  strcpy (CATDIR, GSCDIR);
   regions = gregion_patch (patch, &Nregions);
+  strcpy (CATDIR, tmp);
+  free (tmp);
   
   Nstars = 0;
@@ -20,5 +27,5 @@
   
   for (i = 0; i < Nregions; i++) {
-    gsc = rd_gsc (regions[i].name, &Ngsc);
+    gsc = rd_gsc (regions[i].filename, &Ngsc);
 
     REALLOCATE (stars, Stars, MAX (1, Nstars + Ngsc));
@@ -36,5 +43,5 @@
 Stars *rd_gsc (char *filename, int *nstars) {
   
-  int i, NSTARS, Nstars, Nbytes, nbytes;
+  int i, NSTARS, Nstars, Nbytes, nbytes, Nline, Nbyte;
   char *buffer;
   FILE *f;
@@ -60,8 +67,14 @@
       dparse (&stars[Nstars].R, 1, &buffer[Nbyte]);
       dparse (&stars[Nstars].D, 2, &buffer[Nbyte]);
+      if (stars[Nstars].R < UserPatch.RA[0]) continue;
+      if (stars[Nstars].R > UserPatch.RA[1]) continue;
+      if (stars[Nstars].D < UserPatch.DEC[0]) continue;
+      if (stars[Nstars].D > UserPatch.DEC[1]) continue;
+
       dparse (&stars[Nstars].M, 3, &buffer[Nbyte]);
-      stars[Nstars].dM 	 = NO_ERR;
-      stars[Nstars].t  	 = 0;
-      stars[Nstars].code = GSC_M;
+      stars[Nstars].dM 	  = NO_ERR;
+      stars[Nstars].t  	  = 0;
+      stars[Nstars].code  = GSC_M;
+      stars[Nstars].found = -1;
       Nstars ++;
       CHECK_REALLOCATE (stars, Stars, NSTARS, Nstars, 1000);
Index: /trunk/Ohana/src/addstar/src/getusno.c
===================================================================
--- /trunk/Ohana/src/addstar/src/getusno.c	(revision 3375)
+++ /trunk/Ohana/src/addstar/src/getusno.c	(revision 3376)
@@ -24,12 +24,19 @@
   short int USNO_RED, USNO_BLUE;
 
+  /* require photcode */
   NAMED_PHOTCODE (USNO_RED, "USNO_RED");
   NAMED_PHOTCODE (USNO_BLUE, "USNO_BLUE");
+  if (thiscode == NULL) Shutdown ("photcode not specified");
+  if (thiscode[0].code == USNO_RED) goto good_code;
+  if (thiscode[0].code == USNO_BLUE) goto good_code;
+  Shutdown ("USNO photcode not specified");
+good_code:
 
   /* identify ra & dec range of interest */
-  iRA0  =  catstats[0].RA[0] * 360000.0;
-  iRA1  =  catstats[0].RA[1] * 360000.0;
-  iDEC0 = (catstats[0].DEC[0] + 90.0) * 360000.0;
-  iDEC1 = (catstats[0].DEC[1] + 90.0) * 360000.0;
+  /* note: the use of UserPatch to restrict here limits general utility of function */
+  iRA0  =  MAX (catstats[0].RA[0], UserPatch.RA[0]) * 360000.0;
+  iRA1  =  MIN (catstats[0].RA[1], UserPatch.RA[1]) * 360000.0;
+  iDEC0 = (MAX (catstats[0].DEC[0], UserPatch.DEC[0]) + 90.0) * 360000.0;
+  iDEC1 = (MIN (catstats[0].DEC[1], UserPatch.DEC[1]) + 90.0) * 360000.0;
   
   /* data is organized in south-pole distance zones */
@@ -116,22 +123,21 @@
 
 	bzero (&stars[Nusno], sizeof(Stars));
-	stars[Nusno].R    = buf[0]/360000.0;
-	stars[Nusno].D    = buf[1]/360000.0 - 90.0;
-	stars[Nusno].M    = fabs (0.1*(buf[2] - 1000*((int)(buf[2]/1000))));
-	stars[Nusno].dM   = NO_ERR;
-	stars[Nusno].t    = 0;
-	stars[Nusno].code = USNO_RED;
-	/* r data */
+	stars[Nusno].R     = buf[0]/360000.0;
+	stars[Nusno].D     = buf[1]/360000.0 - 90.0;
+	stars[Nusno].dM    = NO_ERR;
+	stars[Nusno].t     = 0;
+	stars[Nusno].found = -1;
+
+	/* one pass of addstar does either r or b */
+	if (thiscode[0].code == USNO_RED) {
+	  stars[Nusno].code  = USNO_RED;
+	  stars[Nusno].M     = fabs (0.1*(buf[2] - 1000*((int)(buf[2]/1000))));
+	} 
+	if (thiscode[0].code == USNO_BLUE) {	
+	  stars[Nusno].code  = USNO_BLUE;
+	  stars[Nusno].M     = fabs (0.1*((int)(buf[2] - 1000000*((int)(buf[2]/1000000))) / 1000));
+	}
 	Nusno ++;
-	stars[Nusno].R    = buf[0]/360000.0;
-	stars[Nusno].D    = buf[1]/360000.0 - 90.0;
-	stars[Nusno].M    = fabs (0.1*((int)(buf[2] - 1000000*((int)(buf[2]/1000000))) / 1000));
-	stars[Nusno].dM   = NO_ERR;
-	stars[Nusno].t    = 0;
-	stars[Nusno].code = USNO_BLUE;
-	/* b data */
-	Nusno ++;
-
-	CHECK_REALLOCATE (stars, Stars, NUSNO, Nusno-1, 5000);
+	CHECK_REALLOCATE (stars, Stars, NUSNO, Nusno, 5000);
       }
       free (buffer);
Index: /trunk/Ohana/src/addstar/src/gimages.c
===================================================================
--- /trunk/Ohana/src/addstar/src/gimages.c	(revision 3375)
+++ /trunk/Ohana/src/addstar/src/gimages.c	(revision 3376)
@@ -4,5 +4,5 @@
 Image *gimages (Image *image, int *Npimage) {
   
-  int i, j, k, Nimage, addtolist, size;
+  int i, j, k, Nimage, addtolist, size, dbstate;
   int NTIMAGE, Ntimage, ntimage;
   int NPIMAGE, npimage;
@@ -14,19 +14,24 @@
   double zeropt;
   struct stat filestatus;
+  FILE *f;
   
-  f = GetDB ();
+  /* if image.db is opened successfully, f will not be NULL.
+     if image.db is empty, dbstate will be LCK_EMPTY */
+  f = GetDB (&dbstate);
+  if (dbstate == LCK_EMPTY) {
+    *Npimage = 0;
+    return (NULL);
+  }
   fseek (f, 0, SEEK_SET);
 
   /* read header */
   if (!fits_load_header (f, &header)) {
-    if (VERBOSE) fprintf (stderr, "error: can't read image catalog %s\n", ImageCat);
-    Shutdown ();
+    Shutdown ("can't read image catalog %s", ImageCat);
   }
 
   fits_scan (&header, "ZERO_PT", "%lf", 1, &zeropt);
   if (fabs (ZeroPt - zeropt) > 1e-4) {
-    fprintf (stderr, "error: zero point in image (%f:%s) inconsistent with zero point in catalog (%f)\n",
+    Shutdown ("zero point in image (%f:%s) inconsistent with zero point in catalog (%f)",
 	     ZeroPt, image[0].name, zeropt);
-    Shutdown ();
   }
 
@@ -57,6 +62,5 @@
   /* check that file size makes sense */
   if (stat (ImageCat, &filestatus) == -1) {
-    fprintf (stderr, "error: failed to get status of image catalog\n");
-    Shutdown ();
+    Shutdown ("failed to get status of image catalog");
   }
   size = Nimage*sizeof(Image) + header.size;
@@ -67,5 +71,5 @@
     fprintf (stderr, "error: image catalog has inconsistent size\n");
     fprintf (stderr, "header: %d images, data: %d images\n", Nimage, Ndata);
-    if (!FORCE_READ) Shutdown ();
+    if (!FORCE_READ) Shutdown ("refuse to read image table");
 
     Nimage = MIN (Nimage, Ndata);
@@ -114,6 +118,5 @@
 
     if (ntimage == 0) {
-      fprintf (stderr, "error: expected %d images, only found %d\n", Nimage, Ntimage);
-      Shutdown ();
+      Shutdown ("expected %d images, only found %d", Nimage, Ntimage);
     }
   }
Index: /trunk/Ohana/src/addstar/src/greference.c
===================================================================
--- /trunk/Ohana/src/addstar/src/greference.c	(revision 3375)
+++ /trunk/Ohana/src/addstar/src/greference.c	(revision 3376)
@@ -12,22 +12,20 @@
 
   /* get stars from USNO for the given region */
-  if (!strcmp (Refcat, "USNO")) {
+  if (!strcasecmp (Refcat, "USNO")) {
     stars = getusno (catstats, &Nstars);
   }
 
   /* get stars from HST GSC for the given region */
-  if (!strcmp (Refcat, "GSC")) {
+  if (!strcasecmp (Refcat, "GSC")) {
     stars = getgsc (catstats, &Nstars);
   }
   
   /* get stars from 2MASS for the given region */
-  if (!strcmp (Refcat, "2MASS")) {
+  if (!strcasecmp (Refcat, "2MASS")) {
     stars = get2mass (catstats, &Nstars);
   }
   
-  if (Nstars == 0) {
-    fprintf (stderr, "no ref objs: %s\n", Refcat);
-    exit (1);
-  }
+  if (VERBOSE && (Nstars == 0)) fprintf (stderr, "no ref objects in region %s\n", catstats[0].filename);
+
   *nstars = Nstars;
   return (stars);
Index: /trunk/Ohana/src/addstar/src/grefstars.c
===================================================================
--- /trunk/Ohana/src/addstar/src/grefstars.c	(revision 3375)
+++ /trunk/Ohana/src/addstar/src/grefstars.c	(revision 3376)
@@ -9,19 +9,13 @@
   char line[256];
 
+  /* require photcode */
+  if (thiscode == NULL) Shutdown ("photcode not specified");
+
   /* open file */
   f = fopen (file, "r");
-  if (f == NULL) {
-    fprintf (stderr, "ERROR: can't read data from %s\n", file);
-    Shutdown ();
-  }
+  if (f == NULL) Shutdown ("can't read data from %s", file);
 
   NSTARS = 100;
   ALLOCATE (stars, Stars, NSTARS);
-
-  /* require photcode */
-  if (thiscode == NULL) {
-    fprintf (stderr, "error: photcode not specified\n");
-    exit (2);
-  }
 
   /* read in stars line-by-line */
Index: /trunk/Ohana/src/addstar/src/gregion_image.c
===================================================================
--- /trunk/Ohana/src/addstar/src/gregion_image.c	(revision 3375)
+++ /trunk/Ohana/src/addstar/src/gregion_image.c	(revision 3376)
@@ -4,49 +4,25 @@
 GSCRegion *gregion_image (Image *image, int *Nregions) {
   
-  GSCRegion *region;
-  FILE *f;
-  double x, y;
-  double dec, ra;
-  int i, j, done, nregion, NREGION;
+  GSCRegion *regions, impatch;
+  double x, y, X, Y, ra, dec;
   
-  f = fopen (GSCFILE, "r");
-  if (f == NULL) {
-    fprintf (stderr, "ERROR: can't find GSC region file %s\n", GSCFILE);
-    exit (1);
-  }
-  
-  /* find regions at image corners */
-  NREGION = 100;
-  ALLOCATE (region, GSCRegion, NREGION);
-  nregion = 0;
+  /* this has trouble for images which overlap 0,360 */
+  impatch.RA[0]  = 360;
+  impatch.RA[1]  =   0;
+  impatch.DEC[0] = +90;
+  impatch.DEC[1] = -90;
 
-  /* this is not efficient, nor guaranteed - fix me */
-  /* look for new regions on grid across image */ 
-  for (x = 0.0; x <= 1.0; x+=0.1) {
-    for (y = 0.0; y <= 1.0; y+=0.1) {
-      XY_to_RD (&ra, &dec, image[0].NX*(1.1*x - 0.05), image[0].NY*(1.1*y - 0.05), &image[0].coords);
-      aregion (&region[nregion], f, ra, dec);
-      done = FALSE;
-      for (j = 0; (j < nregion) && !done; j++) {
-	if (!strcmp (region[nregion].filename, region[j].filename)) {
-	  nregion --;
-	  done = TRUE;
-	}
-      }
-      nregion ++;
-      CHECK_REALLOCATE (region, GSCRegion, NREGION, nregion, 100);
+  for (x = 0; x <= 1; x++) {
+    for (y = 0; y <= 1; y++) {
+      X = image[0].NX*(1.1*x - 0.05);
+      Y = image[0].NY*(1.1*y - 0.05);
+      XY_to_RD (&ra, &dec, X, Y, &image[0].coords);
+      impatch.RA[0]  = MIN (ra,  impatch.RA[0]);
+      impatch.RA[1]  = MAX (ra,  impatch.RA[1]);
+      impatch.DEC[0] = MIN (dec, impatch.DEC[0]);
+      impatch.DEC[1] = MAX (dec, impatch.DEC[1]);
     }
   }
-
-  if (VERBOSE) {
-    fprintf (stderr, "found %d region files:\n", nregion);
-    for (i = 0; i < nregion; i++) {
-      fprintf (stderr, "  %d %s\n", i, region[i].filename);
-    }
-  }
-  *Nregions = nregion;
-  
-  fclose (f);
-  return (region);
-  
+  regions = gregion_patch (&impatch, Nregions);
+  return (regions);
 }
Index: /trunk/Ohana/src/addstar/src/gregion_match.c
===================================================================
--- /trunk/Ohana/src/addstar/src/gregion_match.c	(revision 3375)
+++ /trunk/Ohana/src/addstar/src/gregion_match.c	(revision 3376)
@@ -3,6 +3,5 @@
 GSCRegion *gregion_match (GSCRegion *regions, int *nregions) {
   
-  int i;
-  int       Nsubset;
+  int i, status, Nregions, Nsubset, NSUBSET;
   GSCRegion *subset;
   struct stat filestats;
@@ -12,5 +11,5 @@
   Nsubset = 0;
   NSUBSET = 100;
-  ALLOCATE (subset, GSCRegions, NSUBSET);
+  ALLOCATE (subset, GSCRegion, NSUBSET);
 
   /* match the basename against the GSCRegion file names */
@@ -22,5 +21,5 @@
     subset[Nsubset] = regions[i];
     Nsubset ++;
-    CHECK_ALLOCATE (subset, GSCRegion, NSUBSET, Nsubset, 100);
+    CHECK_REALLOCATE (subset, GSCRegion, NSUBSET, Nsubset, 100);
   }
   free (regions);
Index: /trunk/Ohana/src/addstar/src/gregion_match_glob.c
===================================================================
--- /trunk/Ohana/src/addstar/src/gregion_match_glob.c	(revision 3375)
+++ /trunk/Ohana/src/addstar/src/gregion_match_glob.c	(revision 3376)
@@ -17,5 +17,5 @@
 
   Nregions = 0;
-  ALLOCATE (regions, GSCRegions, MAX (1, pglob.gl_pathc));
+  ALLOCATE (regions, GSCRegion, MAX (1, pglob.gl_pathc));
 
   /* match the basename against the GSCRegion file names */
Index: /trunk/Ohana/src/addstar/src/gregion_patch.c
===================================================================
--- /trunk/Ohana/src/addstar/src/gregion_patch.c	(revision 3375)
+++ /trunk/Ohana/src/addstar/src/gregion_patch.c	(revision 3376)
@@ -3,6 +3,5 @@
 GSCRegion *gregion_patch (GSCRegion *patch, int *nregions) {
   
-  int i;
-  int       Ngsc, Nregions;
+  int i, Ns, Ne, Ngsc, Nregions;
   GSCRegion *gsc, *regions;
   
@@ -12,7 +11,9 @@
   Ns = FindRegionDecBandStart (gsc, Ngsc, patch[0].DEC[0]);
   Ne = FindRegionDecBandStop (gsc, Ngsc, patch[0].DEC[1]);
+  if (Ns < 0) Shutdown ("invalid patch lower bound %f", patch[0].DEC[0]);
+  if (Ne < 0) Shutdown ("invalid patch upper bound %f", patch[0].DEC[1]);
   
   Nregions = 0;
-  ALLOCATE (regions, GSCRegions, (Ne - Ns));
+  ALLOCATE (regions, GSCRegion, Ne - Ns);
 
   /* find all regions in range within ra range */
Index: /trunk/Ohana/src/addstar/src/gregion_star.c
===================================================================
--- /trunk/Ohana/src/addstar/src/gregion_star.c	(revision 3375)
+++ /trunk/Ohana/src/addstar/src/gregion_star.c	(revision 3376)
@@ -3,7 +3,6 @@
 GSCRegion *gregion_stars (Stars *stars, int Nstars, int *nregions) {
   
-  int i;
-  int       Ngsc, Nregions, NREGIONS;
-  GSCRegion *gsc, regions;
+  int i, j, Ngsc, Nregions, NREGIONS;
+  GSCRegion *gsc, *regions;
   
   gsc = LoadRegions (&Ngsc);
@@ -13,14 +12,14 @@
   ALLOCATE (regions, GSCRegion, NREGIONS);
 
-  sort_stars (stars, Nstars);
+  sort_stars (stars, Nstars); /* sort by RA */
   for (i = 0; i < Nstars; i++) {
-    if (stars[0].found) continue;
-    FindRegionByPoint (&regions[Nregions], star[0].R, star[0].D, gsc, Ngsc);
-    stars[0].found = TRUE;
+    if (stars[i].found) continue;
+    FindRegionByPoint (&regions[Nregions], stars[i].R, stars[i].D, gsc, Ngsc);
+    stars[i].found = TRUE;
     /* search forward for all contained stars */
     for (j = i; j < Nstars; j++) {
-      if (stars[j].R >= regions.RA[1]) break;
-      if (stars[j].D <  regions.DEC[0]) continue;
-      if (stars[j].D >= regions.DEC[1]) continue;
+      if (stars[j].R >= regions[Nregions].RA[1]) break;
+      if (stars[j].D <  regions[Nregions].DEC[0]) continue;
+      if (stars[j].D >= regions[Nregions].DEC[1]) continue;
       stars[j].found = TRUE;
     }
Index: /trunk/Ohana/src/addstar/src/gztest.c
===================================================================
--- /trunk/Ohana/src/addstar/src/gztest.c	(revision 3376)
+++ /trunk/Ohana/src/addstar/src/gztest.c	(revision 3376)
@@ -0,0 +1,99 @@
+# include "ohana.h"
+# include "zlib.h"
+# define DTIME(A,B) ((A.tv_sec - B.tv_sec) + 1e-6*(A.tv_usec - B.tv_usec))
+
+main (int argc, char **argv) {
+
+  int N, Nread, Nseek, Nback;
+  char *filename, *buffer;
+  gzFile gf;
+  FILE *f;
+  struct timeval start, stop;
+
+  if (argc != 6) {
+    fprintf (stderr, "USAGE: gztest (mode) (file) (Nseek) (Nread) (Nback)\n");
+    exit (2);
+  }
+
+  filename = argv[2];
+  Nseek = atoi (argv[3]);
+  Nread = atoi (argv[4]);
+  Nback = -1 * atoi (argv[5]);
+  ALLOCATE (buffer, char, Nread);
+
+  if (!strcmp (argv[1], "gz")) {
+    gf = gzopen (filename, "rb");
+    if (gf == NULL) {
+      fprintf (stderr, "can't read data file: %s", filename);
+      exit (1);
+    }
+
+    gettimeofday (&start, NULL);
+    N = gzseek (gf, Nseek, SEEK_SET);
+    gettimeofday (&stop, NULL);
+    if (N != Nseek) {
+      fprintf (stderr, "error seeking\n");
+      exit (1);
+    }
+    fprintf (stdout, "seek: %f\n", DTIME (stop, start));
+
+    gettimeofday (&start, NULL);
+    N = gzread (gf, buffer, Nread);
+    if (N != Nread) {
+      fprintf (stderr, "error reading\n");
+      exit (1);
+    }
+    gettimeofday (&stop, NULL);
+    fprintf (stdout, "read: %f\n", DTIME (stop, start));
+
+    gettimeofday (&start, NULL);
+    N = gzseek (gf, Nback, SEEK_CUR);
+    gettimeofday (&stop, NULL);
+    if (N == -1) {
+      fprintf (stderr, "error seeking\n");
+      exit (1);
+    }
+    fprintf (stdout, "back: %f\n", DTIME (stop, start));
+    exit (0);
+  } 
+
+  if (!strcmp (argv[1], "raw")) {
+    f = fopen (filename, "r");
+    if (f == NULL) {
+      fprintf (stderr, "can't read data file: %s", filename);
+      exit (1);
+    }
+
+    gettimeofday (&start, NULL);
+    N = fseek (f, Nseek, SEEK_SET);
+    gettimeofday (&stop, NULL);
+    if (N) {
+      fprintf (stderr, "error seeking\n");
+      exit (1);
+    }
+    fprintf (stdout, "seek: %f\n", DTIME (stop, start));
+
+    gettimeofday (&start, NULL);
+    N = fread (buffer, 1, Nread, f);
+    gettimeofday (&stop, NULL);
+    if (N != Nread) {
+      fprintf (stderr, "error reading\n");
+      exit (1);
+    }
+    fprintf (stdout, "read: %f\n", DTIME (stop, start));
+
+    gettimeofday (&start, NULL);
+    N = fseek (f, Nback, SEEK_CUR);
+    gettimeofday (&stop, NULL);
+    if (N) {
+      fprintf (stderr, "error seeking\n");
+      exit (1);
+    }
+    fprintf (stdout, "back: %f\n", DTIME (stop, start));
+    exit (0);
+  }
+    
+  
+  fprintf (stderr, "unknown mode\n");
+  exit (1);
+}
Index: /trunk/Ohana/src/addstar/src/image-db.c
===================================================================
--- /trunk/Ohana/src/addstar/src/image-db.c	(revision 3375)
+++ /trunk/Ohana/src/addstar/src/image-db.c	(revision 3376)
@@ -1,7 +1,7 @@
 # include "addstar.h"
 
-/* file-pointer to Image.db table. if image db does not yet exist,
-   
-*/
+# define LOCK LCK_XCLD
+
+/* file-pointer to Image.db table. if image db does not yet exist */
 static FILE *f = (FILE *) NULL;
 static int dbstate = LCK_UNLOCK;
@@ -13,7 +13,19 @@
 
 /* clean up open / locked ImageCat before shutting down */
-int Shutdown () {  
+int Shutdown (char *format, ...) {  
+  va_list argp;
+  char *formatplus;
+  
+  ALLOCATE (formatplus, char, strlen(format));
+  strcpy (formatplus, format);
+  strcat (formatplus, "\n");
+
+  va_start (argp, format);
+  vfprintf (stderr, formatplus, argp);
+  free (formatplus);
+  va_end (argp);
+
   SetProtect (TRUE);
-  fclearlockfile (ImageCat, f, LCK_HARD, &dbstate);
+  fclearlockfile (ImageCat, f, LOCK, &dbstate);
   fprintf (stderr, "ERROR: addstar halted\n");
   exit (1);
@@ -23,5 +35,5 @@
   /* lock the image catalog */
   check_permissions (ImageCat);
-  f = fsetlockfile (ImageCat, 3600.0, LCK_HARD, &dbstate);
+  f = fsetlockfile (ImageCat, 3600.0, LOCK, &dbstate);
   if ((f == (FILE *) NULL) && (dbstate != LCK_EMPTY)) {
     fprintf (stderr, "ERROR: can't lock image catalog\n");
@@ -33,6 +45,8 @@
 void unlock_image_db (Image *image) {
 
+  mode_t mode;
+
   /* protect wimage from interrupt signals */
-  if (mode == M_IMAGE) {
+  if (MODE == M_IMAGE) {
     SetProtect (TRUE);
     wimage (image); 
@@ -40,5 +54,5 @@
   }
 
-  fclearlockfile (ImageCat, f, LCK_HARD, &dbstate);
+  fclearlockfile (ImageCat, f, LOCK, &dbstate);
   mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
   chmod (ImageCat, mode);
Index: /trunk/Ohana/src/addstar/src/load_pt_catalog.c
===================================================================
--- /trunk/Ohana/src/addstar/src/load_pt_catalog.c	(revision 3375)
+++ /trunk/Ohana/src/addstar/src/load_pt_catalog.c	(revision 3376)
@@ -3,4 +3,6 @@
 int load_pt_catalog (Catalog *catalog, GSCRegion *region) {
   
+  check_permissions (region[0].filename);
+
   /* don't free region before catalog! */
   catalog[0].filename = region[0].filename;
@@ -11,5 +13,5 @@
     /* catalog file is locked.  this is an unexpected error because
        ImageCat was NOT locked so we should be the only locking entity */
-    fprintf (stderr, "ERROR: can't lock file %s\n", catalog.filename);
+    fprintf (stderr, "ERROR: can't lock file %s\n", catalog[0].filename);
     exit (1);
   case 1:
Index: /trunk/Ohana/src/addstar/src/load_subpix.c
===================================================================
--- /trunk/Ohana/src/addstar/src/load_subpix.c	(revision 3375)
+++ /trunk/Ohana/src/addstar/src/load_subpix.c	(revision 3376)
@@ -19,8 +19,6 @@
 
   f = fopen (SubpixDatafile, "r");
-  if (f == (FILE *) NULL) { 
-    fprintf (stderr, "can't load subpix datafile %s\n", SubpixDatafile);
-    Shutdown ();
-  }
+  if (f == NULL) Shutdown ("can't load subpix datafile %s", SubpixDatafile);
+
   for (i = 0; i < Nsubpix; i++) {
     fscanf (f, "%*s %*s %lf %lf %lf %*s\n", 
Index: /trunk/Ohana/src/addstar/src/replace_match.c
===================================================================
--- /trunk/Ohana/src/addstar/src/replace_match.c	(revision 3375)
+++ /trunk/Ohana/src/addstar/src/replace_match.c	(revision 3376)
@@ -3,14 +3,16 @@
 int replace_match (Average *average, Measure *measure, Stars *star) {
 
+  int i;
+
   if (!REPLACE) return (FALSE);
 
   /** in replace mode, search for entry and replace values M, dM, R, D */
-  for (k = 0; k < average[0].Nm; k++) {
-    if (measure[k].source != thiscode[0].code) continue;
-    measure[k].dR       = 360000.0*(average[0].R - stars[0].R);
-    measure[k].dD       = 360000.0*(average[0].D - stars[0].D);
-    measure[k].M        = MIN (1000*stars[0].M,  NO_MAG);
-    measure[k].dM       = MIN (1000*stars[0].dM, NO_ERR);
-    stars[N].found      = average[0].offset + k;
+  for (i = 0; i < average[0].Nm; i++) {
+    if (measure[i].source != thiscode[0].code) continue;
+    measure[i].dR       = 360000.0*(average[0].R - star[0].R);
+    measure[i].dD       = 360000.0*(average[0].D - star[0].D);
+    measure[i].M        = MIN (1000*star[0].M,  NO_MAG);
+    measure[i].dM       = MIN (1000*star[0].dM, NO_ERR);
+    star[0].found      = average[0].offset + i;
     return (TRUE);
   }
Index: /trunk/Ohana/src/addstar/src/sort_lists.c
===================================================================
--- /trunk/Ohana/src/addstar/src/sort_lists.c	(revision 3375)
+++ /trunk/Ohana/src/addstar/src/sort_lists.c	(revision 3376)
@@ -1,4 +1,39 @@
+# include "addstar.h"
 
-void sort_GSCregions (GSCRegion *region, int Nregion) {
+void sort_stars (Stars *stars, int N) {
+
+  int l,j,ir,i;
+  Stars tmp;
+  
+  l = N >> 1;
+  ir = N - 1;
+  for (;;) {
+    if (l > 0) {
+      l--;
+      tmp = stars[l];
+    }
+    else {
+      tmp = stars[ir];
+      stars[ir] = stars[0];
+      if (--ir == 0) {
+	stars[0] = tmp;
+	return;
+      }
+    }
+    i = l;
+    j = (l << 1) + 1;
+    while (j <= ir) {
+      if (j < ir && stars[j].R < stars[j+1].R) j++;
+      if (tmp.R < stars[j].R) {
+	stars[i] = stars[j];
+	j += (i=j) + 1;
+      }
+      else j = ir + 1;
+    }
+    stars[i] = tmp;
+  }
+}
+
+void sort_regions (GSCRegion *region, int N) {
 
   int l,j,ir,i;
@@ -11,6 +46,5 @@
       l--;
       tmp = region[l];
-    }
-    else {
+    } else {
       tmp = region[ir];
       region[ir] = region[0];
@@ -23,6 +57,6 @@
     j = (l << 1) + 1;
     while (j <= ir) {
-      if (j < ir && region[j].DEC < region[j+1].DEC) j++;
-      if (tmp.DEC < region[j].DEC) {
+      if (j < ir && region[j].DEC[0] < region[j+1].DEC[0]) j++;
+      if (tmp.DEC[0] < region[j].DEC[0]) {
 	region[i] = region[j];
 	j += (i=j) + 1;
@@ -47,6 +81,5 @@
       tY = Y[l];
       tS = S[l];
-    }
-    else {
+    } else {
       tX = X[ir];
       X[ir] = X[0];
@@ -91,6 +124,5 @@
       l--;
       tX = X[l];
-    }
-    else {
+    } else {
       tX = X[ir];
       X[ir] = X[0];
Index: /trunk/Ohana/src/addstar/src/update_coords.c
===================================================================
--- /trunk/Ohana/src/addstar/src/update_coords.c	(revision 3375)
+++ /trunk/Ohana/src/addstar/src/update_coords.c	(revision 3376)
@@ -4,7 +4,7 @@
 void update_coords (Average *average, Measure *measure, int *next) {
 
+  int i, m, Npt;
   double R, D, r, d;
   double r2, d2, dR2, dD2;
-  int Npt;
 
   Npt = r = d = r2 = d2 = 0;
@@ -14,5 +14,5 @@
   /* find the average & sum-square */
   m = average[0].offset;  /* first measurement of this star */
-  for (k = 0; k < average[0].Nm; k++) {
+  for (i = 0; i < average[0].Nm; i++) {
     if (measure[m].t == 0) {
       m = next[m];
@@ -36,5 +36,5 @@
   average[0].D -= d / 360000.0;
   m = average[0].offset;  /* first measurement of this star */
-  for (k = 0; k < average[0].Nm; k++) {
+  for (i = 0; i < average[0].Nm; i++) {
     measure[m].dR -= r;
     measure[m].dD -= d;
