Index: trunk/Ohana/src/addstar/include/setobjflags.h
===================================================================
--- trunk/Ohana/src/addstar/include/setobjflags.h	(revision 39524)
+++ trunk/Ohana/src/addstar/include/setobjflags.h	(revision 39525)
@@ -2,5 +2,6 @@
 typedef struct {
   double R, D;
-  e_time time;
+//e_time time;
+//short filter;
   int myBit;
   int flag; // in a subset?
@@ -23,5 +24,5 @@
 int args_setobjflags_client (int *argc, char **argv);
 
-int setobjflags_table (SkyList *skylistInput, HostTable *hosts, char *filename, int myBit);
+int setobjflags_table (SkyList *skylistInput, HostTable *hosts);
 
 MyStars *setobjflags_make_subset (MyStars *stars, int Nstars, int start, SkyRegion *region, int *nsubset);
@@ -46,6 +47,5 @@
 MyStars *setobjflags_load_stars (char *filename, int *nstars);
 
-MyStars *setobjflags_loadfile (char *file, int mybit, int *Nstars);
-// MyStars *setobjflags_readstars (char *filename, int *nstars);
+MyStars *setobjflags_loadfile (int *Nstars);
 
 int setobjflags_sortStars (MyStars *stars, int Nstars);
Index: trunk/Ohana/src/addstar/src/args_setobjflags.c
===================================================================
--- trunk/Ohana/src/addstar/src/args_setobjflags.c	(revision 39524)
+++ trunk/Ohana/src/addstar/src/args_setobjflags.c	(revision 39525)
@@ -15,9 +15,20 @@
   }
 
-  /* we do not allow a subset to be extracted -- all or nothing, babe */
+  /* specify portion of the sky (useful for testing) */
   UserPatch.Rmin = 0;
-  UserPatch.Rmax= 360;
+  UserPatch.Rmax = 360;
   UserPatch.Dmin = -90;
   UserPatch.Dmax = +90;
+  if ((N = get_argument (*argc, argv, "-region"))) {
+    remove_argument (N, argc, argv);
+    UserPatch.Rmin = atof (argv[N]);
+    remove_argument (N, argc, argv);
+    UserPatch.Rmax = atof (argv[N]);
+    remove_argument (N, argc, argv);
+    UserPatch.Dmin = atof (argv[N]);
+    remove_argument (N, argc, argv);
+    UserPatch.Dmax = atof (argv[N]);
+    remove_argument (N, argc, argv);
+  }
 
   // XXX for the moment, make this selection manual.  it needs to be automatic 
@@ -57,16 +68,5 @@
   }
 
-  /* extra error messages */
-  SRC_FILES = NULL;
-  SRC_MYBIT = 0;
-  if ((N = get_argument (*argc, argv, "-src")) == 0) help ("missing -src argument: required");
-  if (N > *argc - 3) help("-src is missing (file) or (bits) values");
-  remove_argument (N, argc, argv);
-  SRC_FILES = strcreate (argv[N]);
-  remove_argument (N, argc, argv);
-  SRC_MYBIT = atoi (argv[N]);
-  remove_argument (N, argc, argv);
-
-  if (*argc < 3) help ("insufficient arguments");
+  if (*argc != 1) help ("insufficient arguments");
   return TRUE;
 }
@@ -143,5 +143,5 @@
   if (message) fprintf (stderr, "ERROR: %s\n\n", message);
 
-  fprintf (stderr, "USAGE: setobjflags [options] -src (file) (flag) [..more -src (file) (flag) sets]\n");
+  fprintf (stderr, "USAGE: setobjflags [options]\n");
   fprintf (stderr, "  add flags for specified detection sets\n\n");
 
Index: trunk/Ohana/src/addstar/src/find_matches_setobjflags.c
===================================================================
--- trunk/Ohana/src/addstar/src/find_matches_setobjflags.c	(revision 39524)
+++ trunk/Ohana/src/addstar/src/find_matches_setobjflags.c	(revision 39525)
@@ -22,4 +22,7 @@
   ALLOCATE (Y2, double, NAVE);
   ALLOCATE (N2, off_t,  NAVE);
