Index: /trunk/Ohana/src/addstar/Makefile
===================================================================
--- /trunk/Ohana/src/addstar/Makefile	(revision 4298)
+++ /trunk/Ohana/src/addstar/Makefile	(revision 4299)
@@ -18,5 +18,5 @@
 INCS	= 	-I$(INC) -I$(LINC) -I$(XINC)
 LIBS	= 	-L$(LLIB) -lohana -lFITS -lz -lm
-CFLAGS	=	$(INCS)
+CFLAGS	=	$(INCS) -g
 LFLAGS	=	$(LIBS) 
 
@@ -36,4 +36,6 @@
 $(SRC)/gcatalog.$(ARCH).o \
 $(SRC)/get2mass.$(ARCH).o \
+$(SRC)/get2mass_as.$(ARCH).o \
+$(SRC)/get2mass_dr2.$(ARCH).o \
 $(SRC)/getgsc.$(ARCH).o \
 $(SRC)/getusno.$(ARCH).o \
@@ -64,4 +66,14 @@
 $(SRC)/rtext.$(ARCH).o
 
+MKACC-2MASS = \
+$(SRC)/mkacc-2mass.$(ARCH).o \
+$(SRC)/image-db.$(ARCH).o \
+$(SRC)/check_permissions.$(ARCH).o \
+$(SRC)/ConfigInit.$(ARCH).o \
+$(SRC)/SetSignals.$(ARCH).o \
+$(SRC)/conversions.$(ARCH).o \
+$(SRC)/wimage.$(ARCH).o \
+$(SRC)/get2mass_as.$(ARCH).o
+
 EXTRA = \
 $(SRC)/bracket.$(ARCH).o \
@@ -74,13 +86,13 @@
 
 addstar                : $(BIN)/addstar.$(ARCH)
-
 $(BIN)/addstar.$(ARCH) : $(ADDSTAR)
-
 # $(ADDSTAR): $(INC)/addstar.h
-
-INSTALL = addstar
 
 gztest                : $(BIN)/gztest.$(ARCH)
 $(BIN)/gztest.$(ARCH) : $(SRC)/gztest.$(ARCH).o
+
+mkacc-2mass                : $(BIN)/mkacc-2mass.$(ARCH)
+$(BIN)/mkacc-2mass.$(ARCH) : $(MKACC-2MASS)
+mkacc-2mass.install        : $(DESTBIN)/mkacc-2mass
 
 INSTALL = addstar
Index: /trunk/Ohana/src/addstar/include/2mass.h
===================================================================
--- /trunk/Ohana/src/addstar/include/2mass.h	(revision 4299)
+++ /trunk/Ohana/src/addstar/include/2mass.h	(revision 4299)
@@ -0,0 +1,13 @@
+
+/* structure for data on a catalog region */
+typedef struct {
+  char filename[256];
+  double RA[2];
+  int Nrec;
+} TM_Region;
+
+short TM_J, TM_H, TM_K;
+
+GSCRegion *get2mass_acc (GSCRegion *patch, int *nfiles, char *path, char *accel);
+Stars *get2mass_2DR_data (GSCRegion *region, GSCRegion *patch, int *nstars);
+Stars *get2mass_AS_data (GSCRegion *region, GSCRegion *patch, int *nstars);
Index: /trunk/Ohana/src/addstar/include/addstar.h
===================================================================
--- /trunk/Ohana/src/addstar/include/addstar.h	(revision 4298)
+++ /trunk/Ohana/src/addstar/include/addstar.h	(revision 4299)
@@ -51,11 +51,4 @@
 } Stars;
 
-/* structure for data on a catalog region */
-typedef struct {
-  char filename[256];
-  double RA[2];
-  int Nrec;
-} TM_Region;
-
 enum {M_IMAGE, M_REFLIST, M_REFCAT};
 
@@ -66,5 +59,6 @@
 char   GSCFILE[256];
 char   CATDIR[256];
