Index: /trunk/Ohana/src/gastro2/include/gastro2.h
===================================================================
--- /trunk/Ohana/src/gastro2/include/gastro2.h	(revision 6241)
+++ /trunk/Ohana/src/gastro2/include/gastro2.h	(revision 6242)
@@ -113,4 +113,5 @@
 int NPOLYTERMS;
 char CDROM[256];
+char USNO_B_DIR[256];
 char CATDIR[256];
 char   CATMODE[16];    /* raw, mef, split, mysql */
Index: /trunk/Ohana/src/gastro2/src/ConfigInit.c
===================================================================
--- /trunk/Ohana/src/gastro2/src/ConfigInit.c	(revision 6241)
+++ /trunk/Ohana/src/gastro2/src/ConfigInit.c	(revision 6242)
@@ -41,4 +41,5 @@
   ScanConfig (config, "LONEOS_REGIONS",    "%s",  0, LONEOS_REGION_FILE);
   ScanConfig (config, "USNO_CDROM",        "%s",  0, CDROM);
+  ScanConfig (config, "USNO_B_DIR",        "%s",  0, USNO_B_DIR);
   ScanConfig (config, "ASTRO_REFCAT",      "%s",  0, REFCAT);
   ScanConfig (config, "CATDIR",            "%s",  0, CATDIR);
Index: /trunk/Ohana/src/gastro2/src/getusno.c
===================================================================
--- /trunk/Ohana/src/gastro2/src/getusno.c	(revision 6241)
+++ /trunk/Ohana/src/gastro2/src/getusno.c	(revision 6242)
@@ -110,4 +110,5 @@
 	  stars[Nusno].R = buf[0]/360000.0;
 	  stars[Nusno].D = buf[1]/360000.0 - 90.0;
+	  /* note that this is the RED mag */
 	  stars[Nusno].M = fabs (0.1*(buf[2] - 1000*((int)(buf[2]/1000))));
 	  /* b = 0.1*((int)(buf[2] - 1000000*((int)(buf[2]/1000000))) / 1000); */
