Index: /trunk/Ohana/src/addstar/include/WISE.h
===================================================================
--- /trunk/Ohana/src/addstar/include/WISE.h	(revision 42145)
+++ /trunk/Ohana/src/addstar/include/WISE.h	(revision 42146)
@@ -21,8 +21,8 @@
 short WISE_W1, WISE_W2, WISE_W3, WISE_W4;
 
-enum {MODE_NONE, MODE_ALLWISE, MODE_ALLSKY, MODE_PRELIM};
+enum {MODE_NONE, MODE_CATWISE, MODE_ALLWISE, MODE_ALLSKY, MODE_PRELIM};
 int MODE;
 
-AddstarClientOptions args_loadwise (int argc, char **argv, AddstarClientOptions options);
+AddstarClientOptions args_loadwise (int *argc, char **argv, AddstarClientOptions options);
 
 int loadwise_rawdata (SkyList *skytable, char *filename, AddstarClientOptions options);
@@ -38,5 +38,5 @@
 int loadwise_star_allsky  (Measure *measure, char *line, int Nmax);
 int loadwise_star_allwise (Measure *measure, char *line, int Nmax);
-
+int loadwise_star_catwise (Measure *measure, char *line, int Nmax, double Rs, double Ds);
 
 char *nextWISEfield (char *line);
@@ -49,4 +49,12 @@
 int setWISE_dup_flag (Measure *measure, char qual);
 int setWISE_use_flag (Measure *measure, char qual);
+int setWISE_sat_flag (Measure *measure, char *ptr);
+
+int setCatWISE_sat_flag (Measure *measure, char *ptr, int start, int end);
+int setCatWISE_blend_flag (Measure *measure, char *line);
 
 char *skipNbounds (char *line, char bound, int Nbound, int Nbyte);
+
+char *getLineSegment (char *line, int start, int end);
+double getDoubleRAW (char *line, int start, int end);
+double getDoubleNAN (char *line, int start, int end);
Index: /trunk/Ohana/src/addstar/src/args_loadwise.c
===================================================================
--- /trunk/Ohana/src/addstar/src/args_loadwise.c	(revision 42145)
+++ /trunk/Ohana/src/addstar/src/args_loadwise.c	(revision 42146)
@@ -3,11 +3,11 @@
 static void help (void);
 