+
+  // use this structure to count the number of mops detections
+  ALLOCATE_ZERO (catalog[0].nOwn_t, int,  NAVE);
 
   /* internal counters */
@@ -85,9 +88,9 @@
     }
 
-    /* this block will match a given detection to the closest object within range of that detection.
-       XXX note that this matches ALL detections within range of the single object to that same object 
-       this is bad, but I cannot just go in linear order (ie, mark off each object as they are
-       used).  I should make a list of all Nobj * Ndet pairs in range and choose the matches
-       based on their separations.  UGH
+    /* this block will match a given detection to the closest object within range of that
+       detection.  Note that this matches ALL detections within range of the single object
+       to that same object.  In this case (setobjflags), this is actually the behavior I
+       want: I have multiple independent star lists which need to be assigned to the
+       database.
      */
     
@@ -120,4 +123,10 @@
     /** set bit for this star **/
     catalog[0].average[n].flags |= stars[N].myBit;
+    if (stars[N].myBit & ID_OBJ_HAS_SOLSYS_DET) {
+      catalog[0].nOwn_t[n] ++;
+      if (catalog[0].nOwn_t[n] >= 0.5*catalog[0].average[n].Nmeasure) {
+	catalog[0].average[n].flags |= ID_OBJ_MOST_SOLSYS_DET;
+      }
+    }
     stars[N].found = TRUE;
     i++;
Index: trunk/Ohana/src/addstar/src/setobjflags.c
===================================================================
--- trunk/Ohana/src/addstar/src/setobjflags.c	(revision 39524)
+++ trunk/Ohana/src/addstar/src/setobjflags.c	(revision 39525)
@@ -48,5 +48,5 @@
   SkyList *skylist = SkyListByPatch (sky, -1, &UserPatch);
 
-  setobjflags_table (skylist, hosts, SRC_FILES, SRC_MYBIT);
+  setobjflags_table (skylist, hosts);
 
   FreeConfig ();
Index: trunk/Ohana/src/addstar/src/setobjflags_io.c
===================================================================
--- trunk/Ohana/src/addstar/src/setobjflags_io.c	(revision 39524)
+++ trunk/Ohana/src/addstar/src/setobjflags_io.c	(revision 39525)
@@ -29,7 +29,4 @@
   gfits_define_bintable_column (&theader, "D", "DEC",      "", "degree", 1.0, 0.0);
   gfits_define_bintable_column (&theader, "J", "MYBIT",    "", "", 1.0, FT_BZERO_INT32);
-//gfits_define_bintable_column (&theader, "J", "averef",   "", "", 1.0, FT_BZERO_INT32);
-//gfits_define_bintable_column (&theader, "J", "objID",    "", "", 1.0, FT_BZERO_INT32);
-//gfits_define_bintable_column (&theader, "J", "catID",    "", "", 1.0, FT_BZERO_INT32);
 
   int i;
@@ -37,7 +34,4 @@
   double       *dec      = NULL; ALLOCATE (dec     , double	 , Nstars); for (i = 0; i < Nstars; i++) dec     [i] = stars[i].D      ;
   unsigned int *myBit    = NULL; ALLOCATE (myBit   , unsigned int, Nstars); for (i = 0; i < Nstars; i++) myBit   [i] = stars[i].myBit  ;
-//unsigned int *averef   = NULL; ALLOCATE (averef  , unsigned int, Nstars); for (i = 0; i < Nstars; i++) averef  [i] = stars[i].starpar.averef  ;
-//unsigned int *objID    = NULL; ALLOCATE (objID   , unsigned int, Nstars); for (i = 0; i < Nstars; i++) objID   [i] = stars[i].starpar.objID   ;
-//unsigned int *catID    = NULL; ALLOCATE (catID   , unsigned int, Nstars); for (i = 0; i < Nstars; i++) catID   [i] = stars[i].starpar.catID   ;
 
   // generate the output array that carries the data