-char   TWO_MASS_DIR[256];
+char   TWO_MASS_DIR_AS[256];
+char   TWO_MASS_DIR_DR2[256];
 char   GSCDIR[256];
 char   CDROM[256];
@@ -99,4 +93,5 @@
 int DUMP_MATCHES;
 int ONLY_IMAGES;
+int EXISTING_REGIONS;
 int FORCE_READ;
 int SKYPROBE;
@@ -172,7 +167,5 @@
 **/
 
-Stars *get2mass (GSCRegion *patch, int *NSTARS);
-TM_Region *get2mass_acc (GSCRegion *patch, int *nfiles);
-Stars *get2mass_data (TM_Region *region, GSCRegion *patch, int *nstars);
+Stars *get2mass (GSCRegion *patch, int *NSTARS, int mode);
 GSCRegion *gregion_stars (Stars *stars, int Nstars, int *Nregion);
 Stars *grefstars (char *file, int *Nstars);
Index: /trunk/Ohana/src/addstar/src/ConfigInit.c
===================================================================
--- /trunk/Ohana/src/addstar/src/ConfigInit.c	(revision 4298)
+++ /trunk/Ohana/src/addstar/src/ConfigInit.c	(revision 4299)
@@ -33,5 +33,6 @@
   ScanConfig (config, "ADDSTAR_YMAX",           "%d",  0, &YMAX);
 
-  ScanConfig (config, "2MASS_DIR",              "%s",  0, TWO_MASS_DIR);
+  ScanConfig (config, "2MASS_DIR_AS",           "%s",  0, TWO_MASS_DIR_AS);
+  ScanConfig (config, "2MASS_DIR_DR2",          "%s",  0, TWO_MASS_DIR_DR2);
   ScanConfig (config, "GSCDIR",                 "%s",  0, GSCDIR);
   ScanConfig (config, "USNO_CDROM",             "%s",  0, CDROM);
Index: /trunk/Ohana/src/addstar/src/RegionOps.c
===================================================================
--- /trunk/Ohana/src/addstar/src/RegionOps.c	(revision 4298)
+++ /trunk/Ohana/src/addstar/src/RegionOps.c	(revision 4299)
@@ -88,4 +88,8 @@
     Nregions ++;
   }
+  if (Nregions > Ny + 2) {
+    fprintf (stderr, "ERROR: too many regions\n");
+    exit (2);
+  }
 
   sort_regions (regions, Nregions);
@@ -114,4 +118,6 @@
   int N, Nlo, Nhi;
   double D0, D1;
+
+  if (dec <= 90) return (0);
 
   /* D0, D1 are upper lower band boundaries */
@@ -147,4 +153,6 @@
   double D0, D1;
 
+  if (dec >= 90) return (Nregion - 1);
+
   /* D0, D1 are upper lower band boundaries */
   /* all regions in this band have DEC[0] < D1 */
Index: /trunk/Ohana/src/addstar/src/addstar.c
===================================================================
--- /trunk/Ohana/src/addstar/src/addstar.c	(revision 4298)
+++ /trunk/Ohana/src/addstar/src/addstar.c	(revision 4299)
@@ -41,7 +41,8 @@
     break;
   }