Index: /trunk/Ohana/src/gastro2/src/getusnob.c
===================================================================
--- /trunk/Ohana/src/gastro2/src/getusnob.c	(revision 6242)
+++ /trunk/Ohana/src/gastro2/src/getusnob.c	(revision 6242)
@@ -0,0 +1,166 @@
+# include "gastro2.h"
+# define NZONE 180
+
+int getusno (CatStats *catstats, RefCatalog *Ref, double epoch) {
+
+  long int offset;
+  int i, bin, first, last, nitems, Nitems, Nbins;
+  float hours[100];
+  int start[100], number[100], *buffer, *ibuf;
+  char filename[128], c, *cbuf;
+  FILE *f;
+  double DEC1;
+  int iDEC0, iDEC1, iRA0, iRA1;
+  int spd, spd_start, spd_end, disk;
+  int NUSNO, Nusno;
+  StarData *stars;
+
+  /* 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 that DEC is in SPD, while both have units to 0.01 degrees */
+  
+  /* data is organized in south-pole distance zones, 1 deg per direction, 0.1 deg per file */
+  spd_start = (int)(10*(catstats[0].DEC[0] + 90));
+  DEC1 = 10*(catstats[0].DEC[1] + 90);
+  if (DEC1 > (int)(DEC1)) {
+    spd_end =   (int)(1 + 10*(catstats[0].DEC[1] + 90));
+  } else {
+    spd_end =   (int)(0 + 10*(catstats[0].DEC[1] + 90));
+  }
+
+  Nusno = 0;
+  NUSNO = 5000;
+  ALLOCATE (stars, StarData, NUSNO);
+
+  for (spd = spd_start; spd < spd_end; spd ++) {
+    
+    /* load accelerator file */
+    sprintf (filename, "%s/%03d/b%04d.acc", USNO_B_DIR, (int)(spd/10), spd); 
+    fprintf (stderr, "reading from %s\n", filename);
+    f = fopen (filename, "r");
+    if (f == (FILE *) NULL) {
+      fprintf (stderr, "can't open file %s, is cdrom %d in drive?\n", filename, disk);
+      fprintf (stderr, "press return when ready to continue: ");
+      fscanf (stdin, "%c", &c);
+      fprintf (stderr, "trying again...\n");
+      f = fopen (filename, "r");
+      if (f == (FILE *) NULL) {
+	fprintf (stderr, "ERROR: can't open file %s, is cdrom %d in drive?\n", filename, disk);
+	exit (1);  
+      }
+    }
+    for (i = 0; fscanf (f, "%f %d %d", &hours[i], &start[i], &number[i]) != EOF; i++);
+    Nbins = i;
+    fclose (f);
+    
+    first = catstats[0].RA[0] / 3.75;
+    if ((catstats[0].RA[1] / 3.75) == (int) (catstats[0].RA[1] / 3.75)) 
+      last  = catstats[0].RA[1] / 3.75;
+    else 
+      last  = 1 + catstats[0].RA[1] / 3.75;
+
+    if ((first > Nbins) || (last > Nbins)) {
+      fprintf (stderr, "ERROR: RA out of range\n");
+      exit (1);
+    }
+    
+    /* open data file */
+    sprintf (filename, "%s/zone%04d.cat", CDROM, spd);
+    fprintf (stderr, "reading from %s\n", filename);
+    f = fopen (filename, "r");
+    if (f == (FILE *) NULL) {
+      fprintf (stderr, "ERROR: can't open file %s\n", filename);
+      exit (1);
+    }
+
+    /* advance file pointer to first slice */
+    /**** 80 is record-length for USNO-B ****/
+    offset = 80*sizeof(int)*(start[first] - 1);
+    fseek (f, offset, SEEK_SET);
+
+    /* sum the number of stars in data segment of interest */
+    Nstars = 0;
+    for (bin = first; bin < last; bin++) {
+      Nstars += number[bin];
+    }
+    Nitems = 80*Nstars/4;  /* number of integer blocks; need to use Fread for byte-swapping read */
+
+    /* allocate space for stars in segment */
+    ALLOCATE (buffer, int, Nitems);
+    nitems = Fread (buffer, sizeof(int), Nitems, f, "int");
+    if (nitems != Nitems) {
+      fprintf (stderr, "ERROR: failure reading data from file %s\n", filename);
+      exit (1);
+    }
+
+    ibuf = buffer;
+    /* print out data from slice within RA and DEC range */
+    for (i = 0; i < Nstars; i++, buf+=80) {
+      if (buf[0] < iRA0) continue;
+      if (buf[0] > iRA1) continue;
+      if (buf[1] < iDEC0) continue;
+      if (buf[1] > iDEC1) continue;
+      
+      stars[Nusno].R = buf[0]/360000.0;
+      stars[Nusno].D = buf[1]/360000.0 - 90.0;
+      
+      uR = (buf[2] % 10000) / 3600.0 * 0.002;
+      uD = ((buf[2] / 10000) % 10000) / 3600.0 * 0.002;
+
+      /* 1st blue mag */
+      mB1 = 0.01 * (buf[5] % 10000);
+      /* 1st blue mag */
+      mB2 = 0.01 * (buf[6] % 10000);
+      /* 1st blue mag */
+      mR1 = 0.01 * (buf[7] % 10000);
+      /* 1st blue mag */
+      mR2 = 0.01 * (buf[8] % 10000);
+
+      if (mB1 && mB2) {
+	mB = 0.5*(mB1 + mB2);
+      } else {
+	mB = (mB1) ? mB1 : mB2;
+      }
+
+      if (mR1 && mR2) {
+	mR = 0.5*(mR1 + mR2);
+      } else {
+	mR = (mR1) ? mR1 : mR2;
+      }
+      
+      stars[Nusno].M = mB;
+      stars[Nusno].R += uR*(epoch - 2000.0);
+      stars[Nusno].D += uD*(epoch - 2000.0);
+
+      Nusno ++;
+      if (Nusno == NUSNO) {
+	NUSNO += 5000;
+	REALLOCATE (stars, StarData, NUSNO);
+      }	  
+      free (buffer);
+    }
+    fclose (f);
+  }
+
+  area_of_region (catstats);
+
+  REALLOCATE (stars, StarData, MAX (1, Nusno));
+
+  Ref[0].stars = stars;
+  Ref[0].N     = Nusno;
+  Ref[0].R0    = catstats[0].RA[0];
+  Ref[0].R1    = catstats[0].RA[1];
+  Ref[0].D0    = catstats[0].DEC[0];
+  Ref[0].D1    = catstats[0].DEC[1];
+  Ref[0].Area  = catstats[0].Area;
+
+  get_luminosity_func (Ref[0].stars, Ref[0].N, &Ref[0].lum);
+  
+  if (VERBOSE) fprintf (stderr, "%d stars from USNO 1.0\n", Nusno);
+  return (TRUE);
+}
+
+
Index: /trunk/Ohana/src/gastro2/src/greference2.c
===================================================================
--- /trunk/Ohana/src/gastro2/src/greference2.c	(revision 6241)
+++ /trunk/Ohana/src/gastro2/src/greference2.c	(revision 6242)
@@ -13,4 +13,10 @@
   if (!strcmp (REFCAT, "USNO")) {
     getusno (&catstats, Ref);
+    /* calculate Ref[0].Moff from Target & Ref dMdN, Mo */
+  }
+
+  /* get stars from the USNO B catalog for the given region */
+  if (!strcmp (REFCAT, "USNOB")) {
+    getusnob (&catstats, Ref, EPOCH);
     /* calculate Ref[0].Moff from Target & Ref dMdN, Mo */
   }