@@ -113,7 +107,4 @@
   GET_COLUMN(dec     , "DEC"       ,   double      ,   double      );
   GET_COLUMN(myBit   , "MYBIT"     ,   unsigned int,   int         );
-//GET_COLUMN(averef  , "averef"    ,   unsigned int,   int         );
-//GET_COLUMN(objID   , "objID"     ,   unsigned int,   int         );
-//GET_COLUMN(catID   , "catID"     ,   unsigned int,   int         );
 
   gfits_free_header (&theader);
@@ -128,4 +119,6 @@
     stars[i].D	              = dec    [i];
     stars[i].myBit            = myBit  [i];
+    stars[i].flag             = FALSE;
+    stars[i].found            = FALSE;
   }
 
Index: trunk/Ohana/src/addstar/src/setobjflags_loadfile.c
===================================================================
--- trunk/Ohana/src/addstar/src/setobjflags_loadfile.c	(revision 39524)
+++ trunk/Ohana/src/addstar/src/setobjflags_loadfile.c	(revision 39525)
@@ -1,14 +1,89 @@
 # include "addstar.h"
 # include "setobjflags.h"
+void sort_exp (int *I, int *T, int *F, int *S, int N);
+int expname_to_int (char *expname);
+int value_to_sequence (int *sequence, int Nsequence, int value);
+
+MyStars *setobjflags_loadfile_mops (char *metadata, char *detections, int mybit, int *Nstars);
+MyStars *setobjflags_loadfile_hern (char *filename, int *Nstars);
 
 /* read ASCII file with ref star data */