-  if (ONLY_MATCH) {
+  if (ONLY_MATCH || EXISTING_REGIONS) {
     regions = gregion_match (regions, &Nregions);
   }
+  if (VERBOSE) fprintf (stderr, "writing to %d regions\n", Nregions);
 
   Naverage = Nmeasure = 0;
Index: /trunk/Ohana/src/addstar/src/args.c
===================================================================
--- /trunk/Ohana/src/addstar/src/args.c	(revision 4298)
+++ /trunk/Ohana/src/addstar/src/args.c	(revision 4299)
@@ -4,9 +4,31 @@
 void help () {
 
-  fprintf (stderr, "USAGE: addstar (filename)\n");
+  fprintf (stderr, "USAGE\n");
+  fprintf (stderr, "  addstar (filename)\n");
+  fprintf (stderr, "     add specified image (cmp format) to database\n\n");
+  fprintf (stderr, "  addstar -ref (filename)");
+  fprintf (stderr, "     add ASCII data (ra dec mag dmag) to database\n\n");
+  fprintf (stderr, "  addstar -cat (catalog)");
+  fprintf (stderr, "     add data from catalog (USNO/2MASS/GSC) to database\n\n");
+
   fprintf (stderr, "  optional flags:\n");
-  fprintf (stderr, "  -v (verbose mode)\n");
-  fprintf (stderr, "  -p (photcode) - define the photcode\n");
-  fprintf (stderr, "\n"); 
+  fprintf (stderr, "  -region ra ra dec dec 	  : only add data in specified region (-ref mode only)\n");
+  fprintf (stderr, "  -p (photcode)         	  : specify photcode (override header)\n");
+  fprintf (stderr, "  -time (YYYY/MM/DD,HH:MM:SS) : specify date/time (override header)\n");
+  fprintf (stderr, "  -mosaic (filename)    	  : identify associated mosaic frame for chip image\n");
+  fprintf (stderr, "  -fits                 	  : input file is FITS table, not TEXT table\n");
+  fprintf (stderr, "  -existing-regions           : only add measurements to existing catalog files\n");
+  fprintf (stderr, "  -only-match           	  : only add measurements to existing objects\n");
+  fprintf (stderr, "  -missed               	  : skipped 'missed' entries\n");
+  fprintf (stderr, "  -replace              	  : replace time/photcode measurements (no duplication)\n");
+  fprintf (stderr, "  -image                	  : only insert image data\n");
+  fprintf (stderr, "  -cal                  	  : perform zero-point calibration\n");
+  fprintf (stderr, "  -skyprobe             	  : specify skyprobe mode\n");
+  fprintf (stderr, "  -accept               	  : accept bad astrometry from header\n");
+  fprintf (stderr, "  -force                	  : force read of database with inconsistent info\n");
+  fprintf (stderr, "  -v                    	  : verbose mode\n");
+  fprintf (stderr, "  -dump (mode)          	  : output test data\n");
+  fprintf (stderr, "  -help                 	  : this list\n");
+  fprintf (stderr, "  -h                    	  : this list\n\n");
   exit (2);
 }
@@ -99,4 +121,10 @@
   /*** modify behavior ***/
   /* only add to existing objects */
+  EXISTING_REGIONS = FALSE;
+  if ((N = get_argument (argc, argv, "-existing-regions"))) {
+    EXISTING_REGIONS = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+  /* only add to existing objects */
   ONLY_MATCH = FALSE;
   if ((N = get_argument (argc, argv, "-only-match"))) {
@@ -165,7 +193,4 @@
     fprintf (stderr, "USAGE: addstar -cat (catalog)\n");
     fprintf (stderr, "USAGE: addstar -ref (filename)\n");
-    fprintf (stderr, "  cur: %s ", argv[0]);
-    for (N = 0; N < argc; N++) { fprintf (stderr, "%s ", argv[N]); }
-    fprintf (stderr, "\n");  
     exit (2);
   }
Index: /trunk/Ohana/src/addstar/src/get2mass.c
===================================================================
--- /trunk/Ohana/src/addstar/src/get2mass.c	(revision 4298)
+++ /trunk/Ohana/src/addstar/src/get2mass.c	(revision 4299)
@@ -1,12 +1,12 @@
 # include "addstar.h"
+# include "2mass.h"
 
-static short TM_J, TM_H, TM_K;
-
-Stars *get2mass (GSCRegion *patch, int *NSTARS) {
+Stars *get2mass (GSCRegion *patch, int *NSTARS, int mode) {
   
+  char accel[64], *path;
   int i, Nstars, Nrefcat, Nregions; 
   Stars     *stars;
   Stars     *refcat;
-  TM_Region *regions;
+  GSCRegion *regions;
 
   NAMED_PHOTCODE (TM_J, "2MASS_J");
@@ -20,11 +20,23 @@
 
 good_code:
-  regions = get2mass_acc (patch, &Nregions);
+  path = TWO_MASS_DIR_AS;
+  if (mode == 1) path = TWO_MASS_DIR_DR2;
+
+  regions = get2mass_acc (patch, &Nregions, path, "accel.dat");
   
   Nstars = 0;
   ALLOCATE (stars, Stars, 1);
-  
+
   for (i = 0; i < Nregions; i++) {
-    refcat = get2mass_data (&regions[i], patch, &Nrefcat);
+    switch (mode) {
+      case 0:
+	refcat = get2mass_AS_data (&regions[i], patch, &Nrefcat);
+	if (VERBOSE) fprintf (stderr, "loaded %d stars from 2MASS (allsky)\n", Nrefcat);
+	break;
+      case 1:
+	refcat = get2mass_2DR_data (&regions[i], patch, &Nrefcat);
+	if (VERBOSE) fprintf (stderr, "loaded %d stars from 2MASS (dr2)\n", Nrefcat);
+	break;
+    }
 
     REALLOCATE (stars, Stars, MAX (1, Nstars + Nrefcat));
@@ -35,5 +47,5 @@
   }
   
-  if (VERBOSE) fprintf (stderr, "%d stars from 2MASS\n", Nstars);
+  if (VERBOSE) fprintf (stderr, "loaded total %d stars from 2MASS\n", Nstars);
   *NSTARS = Nstars;
   return (stars);
@@ -41,19 +53,19 @@
 
 /* watch for patch which cross 0,360 boundary */
-TM_Region *get2mass_acc (GSCRegion *patch, int *nregions) {
+GSCRegion *get2mass_acc (GSCRegion *patch, int *nregions, char *path, char *accel) {
 
   int Nregions, NREGIONS, Nrec;
-  TM_Region *regions;
-  char accel[1024], line[128], filename[128];
-  FILE     *f;
-  double Rs, Re;
+  GSCRegion *regions;
+  char accelfile[1024], line[256], filename[128];
+  FILE *f;
+  double Rs, Re, Ds, De;
 
-  sprintf (accel, "%s/idr2.acc", TWO_MASS_DIR);
-  f = fopen (accel, "r");
-  if (f == NULL) Shutdown ("can't read data from accelerator %s", accel);
+  sprintf (accelfile, "%s/%s", path, accel);
+  f = fopen (accelfile, "r");
+  if (f == NULL) Shutdown ("can't read data from accelerator %s", accelfile);
 
   Nregions = 0;
-  NREGIONS = 20;
-  ALLOCATE (regions, TM_Region, NREGIONS);
+  NREGIONS = 200;
+  ALLOCATE (regions, GSCRegion, NREGIONS);
 
   /* read in stars line-by-line */
@@ -62,114 +74,22 @@
     if (line[0] == 0) continue;
     if (line[0] == '#') continue;
-    sscanf (line, "%s %lf %lf %d", filename, &Rs, &Re, &Nrec);
+    sscanf (line, "%s %lf %lf %lf %lf", filename, &Rs, &Re, &Ds, &De);
     Rs *= 15.0;
     Re *= 15.0;
     if (Rs > patch[0].RA[1]) continue;
     if (Re < patch[0].RA[0]) continue;
-    sprintf (regions[Nregions].filename, "%s/%s", TWO_MASS_DIR, filename);
+    if (Ds > patch[0].DEC[1]) continue;
+    if (De < patch[0].DEC[0]) continue;
+    sprintf (regions[Nregions].filename, "%s/%s", path, filename);
     regions[Nregions].RA[0] = Rs;
     regions[Nregions].RA[1] = Re;
-    regions[Nregions].Nrec = Nrec;
+    regions[Nregions].DEC[0] = Ds;
+    regions[Nregions].DEC[1] = De;
     Nregions ++;
-    CHECK_REALLOCATE (regions, TM_Region, NREGIONS, Nregions, 20);
+    CHECK_REALLOCATE (regions, GSCRegion, NREGIONS, Nregions, 20);
   }    
+  fclose (f);
 
   *nregions = Nregions;
   return (regions);
 }
-
-# define NBYTE 302
-# define NLINE 30000
-
-Stars *get2mass_data (TM_Region *region, GSCRegion *patch, int *nstars) {
-  
-  int i, Nstars, NSTARS, Nbyte, Nline;
-  Stars *stars;
-  gzFile gf;
-  char *filename, buffer[NLINE*NBYTE];
-  double RA, DEC, J, H, K, dJ, dH, dK;
-  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) Shutdown ("can't read 2mass data file: %s", filename);
-
-  Nstars = 0;
-  NSTARS = 10000;
-  ALLOCATE (stars, Stars, NSTARS);
-
-  /* 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 ==  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++) {
-      
-      dparse (&RA,  1, &buffer[NBYTE*i+  0]);
-      dparse (&DEC, 2, &buffer[NBYTE*i+  0]);
-
-      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;
-      }
-      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 ++;
-      CHECK_REALLOCATE (stars, Stars, NSTARS, Nstars, 300);
-    }
-  }  
-finished:
-  gzclose (gf);
-
-  *nstars = Nstars;
-  return (stars);
-}
-
-    /* this just scans along in the file.  file is sorted by dec, so we 
-       should be skipping large chunks - but we would need to have
-       the size from the accel file (won't fit in GSCRegion) and need
-       to use gzseek, if it exists.
-    */
Index: /trunk/Ohana/src/addstar/src/get2mass_as.c
===================================================================
--- /trunk/Ohana/src/addstar/src/get2mass_as.c	(revision 4299)
+++ /trunk/Ohana/src/addstar/src/get2mass_as.c	(revision 4299)
@@ -0,0 +1,196 @@
+# include "addstar.h"
+# include "2mass.h"
+
+/* unlike the DR2 data, the AS data is NOT fixed bytes/row 
+ * we need to handle fractional lines at the end of each read block
+ */
+
+/* read in chunks of ~16MB */
+# define NBYTE 0x1000000
+
+char *skipNbounds (char *line, char bound, int Nbound, int Nbyte);
+void *memrchr(const void *s, int c, size_t n);
+e_time get2mass_time (char *ptr, char *buffer, int Nbound, int Nbyte);
+
+Stars *get2mass_AS_data (GSCRegion *region, GSCRegion *patch, int *nstars) {
+  
+  int FilterSkip, TimeSkip, Np;
+  int i, Nstars, NSTARS, Nbyte, Nline, Nextra, code;
+  Stars *stars;
+  gzFile gf;
+  char *buffer, *filename;
+  char *p, *q, *ptr, *end, *tmp;
+  char line[1000];
+  double RA, DEC, J, H, K, dJ, dH, dK, M, dM;
+  double RA0, RA1, DEC0, DEC1;
+  e_time time;
+
+  ALLOCATE (buffer, char, NBYTE);
+
+  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]);
+
+  code = thiscode[0].code;
+  FilterSkip = TimeSkip = 0;
+  if (thiscode[0].code == TM_J) {
+      FilterSkip = 6;
+      TimeSkip = 23;
+  }
+  if (thiscode[0].code == TM_H) {
+      FilterSkip = 10;
+      TimeSkip = 19;
+  }
+  if (thiscode[0].code == TM_K) {
+      FilterSkip = 14;
+      TimeSkip = 15;
+  }
+  if (!FilterSkip) Shutdown ("invalid photcode %d", thiscode[0].code);
+
+  filename = region[0].filename;
+  gf = gzopen (filename, "rb");
+  if (gf == NULL) Shutdown ("can't read 2mass data file: %s", filename);
+
+  Nstars = 0;
+  NSTARS = 10000;
+  ALLOCATE (stars, Stars, NSTARS);
+
+  Nextra = 0;
+  while ((Nbyte = gzread (gf, &buffer[Nextra], NBYTE-Nextra)) != 0) {
+    if (Nbyte == -1) Shutdown ("error reading from gzipped file %s", filename);
+    Nbyte += Nextra;
+
+    if (VERBOSE) fprintf (stderr, ".");
+
+    /* find bounds on first complete line */
+    p = buffer;
+    q = memchr (p, '\n', Nbyte);
+    if (q == NULL) Shutdown ("incomplete line at end of file\n");
+
+    while (1) {
+
+      RA = strtod (p, NULL);
+      ptr = skipNbounds (p, '|', 1, Nbyte - (p - buffer));
+      DEC = strtod (ptr, NULL);
+      if (DEC > 90) Shutdown ("weird DEC value: something is wrong");
+
+      /* this test is now wrong */
+      if (DEC > DEC1) goto skip_star;
+      if (DEC < DEC0) goto skip_star;
+      if (RA <  RA0)  goto skip_star;
+      if (RA >  RA1)  goto skip_star;
+
+      ptr = skipNbounds (p, '|', FilterSkip, Nbyte - (p - buffer));
+      if (ptr == NULL) Shutdown ("format error in 2mass");
+      M  = strtod (ptr, NULL);
+      ptr = skipNbounds (ptr, '|', 1, Nbyte - (ptr - buffer));
+      dM = strtod (ptr, NULL);
+      time = get2mass_time (ptr, buffer, TimeSkip, Nbyte);
+
+      stars[Nstars].R     = RA;
+      stars[Nstars].D     = DEC;
+      stars[Nstars].M     = M;
+      stars[Nstars].dM    = dM;
+      stars[Nstars].code  = code;
+      stars[Nstars].t     = time;
+      stars[Nstars].found = -1;
+
+      Nstars ++;
+      CHECK_REALLOCATE (stars, Stars, NSTARS, Nstars, 5000);
+
+    skip_star:
+      /* start of the next line */
+      tmp = p;
+      p = q + 1;
+      if (p - buffer == Nbyte) {
+	Nextra = 0;
+	break;
+      }
+      /* end of the next line */
+      q = memchr (p, '\n', Nbyte - (p - buffer));
+      if (q == NULL) {
+	Nextra = Nbyte - (p - buffer);
+	memmove (buffer, p, Nextra);
+	break;
+      } 
+    }
+  }
+  if (VERBOSE) fprintf (stderr, "\n");
+  
+finished:
+  gzclose (gf);
+  free (buffer);
+  *nstars = Nstars;
+  return (stars);
+}
+
+/* this just scans along in the file.  file is sorted by dec, so we 
+   should be skipping large chunks - but we would need to have
+   the size from the accel file (won't fit in GSCRegion) and need
+   to use gzseek, if it exists.
+*/
+/* 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);
+*/
+
+/* return a pointer to the first char after Nbound of value bound */
+char *skipNbounds (char *line, char bound, int Nbound, int Nbyte) {
+
+  int i;
+  char *p, *q;
+
+  p = line;
+  for (i = 0; i < Nbound; i++) {
+    q = memchr (p, bound, Nbyte - (p - line));
+    if (q == NULL) return (NULL);
+    p = q + 1;
+    if (p - line == Nbyte) return (NULL);
+  }
+  return (p);
+}
+  
+e_time get2mass_time (char *ptr, char *buffer, int Nbound, int Nbyte) {
+
+  e_time time;
+  char *p, *end;
+
+  p = skipNbounds (ptr, '|', Nbound, Nbyte - (ptr - buffer));
+  if (p == NULL) Shutdown ("format error in 2mass");
+  end = memchr (p, '|', Nbyte - (p - buffer));
+  if (end == NULL) Shutdown ("format error in 2mass");
+  *end = 0;
+  time = date_to_sec (ptr);
+  *end = '|';
+
+  return (time);
+}
+
+# if (0)
+    /** need to re-think this test **/
+    if (0) {
+      /* search for end of last complete line */
+      p = memrchr (buffer, '\n', Nbyte);
+      if (p == NULL) Shutdown ("incomplete line in at end of file\n");
+
+      /* search for start of last complete line */
+      /* last block may be only one line */
+      q = memrchr (buffer, '\n', (p - buffer - 1));
+      if (q == NULL) {
+	q = buffer;
+      } else {
+	q ++;
+      }
+
+      /* skip past block not yet in range */
+      RA = strtod (q, NULL);
+      ptr = skipNbounds (q, '|', 1, Nbyte - (q - buffer));
+      DEC = strtod (ptr, NULL);
+      if (DEC < DEC0) continue;
+    }
+
+# endif
Index: /trunk/Ohana/src/addstar/src/get2mass_dr2.c
===================================================================
--- /trunk/Ohana/src/addstar/src/get2mass_dr2.c	(revision 4299)
+++ /trunk/Ohana/src/addstar/src/get2mass_dr2.c	(revision 4299)
@@ -0,0 +1,111 @@
+# include "addstar.h"
+# include "2mass.h"
+
+# define NBYTE 302
+# define NLINE 30000
+
+Stars *get2mass_2DR_data (GSCRegion *region, GSCRegion *patch, int *nstars) {
+  
+  int i, Nstars, NSTARS, Nbyte, Nline;
+  Stars *stars;
+  gzFile gf;
+  char *buffer, *filename;
+  char line[303];
+  double RA, DEC, J, H, K, dJ, dH, dK;
+  double RA0, RA1, DEC0, DEC1;
+
+  ALLOCATE (buffer, char, (NBYTE*NLINE));
+
+  if (region == NULL) exit (2);
+  if (patch == NULL) exit (3);
+
+  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]);
+
+  fprintf (stderr, "overlap: %f - %f, %f - %f\n", RA0, RA1, DEC0, DEC1);
+
+  filename = region[0].filename;
+  gf = gzopen (filename, "rb");
+  if (gf == NULL) Shutdown ("can't read 2mass data file: %s", filename);
+
+  Nstars = 0;
+  NSTARS = 10000;
+  ALLOCATE (stars, Stars, NSTARS);
+
+  while ((Nbyte = gzread (gf, buffer, NLINE*NBYTE)) != 0) {
+    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;
+
+    memcpy (line, &buffer[NBYTE*(Nline-1)], NBYTE);
+    line[302] = 0;
+
+    for (i = 0; i < Nline; i++) {
+      
+      dparse (&RA,  1, &buffer[NBYTE*i+  0]);
+      dparse (&DEC, 2, &buffer[NBYTE*i+  0]);
+
+      /* dr2 is nicely sorted in dec order */
+      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;
+      }
+      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 ++;
+      CHECK_REALLOCATE (stars, Stars, NSTARS, Nstars, 5000);
+    }
+  }  
+finished:
+  gzclose (gf);
+  free (buffer);
+
+  *nstars = Nstars;
+  return (stars);
+}
+
+/* this just scans along in the file.  file is sorted by dec, so we 
+   should be skipping large chunks - but we would need to have
+   the size from the accel file (won't fit in GSCRegion) and need
+   to use gzseek, if it exists.
+*/
+/* 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);
+*/
+
Index: /trunk/Ohana/src/addstar/src/greference.c
===================================================================
--- /trunk/Ohana/src/addstar/src/greference.c	(revision 4298)
+++ /trunk/Ohana/src/addstar/src/greference.c	(revision 4299)
@@ -24,5 +24,15 @@
   /* get stars from 2MASS for the given region */
   if (!strcasecmp (Refcat, "2MASS")) {
-    stars = get2mass (catstats, &Nstars);
+    stars = get2mass (catstats, &Nstars, 0);
+  }
+  
+  /* get stars from 2MASS for the given region */
+  if (!strcasecmp (Refcat, "2MASS-ALLSKY")) {
+    stars = get2mass (catstats, &Nstars, 0);
+  }
+  
+  /* get stars from 2MASS for the given region */
+  if (!strcasecmp (Refcat, "2MASS-DR2")) {
+    stars = get2mass (catstats, &Nstars, 1);
   }
   