-AddstarClientOptions args_loadwise (int argc, char **argv, AddstarClientOptions options) {
+AddstarClientOptions args_loadwise (int *argc, char **argv, AddstarClientOptions options) {
   
   int N;
 
   /* check for help request */
-  if (get_argument (argc, argv, "-help") ||
-      get_argument (argc, argv, "-h")) {
+  if (get_argument (*argc, argv, "-help") ||
+      get_argument (*argc, argv, "-h")) {
     help ();
   }
@@ -29,33 +29,33 @@
   /* only add to existing regions */
   options.existing_regions = FALSE;
-  if ((N = get_argument (argc, argv, "-existing-regions"))) {
+  if ((N = get_argument (*argc, argv, "-existing-regions"))) {
     options.existing_regions = TRUE;
-    remove_argument (N, &argc, argv);
+    remove_argument (N, argc, argv);
   }
   /* only add to existing objects */
   options.only_match = FALSE;
-  if ((N = get_argument (argc, argv, "-only-match"))) {
+  if ((N = get_argument (*argc, argv, "-only-match"))) {
     options.only_match = TRUE;
-    remove_argument (N, &argc, argv);
+    remove_argument (N, argc, argv);
   }
   /* replace measurement, don't duplicate (ref/cat only) */
   options.replace = FALSE;
-  if ((N = get_argument (argc, argv, "-replace"))) {
+  if ((N = get_argument (*argc, argv, "-replace"))) {
     options.replace = TRUE;
-    remove_argument (N, &argc, argv);
+    remove_argument (N, argc, argv);
   }
 
   /* extra error messages */
   VERBOSE = FALSE;
-  if ((N = get_argument (argc, argv, "-v"))) {
+  if ((N = get_argument (*argc, argv, "-v"))) {
     VERBOSE = TRUE;
-    remove_argument (N, &argc, argv);
+    remove_argument (N, argc, argv);
   }
 
   /* load the prelim data dump */
-  MODE = MODE_ALLWISE;
-  if ((N = get_argument (argc, argv, "-mode"))) {
-    MODE = MODE_NONE;
-    remove_argument (N, &argc, argv);
+  MODE = MODE_NONE;
+  if ((N = get_argument (*argc, argv, "-mode"))) {
+    remove_argument (N, argc, argv);
+    if (!strcasecmp(argv[N], "catwise")) MODE = MODE_CATWISE;
     if (!strcasecmp(argv[N], "allwise")) MODE = MODE_ALLWISE;
     if (!strcasecmp(argv[N], "allsky"))  MODE = MODE_ALLSKY;
@@ -65,5 +65,5 @@
       exit (2);
     }
-    remove_argument (N, &argc, argv);
+    remove_argument (N, argc, argv);
   }
 
@@ -85,5 +85,5 @@
   DUMP = NULL;
 
-  if (argc < 2) {
+  if (*argc < 2) {
     fprintf (stderr, "USAGE: loadwise [options] (wisefile) [..more files]\n");
     exit (2);
@@ -94,6 +94,8 @@
 static void help () {
 
-  fprintf (stderr, "USAGE: loadwise [options] (wisefile) [..more files]\n");
+  fprintf (stderr, "USAGE: loadwise [-mode MODE] [options] (wisefile) [..more files]\n");
   fprintf (stderr, "  add data from WISE catalog to DVO\n\n");
+
+  fprintf (stderr, "  MODE may be : catwise, allwise, allsky, prelim\n");
 
   fprintf (stderr, "  optional flags:\n");
Index: /trunk/Ohana/src/addstar/src/loadwise.c
===================================================================
--- /trunk/Ohana/src/addstar/src/loadwise.c	(revision 42145)
+++ /trunk/Ohana/src/addstar/src/loadwise.c	(revision 42146)
@@ -22,5 +22,5 @@
   SetSignals ();
   options = ConfigInit (&argc, argv);
-  options = args_loadwise (argc, argv, options);
+  options = args_loadwise (&argc, argv, options);
 
   // load the full sky description table:
Index: /trunk/Ohana/src/addstar/src/loadwise_ops.c
===================================================================
--- /trunk/Ohana/src/addstar/src/loadwise_ops.c	(revision 42145)
+++ /trunk/Ohana/src/addstar/src/loadwise_ops.c	(revision 42146)
@@ -17,8 +17,14 @@
   char *ptr = line;
 
-  ptr = skipNbounds (ptr, '|', 1, Nmax);
-  *R = strtod (ptr, NULL);
-  ptr = skipNbounds (ptr, '|', 1, Nmax);
-  *D = strtod (ptr, NULL);
+  if (MODE == MODE_CATWISE) {
+      // copy the string ranges and then use strtod (not necessary?)
+      *R = strtod (&ptr[47], NULL); // safe to use the strtod on the line because it is white-space separated
+      *D = strtod (&ptr[59], NULL);
+  } else {
+      ptr = skipNbounds (ptr, '|', 1, Nmax);
+      *R = strtod (ptr, NULL);
+      ptr = skipNbounds (ptr, '|', 1, Nmax);
+      *D = strtod (ptr, NULL);
+  }
   if (*D > 90) Shutdown ("weird DEC value: something is wrong");
 
@@ -91,4 +97,27 @@
 }
   
+/* return a pointer to the first char after Nbound of value bound */
+char *getLineSegment (char *line, int start, int end) {
+
+  // do NOT damage the buffer by seting the end byte to NULL
+  if (0) { line[end] = 0; }
+  char *ptr = &line[start];
+  return (ptr);
+}
+  
+double getDoubleRAW (char *line, int start, int end) {
+    char *ptr = getLineSegment(line, start, end);
+    double value = strtod (ptr, NULL);
+    return value;
+}
+
+double getDoubleNAN (char *line, int start, int end) {
+    char *endpoint = NULL;
+    char *ptr = getLineSegment(line, start, end);
+    double value = strtod (ptr, &endpoint);
+    if (endpoint == ptr) { value = NAN; }
+    return value;
+}
+
 /* watch for patches which cross 0,360 boundary */
 SkyTable *loadWISE_acc (char *path, char *accel) {
Index: /trunk/Ohana/src/addstar/src/loadwise_rawdata.c
===================================================================
--- /trunk/Ohana/src/addstar/src/loadwise_rawdata.c	(revision 42145)
+++ /trunk/Ohana/src/addstar/src/loadwise_rawdata.c	(revision 42146)
@@ -28,4 +28,6 @@
   getWISE_setup ();
 
+  int NMeasPerStar = (MODE == MODE_CATWISE) ? 2 : 4;
+
   ALLOCATE (buffer, char, NBYTE);
 
@@ -34,4 +36,6 @@
   if (f == NULL) Shutdown ("can't read WISE data file: %s", filename);
   // test if this is a raw datafile or gzipped...
+
+  int skipHeader = TRUE;
 
   Nextra = 0;  // number excess bytes from lsat partial row
@@ -59,6 +63,18 @@
     Dmax = -90.0;
 
+    // XXX buffer is being reread instead of continuing.
+
     // scan through entire buffer for star coords
     while (1) {
+
+      if (skipHeader && (MODE == MODE_CATWISE)) {
+	if (*p == '\\') goto skip_header;
+	if (*p == '|') goto skip_header;
+      }
+      if (skipHeader && (MODE == MODE_CATWISE)) {
+	// once we get past the header, do not skip any more
+	skipHeader = FALSE;
+      }
+
       getWISE_coords (p, &tstars[Ntstars].R, &tstars[Ntstars].D, Nbyte - offset);
       tstars[Ntstars].offset = offset; // offset within scan
@@ -74,4 +90,6 @@
       Ntstars ++;
       CHECK_REALLOCATE (tstars, WISE_Stars, NTSTARS, Ntstars, 10000);
+
+    skip_header:
 
       /* start of the next line */
@@ -143,8 +161,9 @@
 	if (tstars[j].D > UserPatch.Dmax) continue;
 	  
+	// offset is bytes to start of line from start of buffer
 	offset = tstars[j].offset;
 
 	dvo_average_init (&newcat->average[Nave]);
-	for (k = 0; k < 4; k++) {
+	for (k = 0; k < NMeasPerStar; k++) {
 	  dvo_measure_init (&newcat->measure[Nmeas+k]);
 	}
@@ -163,4 +182,7 @@
 	    loadwise_star_allwise (&newcat->measure[Nmeas], &buffer[offset], Nbyte - offset);
 	    break;
+	  case MODE_CATWISE:
+	    loadwise_star_catwise (&newcat->measure[Nmeas], &buffer[offset], Nbyte - offset, tstars[j].R, tstars[j].D);
+	    break;
 	  default:
 	    break;
@@ -169,9 +191,9 @@
 	tstars[j].flag = TRUE;
 
-	newcat->average[Nave].Nmeasure = 4;
+	newcat->average[Nave].Nmeasure = NMeasPerStar;
 	newcat->average[Nave].measureOffset = Nmeas;
 
 	Nave ++;
-	Nmeas += 4;
+	Nmeas += NMeasPerStar;
 
 	CHECK_REALLOCATE (newcat->average, Average, NAVE,  Nave,  1000);
Index: /trunk/Ohana/src/addstar/src/loadwise_star_full.c
===================================================================
--- /trunk/Ohana/src/addstar/src/loadwise_star_full.c	(revision 42145)
+++ /trunk/Ohana/src/addstar/src/loadwise_star_full.c	(revision 42146)
@@ -2,12 +2,100 @@
 # include "WISE.h"
 
-int setWISE_ph_qual (Measure *measure, char qual);
 int setWISE_var_flag_allsky (Measure *measure, char qual);
 int setWISE_ext_flag_allsky (Measure *measure, char ptr);
 int setWISE_var_flag_prelim (Measure *measure, char qual);
 int setWISE_ext_flag_prelim (Measure *measure, char ptr);
-int setWISE_cc_flag (Measure *measure, char qual);
-int setWISE_sat_flag (Measure *measure, char *ptr);
 int setWISE_blend_flag (Measure *measure, char *ptr);
+
+// fill in the data for a CatWISE double star.  takes a pointer to the start of the line the
+// RA and DEC have already been set
+int loadwise_star_catwise (Measure *measure, char *line, int Nmax, double Rs, double Ds) {
+
+  int i;
+  char *ptr;
+
+  if (line == NULL) Shutdown ("format error in WISE");
+
+  ptr = line;
+
+  /*** CATWISE has fixed width data, not pipe-separated, etc ***/
+
+  // https://irsa.ipac.caltech.edu/data/WISE/CatWISE/gator_docs/catwise_colDescriptions.html
+
+  // We are supplied a pointer (line) to the start of a full line of data.  The CatWISE
+  // format uses fixed-width fields with white-space separators.  The ra & dec values have
+  // already been extracted.
+
+  measure[0].R    = Rs;
+  measure[0].D    = Ds;
+  measure[1].R    = Rs;
+  measure[1].D    = Ds;
+
+  // I can assign dRA and dDEC to dX and dY if I can consistently set posangle and pltscale
+  measure[0].dXccd = ToShortPixels(getDoubleRAW (line, 71, 79) + 0.005); // sig_ra -- add 5/1000 to avoid truncation
+  measure[0].dYccd = ToShortPixels(getDoubleRAW (line, 80, 88) + 0.005); // sig_dec
+  measure[0].posangle = 0.0;
+  measure[0].pltscale = 1.0;
+
+  // we only know a single set of values for both bands 
+  measure[1].dXccd    = measure[0].dXccd;
+  measure[1].dYccd    = measure[0].dYccd;
+  measure[1].posangle = measure[0].posangle;
+  measure[1].pltscale = measure[0].pltscale;
+
+  measure[0].Xccd = getDoubleRAW (line,  98, 106); // wx
+  measure[0].Yccd = getDoubleRAW (line, 107, 115); // wy
+  measure[1].Xccd = measure[0].Xccd;
+  measure[1].Yccd = measure[0].Yccd;
+
+  // W1
+  measure[0].M         = getDoubleNAN (line, 248, 254); // w1mpro
+  measure[0].dM        = getDoubleNAN (line, 255, 264); // w1sigmpro
+  measure[0].psfChisq  = getDoubleRAW (line, 265, 275); // w1rchi2
+  measure[0].psfQF     = measure[0].psfChisq;
+  measure[0].photFlags = 0;
+
+  // W2
+  measure[1].M         = getDoubleNAN (line, 276, 282); // w2mpro
+  measure[1].dM        = getDoubleNAN (line, 283, 292); // w2sigmpro
+  measure[1].psfChisq  = getDoubleRAW (line, 293, 303); // w2rchi2
+  measure[1].psfQF     = measure[1].psfChisq;
+  measure[1].photFlags = 0;
+
+  setCatWISE_blend_flag (measure, line); // w1sat
+
+  setCatWISE_sat_flag (&measure[0], line, 323, 330); // w1sat
+  setCatWISE_sat_flag (&measure[1], line, 331, 338); // w2sat
+
+  // cc_flags? 1642 - 1657
+  // setWISE_cc_flag (&measure[0], ptr[i]); // cc_flags
+
+  // set ext flags for all 4 measures
+  // setCatWISE_ext_flag_allsky (measure, ptr[0]); // ext_flg
+
+  // setWISE_var_flag_allsky (&measure[0], ptr[i]); // var_flg
+
+  // setWISE_ph_qual (&measure[i], ptr[i]); // ph_qual
+
+  double mjdmean = getDoubleRAW (line, 1126, 1138); // MeanObsMJD
+  
+  // the release is based on data taken in the period 14 January 2010 to 29 April 2010
+  if (mjdmean == 0.0) {
+    measure[0].t = 0;
+  } else {
+    measure[0].t = ohana_mjd_to_sec (mjdmean);
+  }
+  measure[1].t = measure[0].t;
+
+  measure[0].photcode  = WISE_W1;
+  measure[0].detID   = 0;
+  measure[0].imageID = 0;
+
+  measure[1].photcode  = WISE_W2;
+  measure[1].detID   = 0;
+  measure[1].imageID = 0;
+
+  return TRUE;
+}
 
 // fill in the data for a WISE quad star.  takes a pointer to the start of the line the
@@ -458,4 +546,22 @@
 }
 
+int setCatWISE_blend_flag (Measure *measure, char *line) {
+
+  // na
+  int nb = atoi(getLineSegment(line, 315, 318)); // nb
+  int na = atoi(getLineSegment(line, 319, 322)); // na
+
+  if (nb != 1) {
+    if (na == 0) {
+      measure[0].photFlags |= FLAG_BLEND_ACTIVE;
+      measure[1].photFlags |= FLAG_BLEND_ACTIVE;
+    } else {
+      measure[0].photFlags |= FLAG_BLEND_PASSIVE;
+      measure[1].photFlags |= FLAG_BLEND_PASSIVE;
+    }
+  }
+  return TRUE;
+}
+
 int setWISE_sat_flag (Measure *measure, char *ptr) {
 
@@ -465,4 +571,13 @@
     }
     return TRUE;
+}
+
+int setCatWISE_sat_flag (Measure *measure, char *ptr, int start, int end) {
+
+  float sat = getDoubleRAW (ptr, start, end);
+  if (sat > 0.0) {
+    measure[0].photFlags |= FLAG_SATURATED_PIX;
+  }
+  return TRUE;
 }
 