Index: /trunk/Ohana/src/mosastro/Makefile
===================================================================
--- /trunk/Ohana/src/mosastro/Makefile	(revision 6241)
+++ /trunk/Ohana/src/mosastro/Makefile	(revision 6242)
@@ -42,4 +42,5 @@
 $(SRC)/gcatalog.$(ARCH).o \
 $(SRC)/getusno.$(ARCH).o \
+$(SRC)/getusnob.$(ARCH).o \
 $(SRC)/wstars.$(ARCH).o \
 $(SRC)/field.$(ARCH).o \
Index: /trunk/Ohana/src/mosastro/include/mosastro.h
===================================================================
--- /trunk/Ohana/src/mosastro/include/mosastro.h	(revision 6241)
+++ /trunk/Ohana/src/mosastro/include/mosastro.h	(revision 6242)
@@ -89,4 +89,5 @@
 char StoneRegions[256];
 char CDROM[256];
+char USNO_B_DIR[256];
 char REFCAT[256];
 char CATDIR[256];
@@ -162,4 +163,5 @@
 StarData  *getstone           PROTO((CatStats *input, int *nstars));
 StarData  *getusno            PROTO((CatStats *catstats, int *Nstars));
+StarData  *getusnob           PROTO((CatStats *catstats, int *Nstars));
 StarData  *gptolemy           PROTO((char *filename, int *NSTARS));
 StarData  *greference         PROTO((int *Nrefcat));
Index: /trunk/Ohana/src/mosastro/src/ConfigInit.c
===================================================================
--- /trunk/Ohana/src/mosastro/src/ConfigInit.c	(revision 6241)
+++ /trunk/Ohana/src/mosastro/src/ConfigInit.c	(revision 6242)
@@ -26,4 +26,5 @@
   ScanConfig (config, "GSCDIR",           "%s",  0, GSC_DIR);
   ScanConfig (config, "STONE_DIR",        "%s",  0, StoneRegions);
+  ScanConfig (config, "USNO_B_DIR",       "%s",  0, USNO_B_DIR);
 
   /* abstracted header keywords */