-MyStars *setobjflags_loadfile (char *file, int mybit, int *Nstars) {
-
-  FILE *f;
-  char line[256];
-
-  /* open file */
-  f = fopen (file, "r");
-  if (f == NULL) Shutdown ("can't read data from %s", file);
+MyStars *setobjflags_loadfile (int *Nstars) {
+
+  int Nmops;
+  MyStars *mopsStars = setobjflags_loadfile_mops ("md.fix.dat", "mops_export.txt", ID_OBJ_HAS_SOLSYS_DET, &Nmops);
+
+  int Nhern;
+  MyStars *hernStars = setobjflags_loadfile_hern ("NH_qso_rrlyrae_candidates_catalog.fits", &Nhern);
+
+  // merge into a single table
+  int Ntotal = Nhern + Nmops;
+  REALLOCATE (mopsStars, MyStars, Ntotal);
+  for (int i = Nmops, j = 0; i < Ntotal; i++, j++) {
+    mopsStars[i] = hernStars[j];
+  }
+  free (hernStars);
+
+  *Nstars = Ntotal;
+  return mopsStars;
+}
+
+MyStars *setobjflags_loadfile_mops (char *metadata, char *detections, int mybit, int *Nstars) {
+
+  // code to read in the MOPS detection dump
+  int Nexp = 0;
+  int NEXP = 1000;
+  ALLOCATE_PTR (expTIM,    int, NEXP);
+  ALLOCATE_PTR (expSEQ,    int, NEXP);
+  ALLOCATE_PTR (expFLT,    int, NEXP);
+  ALLOCATE_PTR (expIDX,    int, NEXP);
+
+  // load the metadata file:
+  FILE *f = fopen (metadata, "r");
+  if (f == NULL) Shutdown ("can't read data from %s", metadata);
+    
+  /* read in stars line-by-line */
+  char line[1024];
+  while (scan_line (f, line) != EOF) {
+    if (Nexp % 1000 == 0) fprintf (stderr, ".");
+
+    char filter[64], expname[64];
+    double expMJD;
+
+    int status = sscanf(line, "%lf %s %s", &expMJD, filter, expname);
+    if (status != 3) {
+      fprintf (stderr, "error reading line from MD: %s\n", line);
+      continue;
+    }
+
+    // XXX NOTE this does not handle gpc2 images
+    expIDX[Nexp] = expname_to_int (expname);
+
+    switch (filter[0]) {
+      case 'g': expFLT[Nexp] = 0; break;
+      case 'r': expFLT[Nexp] = 1; break;
+      case 'i': expFLT[Nexp] = 2; break;
+      case 'z': expFLT[Nexp] = 3; break;
+      case 'y': expFLT[Nexp] = 4; break;
+      case 'w': expFLT[Nexp] = 5; break;
+      default: myAbort ("oops");
+    }
+
+    expSEQ[Nexp] = Nexp;
+    expTIM[Nexp] = ohana_mjd_to_sec (expMJD);
+
+    Nexp++ ;
+    if (Nexp == NEXP) {
+      NEXP += 1000;
+      REALLOCATE (expTIM,    int, NEXP);
+      REALLOCATE (expSEQ,    int, NEXP);
+      REALLOCATE (expFLT,    int, NEXP);
+      REALLOCATE (expIDX,    int, NEXP);
+    }
+  }
+  fclose (f);
+  sort_exp (expIDX, expTIM, expFLT, expSEQ, Nexp);
+
+  fprintf (stderr, "done reading exposure metadata\n");
 
   MyStars *stars = NULL;
@@ -16,28 +91,219 @@
   ALLOCATE (stars, MyStars, NSTARS);
 
+  // load the detection file:
+  f = fopen (detections, "r");
+  if (f == NULL) Shutdown ("can't read data from %s", detections);
+    
+  scan_line (f, line); // skip the first line
+
   /* read in stars line-by-line */
-  int N = 0;
+  int N = 0, Nbad = 0, Nmiss = 0;
   while (scan_line (f, line) != EOF) {
+    if (N % 1000 == 0) fprintf (stderr, ".");
     stripwhite (line);
     if (line[0] == 0) continue;
     if (line[0] == '#') continue;
-
-    int status = sscanf (line, "%lf %lf", &stars[N].R, &stars[N].D);
-    if (status != 2) {
-      fprintf (stderr, "error reading line: %s\n", line);
+      
+    char expname[64];
+    int status = sscanf (line, "%s %lf %lf", expname, &stars[N].R, &stars[N].D);
+    if (status != 3) {
+      if (Nbad < 20) fprintf (stderr, "error reading line: %s\n", line);
+      Nbad ++;
       continue;
     }
     stars[N].R = ohana_normalize_angle (stars[N].R);
-    
+      
+    int expID = expname_to_int (expname);
+    int seq = value_to_sequence (expIDX, Nexp, expID);
+    if (seq < 0) {
+      if (Nmiss < 20) fprintf (stderr, "error missing expname: %s\n", expname);
+      Nmiss ++;
+    }
+
     stars[N].myBit = mybit;
-
-    stars[N].time = 0;
-    stars[N].flag = FALSE;
-    stars[N].found = FALSE;
-
+      
+    // stars[N].time   = expTIM[seq];
+    // stars[N].filter = expFLT[seq];
+    stars[N].flag   = FALSE;
+    stars[N].found  = FALSE;
+      
     N++;
     CHECK_REALLOCATE (stars, MyStars, NSTARS, N, 1000);
   }
+  fclose (f);
   *Nstars = N;
+
+  fprintf (stderr, "done reading mops detections\n");
+
+  FREE (expTIM);
+  FREE (expSEQ);
+  FREE (expFLT);
+  FREE (expIDX);
+
   return (stars);
 }
+
+# define GET_COLUMN(OUT,NAME,TYPE)					\
+  TYPE *OUT = gfits_get_bintable_column_data (&theader, &ftable, NAME, type, &Nrow, &Ncol); \
+  myAssert (!strcmp(type, #TYPE), "wrong column type");
+
+# define MIN_QSO_P60_VALUE 0.60
+# define MIN_QSO_P05_VALUE 0.05
+
+# define MIN_RRLYRA_P60_VALUE 0.60
+# define MIN_RRLYRA_P05_VALUE 0.05
+
+MyStars *setobjflags_loadfile_hern (char *filename, int *Nstars) {
+
+  int i, Ncol;
+  off_t Nrow;
+  char type[16];
+
+  Header header;
+  Header theader;
+  Matrix matrix;
+  FTable ftable;
+
+  header.buffer = NULL;
+  matrix.buffer = NULL;
+  ftable.buffer = NULL;
+  theader.buffer = NULL;
+  
+  FILE *f = fopen (filename, "r");
+  if (!f) {
+    fprintf (stderr, "ERROR: cannot open image subset file %s\n", filename);
+    return NULL;
+  }
+
+  /* load in PHU segment (ignore) */
+  if (!gfits_fread_header (f, &header)) {
+    if (VERBOSE) fprintf (stderr, "can't read image subset header\n");
+    goto escape;
+  }
+  if (!gfits_fread_matrix (f, &matrix, &header)) {
+    if (VERBOSE) fprintf (stderr, "can't read image subset matrix\n");
+    goto escape;
+  }
+
+  ftable.header = &theader;
+
+  // load data for this header 
+  if (!gfits_load_header (f, &theader)) goto escape;
+  
+  // read the fits table bytes
+  if (!gfits_fread_ftable_data (f, &ftable, FALSE)) goto escape;
+  
+  // need to create and assign to flat-field correction
+  GET_COLUMN(R,         "ra",   	float);
+  GET_COLUMN(D,         "dec",  	float);
+  GET_COLUMN(pQSO,      "p_QSO",  	float);
+  GET_COLUMN(pRRLyra,   "p_RRLyrae",  	float);
+  gfits_free_header (&theader);
+  gfits_free_table  (&ftable);
+
+  MyStars *stars = NULL;
+  ALLOCATE (stars, MyStars, Nrow);
+
+  for (i = 0; i < Nrow; i++) {
+    stars[i].R      = R[i];         
+    stars[i].D      = D[i];
+    // stars[i].time   = 0;
+    // stars[i].filter = 0;
+    stars[i].myBit  = ID_OBJ_HERN_VARIABLE; 
+
+    if (pQSO[i] >= MIN_QSO_P60_VALUE) {
+      stars[i].myBit |= ID_OBJ_HERN_QSO_P60;
+    }
+    if (pQSO[i] >= MIN_QSO_P05_VALUE) {
+      stars[i].myBit |= ID_OBJ_HERN_QSO_P05;
+    }
+    if (pRRLyra[i] >= MIN_RRLYRA_P60_VALUE) {
+      stars[i].myBit |= ID_OBJ_HERN_RRL_P60;
+    }
+    if (pRRLyra[i] >= MIN_RRLYRA_P05_VALUE) {
+      stars[i].myBit |= ID_OBJ_HERN_RRL_P05;
+    }
+    stars[i].flag   = FALSE;
+    stars[i].found  = FALSE;
+  }
+
+  FREE (R);
+  FREE (D);
+  FREE (pQSO);
+  FREE (pRRLyra);
+
+  gfits_free_header (&header);
+  gfits_free_matrix (&matrix);
+  fclose (f);
+  
+  *Nstars = Nrow;
+  return (stars);
+
+ escape:
+  gfits_free_header (&header);
+  gfits_free_matrix (&matrix);
+  gfits_free_header (&theader);
+  gfits_free_table  (&ftable);
+
+  fclose (f);
+  return NULL;
+}
+
+int expname_to_int (char *expname) {
+  
+  // XXX NOTE this does not handle gpc2 images
+  myAssert (expname[ 0] == 'o', "invalid exposure name");
+  myAssert (expname[ 5] == 'g', "invalid exposure name");
+  myAssert (expname[10] == 'o', "invalid exposure name");
+  int mjdExp = atoi(&expname[1]);
+  int seqExp = atoi(&expname[6]);
+  int value  = mjdExp * 10000 + seqExp;
+  return value;
+}
+
+void sort_exp (int *I, int *T, int *F, int *S, int N) {
+
+# define SWAPFUNC(A,B){ int itmp; 	\
+    itmp = I[A]; I[A] = I[B]; I[B] = itmp;	\
+    itmp = T[A]; T[A] = T[B]; T[B] = itmp;	\
+    itmp = F[A]; F[A] = F[B]; F[B] = itmp;	\
+    itmp = S[A]; S[A] = S[B]; S[B] = itmp;	\
+  }
+# define COMPARE(A,B)(I[A] < I[B])
+  
+  OHANA_SORT (N, COMPARE, SWAPFUNC);
+  
+# undef SWAPFUNC
+# undef COMPARE
+  
+}
+
+// find the entry by bisection:
+int value_to_sequence (int *sequence, int Nsequence, int value) {
+
+  int Nlo = 0; 
+  int Nhi = Nsequence - 1;
+
+  if (value < sequence[Nlo]) return -1;
+  if (value > sequence[Nhi]) return -1;
+
+  int N;
+  while (Nhi - Nlo > 4) {
+    N = 0.5*(Nlo + Nhi);
+    if (sequence[N] < value) {
+      Nlo = MAX(N, 0);
+    } else {
+      Nhi = MIN(N + 1, Nsequence - 1);
+    }
+  }
+  // mySequence->value[Nlo] <  value 
+  // mySequence->value[Nhi] >= value
+
+  for (N = Nlo; N <= Nhi; N++) {
+    if (sequence[N] == value) {
+      return N;
+    }
+  }
+  return -1;
+}
+
Index: trunk/Ohana/src/addstar/src/setobjflags_remote_hosts.c
===================================================================
--- trunk/Ohana/src/addstar/src/setobjflags_remote_hosts.c	(revision 39524)
+++ trunk/Ohana/src/addstar/src/setobjflags_remote_hosts.c	(revision 39525)
@@ -28,4 +28,15 @@
 void free_remote_hosts (void) {
   if (!hosts) return;
+
+  for (int i = 0; i < Nhosts; i++) {
+    if (hosts[i] == NULL) continue;
+    
+    HostInfo *host = hosts[i];
+    free (host->hostname);
+    free (host->pathname);
+    FreeIOBuffer (&host->stdout);
+    FreeIOBuffer (&host->stderr);
+    free (host);
+  }
   free (hosts);
 }
Index: trunk/Ohana/src/addstar/src/setobjflags_save_remote.c
===================================================================
--- trunk/Ohana/src/addstar/src/setobjflags_save_remote.c	(revision 39524)
+++ trunk/Ohana/src/addstar/src/setobjflags_save_remote.c	(revision 39525)
@@ -59,4 +59,12 @@
     fprintf (stderr, "command: %s\n", command);
 
+    if (PARALLEL_MANUAL) {
+      free (command);
+      fprintf (stderr, "run the setobjflags_client command above. when done, hit return\n");
+      getchar ();
+      save_remote_host (host);
+      return TRUE;
+    }
+
     // launch the job on the remote machine (no handshake)
     int errorInfo = 0;
Index: trunk/Ohana/src/addstar/src/setobjflags_table.c
===================================================================
--- trunk/Ohana/src/addstar/src/setobjflags_table.c	(revision 39524)
+++ trunk/Ohana/src/addstar/src/setobjflags_table.c	(revision 39525)
@@ -2,10 +2,8 @@
 # include "setobjflags.h"
 
-int setobjflags_table (SkyList *skylistInput, HostTable *hosts, char *filename, int mybit) {
+int setobjflags_table (SkyList *skylistInput, HostTable *hosts) {
   
-  int i, Nstars;
-
-  fprintf (stderr, "loading %s, using bit 0x%08x\n", filename, mybit);
-  MyStars *stars = setobjflags_loadfile (filename, mybit, &Nstars);
+  int Nstars;
+  MyStars *stars = setobjflags_loadfile (&Nstars);
   if (!stars) return FALSE;
 
@@ -15,5 +13,5 @@
   // scan through the stars, loading the containing catalogs
   // skip through table for unsaved stars
-  for (i = 0; i < Nstars; i++) {
+  for (int i = 0; i < Nstars; i++) {
     if (stars[i].flag) continue;
 