Index: /trunk/Ohana/src/addstar/src/gregion_patch.c
===================================================================
--- /trunk/Ohana/src/addstar/src/gregion_patch.c	(revision 4298)
+++ /trunk/Ohana/src/addstar/src/gregion_patch.c	(revision 4299)
@@ -28,4 +28,10 @@
   }
 
+  if (VERBOSE) fprintf (stderr, "Nregions in patch: %d, Ne: %d, Ns: %d\n", Nregions, Ne, Ns);
+  if (Nregions > (Ne - Ns)) {
+    fprintf (stderr, "ERROR: too many regions found\n");
+    exit (1);
+  }
+
   *nregions = Nregions;
   return (regions);
Index: /trunk/Ohana/src/addstar/src/gstars.c
===================================================================
--- /trunk/Ohana/src/addstar/src/gstars.c	(revision 4298)
+++ /trunk/Ohana/src/addstar/src/gstars.c	(revision 4299)
@@ -4,5 +4,5 @@
 
   FILE *f;
-  int j, N, extend, Nbytes;
+  int j, N, Nbytes;
   int itmp, hour, min;
   char *c, photcode[64], line[80];
Index: /trunk/Ohana/src/addstar/src/mkacc-2mass.c
===================================================================
--- /trunk/Ohana/src/addstar/src/mkacc-2mass.c	(revision 4299)
+++ /trunk/Ohana/src/addstar/src/mkacc-2mass.c	(revision 4299)
@@ -0,0 +1,68 @@
+# include "addstar.h"
+# include "2mass.h"
+
+int main (int argc, char **argv) {
+
+  int i, N, Nrefcat;
+  Stars *refcat;
+  GSCRegion *regions, accregion;
+
+  ConfigInit (&argc, argv);
+
+  /* override any header PHOTCODE values */
+  thiscode = NULL;
+  if ((N = get_argument (argc, argv, "-p"))) {
+    remove_argument (N, &argc, argv);
+    thiscode = GetPhotcodebyName (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  if (argc != 2) {
+    fprintf (stderr, "USAGE: mkacc.2mass (file)\n");
+    exit (2);
+  }
+
+  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:
+  UserPatch.RA[0] = 0;
+  UserPatch.RA[1] = 360;
+  UserPatch.DEC[0] = -90;
+  UserPatch.DEC[1] = +90;
+
+  ALLOCATE (regions, GSCRegion, 1);
+  strcpy (regions[0].filename, argv[1]);
+  regions[0].RA[0] = 0;
+  regions[0].RA[1] = 360;
+  regions[0].DEC[0] = -90;
+  regions[0].DEC[1] = +90;
+
+  refcat = get2mass_AS_data (regions, &UserPatch, &Nrefcat);
+
+  /* find upper and lower file limits in RA and DEC */
+
+  strcpy (accregion.filename, regions[0].filename);
+  accregion.RA[0]  = 360;
+  accregion.RA[1]  =   0;
+  accregion.DEC[0] = +90;
+  accregion.DEC[1] = -90;
+
+  for (i = 0; i < Nrefcat; i++) {
+    accregion.RA[0]  = MIN (refcat[i].R, accregion.RA[0]);
+    accregion.RA[1]  = MAX (refcat[i].R, accregion.RA[1]);
+    accregion.DEC[0] = MIN (refcat[i].D, accregion.DEC[0]);
+    accregion.DEC[1] = MAX (refcat[i].D, accregion.DEC[1]);
+  }
+
+  fprintf (stderr, "%s %10.6f %10.6f  %10.6f %10.6f  %d\n", 
+	   accregion.filename, accregion.RA[0]/15.0, accregion.RA[1]/15.0, accregion.DEC[0], accregion.DEC[1], Nrefcat);
+
+  exit (0);
+}
Index: /trunk/Ohana/src/addstar/src/rfits.c
===================================================================
--- /trunk/Ohana/src/addstar/src/rfits.c	(revision 4298)
+++ /trunk/Ohana/src/addstar/src/rfits.c	(revision 4299)
@@ -3,5 +3,5 @@
 Stars *rfits (FILE *f, int *nstars) {
 
-  int i, Nx, Ny, Nstars;
+  int i, Nstars;
   Header theader;
   FTable table;