Index: /trunk/Ohana/src/mosastro/src/getusnob.c
===================================================================
--- /trunk/Ohana/src/mosastro/src/getusnob.c	(revision 6242)
+++ /trunk/Ohana/src/mosastro/src/getusnob.c	(revision 6242)
@@ -0,0 +1,154 @@
+# include "mosastro.h"
+
+StarData *getusnob (CatStats *catstats, int *Nstars) {
+
+  long int offset;
+  int i, bin, first, last, nitems, Nitems, Nbins;
+  float hours[100];
+  int start[100], number[100], *buffer, *buf;
+  char filename[128], c;
+  FILE *f;
+  double DEC1;
+  double uR, uD;
+  float mB1, mB2, mR1, mR2, mB, mR;
+  int iDEC0, iDEC1, iRA0, iRA1;
+  int spd, spd_start, spd_end, disk;
+  int NUSNO, Nusno, nstars;
+  StarData *stars;
+
+  /* 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 that DEC is in SPD, while both have units to 0.01 degrees */
+  
+  /* data is organized in south-pole distance zones, 1 deg per direction, 0.1 deg per file */
+  spd_start = (int)(10*(catstats[0].DEC[0] + 90));
+  DEC1 = 10*(catstats[0].DEC[1] + 90);
+  if (DEC1 > (int)(DEC1)) {
+    spd_end =   (int)(1 + 10*(catstats[0].DEC[1] + 90));
+  } else {
+    spd_end =   (int)(0 + 10*(catstats[0].DEC[1] + 90));
+  }
+
+  Nusno = 0;
+  NUSNO = 5000;
+  ALLOCATE (stars, StarData, NUSNO);
+
+  for (spd = spd_start; spd < spd_end; spd ++) {
+    
+    /* load accelerator file */
+    sprintf (filename, "%s/%03d/b%04d.acc", USNO_B_DIR, (int)(spd/10), spd); 
+    fprintf (stderr, "reading from %s\n", filename);
+    f = fopen (filename, "r");
+    if (f == (FILE *) NULL) {
+      fprintf (stderr, "can't open file %s, is cdrom %d in drive?\n", filename, disk);
+      fprintf (stderr, "press return when ready to continue: ");
+      fscanf (stdin, "%c", &c);
+      fprintf (stderr, "trying again...\n");
+      f = fopen (filename, "r");
+      if (f == (FILE *) NULL) {
+	fprintf (stderr, "ERROR: can't open file %s, is cdrom %d in drive?\n", filename, disk);
+	exit (1);  
+      }
+    }
+    for (i = 0; fscanf (f, "%f %d %d", &hours[i], &start[i], &number[i]) != EOF; i++);
+    Nbins = i;
+    fclose (f);
+    
+    first = catstats[0].RA[0] / 3.75;
+    if ((catstats[0].RA[1] / 3.75) == (int) (catstats[0].RA[1] / 3.75)) 
+      last  = catstats[0].RA[1] / 3.75;
+    else 
+      last  = 1 + catstats[0].RA[1] / 3.75;
+
+    if ((first > Nbins) || (last > Nbins)) {
+      fprintf (stderr, "ERROR: RA out of range\n");
+      exit (1);
+    }
+    
+    /* open data file */
+    /* sprintf (filename, "%s/zone%04d.cat", CDROM, spd); */
+    sprintf (filename, "%s/%03d/b%04d.cat", USNO_B_DIR, (int)(spd/10), spd); 
+    fprintf (stderr, "reading from %s\n", filename);
+    f = fopen (filename, "r");
+    if (f == (FILE *) NULL) {
+      fprintf (stderr, "ERROR: can't open file %s\n", filename);
+      exit (1);
+    }
+
+    /* advance file pointer to first slice */
+    /**** 4*20 is record-length for USNO-B ****/
+    offset = 20*sizeof(int)*(start[first] - 1);
+    fseek (f, offset, SEEK_SET);
+
+    /* sum the number of stars in data segment of interest */
+    nstars = 0;
+    for (bin = first; bin < last; bin++) {
+      nstars += number[bin];
+    }
+    Nitems = 20*nstars;  /* number of integer blocks; need to use Fread for byte-swapping read */
+
+    /* allocate space for stars in segment */
+    ALLOCATE (buffer, int, Nitems);
+    // data has the WRONG byte order?
+    // nitems = Fread (buffer, sizeof(int), Nitems, f, "int");
+    nitems = fread (buffer, sizeof(int), Nitems, f);
+    if (nitems != Nitems) {
+      fprintf (stderr, "ERROR: failure reading data from file %s\n", filename);
+      exit (1);
+    }
+
+    buf = buffer;
+    /* print out data from slice within RA and DEC range */
+    for (i = 0; i < nstars; i++, buf+=20) {
+      if (buf[0] < iRA0) continue;
+      if (buf[0] > iRA1) continue;
+      if (buf[1] < iDEC0) continue;
+      if (buf[1] > iDEC1) continue;
+      
+      bzero (&stars[Nusno], sizeof(StarData));
+      stars[Nusno].R = buf[0]/360000.0;
+      stars[Nusno].D = buf[1]/360000.0 - 90.0;
+      
+      uR = (buf[2] % 10000);
+      uR = (uR - 5000.0) * 0.002 / 3600.0;
+      uD = ((buf[2] / 10000) % 10000);
+      uD = (uD - 5000.0) * 0.002 / 3600.0;
+
+      /* 1st blue mag */
+      mB1 = 0.01 * (buf[5] % 10000);
+      /* 1st blue mag */
+      mB2 = 0.01 * (buf[6] % 10000);
+      /* 1st blue mag */
+      mR1 = 0.01 * (buf[7] % 10000);
+      /* 1st blue mag */
+      mR2 = 0.01 * (buf[8] % 10000);
+
+      if (mB1 && mB2) {
+	mB = 0.5*(mB1 + mB2);
+      } else {
+	mB = (mB1) ? mB1 : mB2;
+      }
+
+      if (mR1 && mR2) {
+	mR = 0.5*(mR1 + mR2);
+      } else {
+	mR = (mR1) ? mR1 : mR2;
+      }
+      
+      stars[Nusno].M = mB;
+      stars[Nusno].R += uR*(Year - 2000.0);
+      stars[Nusno].D += uD*(Year - 2000.0);
+      Nusno ++;
+      CHECK_REALLOCATE (stars, StarData, NUSNO, Nusno, 5000);
+    }
+    free (buffer);
+    fclose (f);
+  }
+  
+  *Nstars = Nusno;
+  if (VERBOSE) fprintf (stderr, "%d stars from USNO B1.0\n", Nusno);
+  return (stars);
+}
Index: /trunk/Ohana/src/mosastro/src/greference.c
===================================================================
--- /trunk/Ohana/src/mosastro/src/greference.c	(revision 6241)
+++ /trunk/Ohana/src/mosastro/src/greference.c	(revision 6242)
@@ -28,4 +28,9 @@
   }
 
+  /* get stars from the USNO A catalog for the given region */
+  if (!strcmp (REFCAT, "USNOB")) {
+    stars = getusnob (&catstats, &Nstars);
+  }
+
   /* get stars from the HST GSC catalog for the given region */
   if (!strcmp (REFCAT, "GSC")) {
