Index: /branches/eam_branches/ipp-20111122/Ohana/src/opihi/dvo/dvo_client.c
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/opihi/dvo/dvo_client.c	(revision 33312)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/opihi/dvo/dvo_client.c	(revision 33313)
@@ -39,4 +39,32 @@
     remove_argument (N, argc, argv);
     HOSTDIR = strcreate (argv[N]);;
+    remove_argument (N, argc, argv);
+  }
+
+  // parse -skyregion option (used by most commands)
+  set_skyregion (0.0, 360.0, -90.0, +90.0);
+  if ((N = get_argument (*argc, argv, "-skyregion"))) {
+    if (N + 4 >= *argc) {
+      gprint (GP_ERR, "USAGE: -skyregion (RA) (RA) (DEC) (DEC)\n");
+      exit (1);
+    }
+    remove_argument (N, argc, argv);
+    set_skyregion (atof(argv[N]), atof(argv[N+1]), atof(argv[N+2]), atof(argv[N+3]));
+    remove_argument (N, argc, argv);
+    remove_argument (N, argc, argv);
+    remove_argument (N, argc, argv);
+    remove_argument (N, argc, argv);
+  }    
+
+  // parse -time option
+  if ((N = get_argument (*argc, argv, "-time"))) {
+    if (N + 2 >= *argc) {
+      gprint (GP_ERR, "USAGE: -time (TimeRef) (TimeFormat)\n");
+      exit (1);
+    }
+    remove_argument (N, argc, argv);
+    set_str_variable ("TIMEREF", argv[N]);
+    remove_argument (N, argc, argv);
+    set_str_variable ("TIMEFORMAT", argv[N]);
     remove_argument (N, argc, argv);
   }
Index: /branches/eam_branches/ipp-20111122/Ohana/src/opihi/dvo/mextract.c
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/opihi/dvo/mextract.c	(revision 33312)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/opihi/dvo/mextract.c	(revision 33313)
@@ -2,5 +2,5 @@
 
 # define DEBUG 1
-# define PARALLEL_MANUAL 1
+# define PARALLEL_MANUAL 0
 # define PARALLEL_SERIAL 0
 # define MAX_PATH_LENGTH 1024
@@ -8,4 +8,5 @@
 int HostTableLaunchJobs (HostTable *table, char *basecmd);
 Vector **MergeVectors (Vector **vec, int *Nvec, Vector **invec, int Ninvec);
+int HostTableParallelOps (int argc, char **argv, char *ResultFile);
 
 int mextract (int argc, char **argv) {
@@ -56,68 +57,20 @@
   }
 
-  // XXX not yet thought through (where are these set?)
+  // init here so free in 'escape' block does not crash
+  dvo_catalog_init (&catalog, TRUE);
+
+  // parse skyregion options.  NOTE: this is stripped off in parallel operation and always
+  // defined for the client via the -skyregion option.  The dvo_client parses this
+  // argument in the main program, before it is passed to the command (like mextract)
+  if ((selection = SetRegionSelection (&argc, argv)) == NULL) goto escape;
+
+  // this does all the work of re-packaging the command, calling it on the remote machines, then loading in the results
   if (PARALLEL && !HOST_ID) {
-    // load the list of hosts
-    SkyTable *sky = GetSkyTable();
-    if (!sky) return FALSE;
-
-    char *CATDIR = GetCATDIR ();
-    if (!CATDIR) return FALSE;
-
-    HostTable *table = HostTableLoad (CATDIR, sky->hosts);
-    if (!table) {
-      fprintf (stderr, "ERROR: failure reading Host Table %s for database %s\n", sky->hosts, CATDIR);
-      return FALSE;
-    }    
-
-    // other things I need to append?
-    char *basecmd = paste_args (argc, argv);
-    double Rmin, Rmax, Dmin, Dmax;
-    get_skyregion (&Rmin, &Rmax, &Dmin, &Dmax);
-
-    char tmp;
-    char *command = NULL;
-    int length = snprintf (&tmp, 0, "%s -D CATDIR %s -skyregion %f %f %f %f", basecmd, CATDIR, Rmin, Rmax, Dmin, Dmax);
-
-    ALLOCATE (command, char, length);
-    snprintf (command, length, "%s -D CATDIR %s -skyregion %f %f %f %f", basecmd, CATDIR, Rmin, Rmax, Dmin, Dmax);
-
-    // launch this command remotely
-    HostTableLaunchJobs (table, command);
-    free (command);
-
-    if (PARALLEL_MANUAL) {
-      fprintf (stderr, "run the relphot_client commands above.  when these are done, hit return\n");
-      getchar();
-    }
-    if (!PARALLEL_MANUAL && !PARALLEL_SERIAL) {
-      HostTableWaitJobs (table, __FILE__, __LINE__);
-    }
-
-    // load fields from file
-    int    Nvec = 0;
-    Vector **vec = NULL;
-    for (i = 0; i < table->Nhosts; i++) {
-      char resultFile[MAX_PATH_LENGTH];
-      snprintf (resultFile, MAX_PATH_LENGTH, "%s/dvo.results.fits", table->hosts[i].pathname);
-	
-      int    Ninvec = 0;
-      Vector **invec = ReadVectorTableFITS (resultFile, "MEXTRACT", &Ninvec);
-
-      vec = MergeVectors (vec, &Nvec, invec, Ninvec);
-      if (vec != invec) {
-	FreeVectorArray (invec, Ninvec);
-      }
-    }
-
-    for (i = 0; i < Nvec; i++) {
-      AssignVector (vec[i], vec[i]->name, ANYVECTOR, TRUE);
-    }
-    free (vec);
-
-    return TRUE;
-  }
-
-  dvo_catalog_init (&catalog, TRUE);
+    // not all parallel ops need to set the region selection...
+    if (!SetSkyRegions (selection)) goto escape;
+
+    int status = HostTableParallelOps (argc, argv, ResultFile);
+    return status;
+  }
 
   /* load photcode information */
@@ -127,7 +80,4 @@
   // init locally static variables (time refs)
   dbExtractMeasuresInit();
-
-  // parse skyregion options
-  if ((selection = SetRegionSelection (&argc, argv)) == NULL) goto escape;
 
   // command-line is of the form: avextract field,field, field [where (field op value)...]
@@ -174,5 +124,5 @@
   for (i = 0; !loadImages && (i < Nfields); i++) {
     if (!MEASURE_HAS_XCCD) {
-      // I'm keeping this code because it gives a way of handing dvo dbs that don't have
+      // I'm keeping this code because it gives a way of handling dvo dbs that don't have
       // measure.xccd if we need it
       if (fields[i].ID == MEAS_XCCD) loadImages = TRUE;
@@ -279,11 +229,10 @@
 
   for (n = 0; n < Nreturn; n++) {
-    ResetVector (vec[n], fields[n].type, MAX(0,Npts));
-  }
-
+    ResetVector (vec[n], fields[n].type, Npts);
+  }
+
+  // write vectors to a table (this is used by parallel dvo operations, but can be used elsewhere)
   if (ResultFile) {
-    // write vectors to a table
-    // char *resultFile?
-    int status = WriteVectorTableFITS (ResultFile, "MEXTRACT", vec, Nreturn, FALSE, NULL);
+    int status = WriteVectorTableFITS (ResultFile, "RESULT", vec, Nreturn, FALSE, NULL);
     if (!status) goto escape;
   }
@@ -443,7 +392,7 @@
 
     char command[1024];
-    snprintf (command, 1024, "%s -result %s -hostID %d -hostdir %s", basecmd, resultFile, table->hosts[i].hostID, table->hosts[i].pathname);
-
-    fprintf (stderr, "command: %s\n", command);
+    snprintf (command, 1024, "dvo_client %s -result %s -hostID %d -hostdir %s", basecmd, resultFile, table->hosts[i].hostID, table->hosts[i].pathname);
+
+    if (DEBUG || PARALLEL_MANUAL) fprintf (stderr, "command: %s\n", command);
 
     if (PARALLEL_MANUAL) {
@@ -488,13 +437,14 @@
     myAssert (vec[i]->type == invec[i]->type, "programming error (2)");
 
+    int N = vec[i]->Nelements;
     if (vec[i]->type == OPIHI_FLT) {
       REALLOCATE (vec[i]->elements.Flt, opihi_flt, vec[i]->Nelements + invec[i]->Nelements);
       for (j = 0; j < invec[i]->Nelements; j++) {
-	vec[i]->elements.Flt[i+j] = vec[i]->elements.Flt[j];
+	vec[i]->elements.Flt[N+j] = invec[i]->elements.Flt[j];
       }
     } else {
       REALLOCATE (vec[i]->elements.Int, opihi_int, vec[i]->Nelements + invec[i]->Nelements);
       for (j = 0; j < invec[i]->Nelements; j++) {
-	vec[i]->elements.Int[i+j] = vec[i]->elements.Int[j];
+	vec[i]->elements.Int[N+j] = invec[i]->elements.Int[j];
       }
     }
@@ -503,2 +453,85 @@
   return vec;
 }
+
+int HostTableParallelOps (int argc, char **argv, char *ResultFile) {
+
+  int i;
+
+  // load the list of hosts
+  SkyTable *sky = GetSkyTable();
+  if (!sky) return FALSE;
+
+  char *tmppath = GetCATDIR ();
+  if (!tmppath) return FALSE;
+
+  char *CATDIR = abspath (tmppath, MAX_PATH_LENGTH);
+  if (!CATDIR) return FALSE;
+
+  HostTable *table = HostTableLoad (CATDIR, sky->hosts);
+  if (!table) {
+    fprintf (stderr, "ERROR: failure reading Host Table %s for database %s\n", sky->hosts, CATDIR);
+    return FALSE;
+  }    
+
+  // other things I need to append?
+  char *basecmd = paste_args (argc, argv);
+
+  // determine the sky region 
+  double Rmin, Rmax, Dmin, Dmax;
+  get_skyregion (&Rmin, &Rmax, &Dmin, &Dmax);
+
+  // determine time reference and format
+  char *TimeRef = get_variable ("TIMEREF");
+  if (!TimeRef) return FALSE;
+
+  char *TimeFormat = get_variable ("TIMEFORMAT");
+  if (!TimeFormat) return FALSE;
+
+  char tmp;
+  char *command = NULL;
+  int length = snprintf (&tmp, 0, "%s -D CATDIR %s -time %s %s -skyregion %f %f %f %f", basecmd, CATDIR, TimeRef, TimeFormat, Rmin, Rmax, Dmin, Dmax);
+
+  ALLOCATE (command, char, length);
+  snprintf (command, length, "%s -D CATDIR %s -time %s %s -skyregion %f %f %f %f", basecmd, CATDIR, TimeRef, TimeFormat, Rmin, Rmax, Dmin, Dmax);
+
+  // launch this command remotely
+  HostTableLaunchJobs (table, command);
+  free (command);
+
+  if (PARALLEL_MANUAL) {
+    fprintf (stderr, "run the relphot_client commands above.  when these are done, hit return\n");
+    getchar();
+  }
+  if (!PARALLEL_MANUAL && !PARALLEL_SERIAL) {
+    HostTableWaitJobs (table, __FILE__, __LINE__);
+  }
+
+  // load fields from file
+  int    Nvec = 0;
+  Vector **vec = NULL;
+  for (i = 0; i < table->Nhosts; i++) {
+    char resultFile[MAX_PATH_LENGTH];
+    snprintf (resultFile, MAX_PATH_LENGTH, "%s/dvo.results.fits", table->hosts[i].pathname);
+	
+    int    Ninvec = 0;
+    Vector **invec = ReadVectorTableFITS (resultFile, "RESULT", &Ninvec);
+
+    vec = MergeVectors (vec, &Nvec, invec, Ninvec);
+    if (vec != invec) {
+      FreeVectorArray (invec, Ninvec);
+    }
+  }
+
+  // write vectors to a table (this is used by parallel dvo operations, but can be used elsewhere)
+  if (ResultFile) {
+    int status = WriteVectorTableFITS (ResultFile, "RESULT", vec, Nvec, FALSE, NULL);
+    if (!status) return FALSE;
+  }
+
+  for (i = 0; i < Nvec; i++) {
+    AssignVector (vec[i], vec[i]->name, ANYVECTOR, TRUE);
+  }
+  free (vec);
+
+  return TRUE;
+}
Index: /branches/eam_branches/ipp-20111122/Ohana/src/opihi/dvo/region_list.c
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/opihi/dvo/region_list.c	(revision 33312)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/opihi/dvo/region_list.c	(revision 33313)
@@ -131,4 +131,47 @@
   selection[0].useSkyregion = TRUE;
   return selection;
+}
+
+/* given possible options (by name, by list, by graph region), select SkyRegions */
+int SetSkyRegions (SkyRegionSelection *selection) {
+
+  if (selection->name != NULL) {
+    gprint (GP_ERR, "name-based selection not yet implemented (in parallel mode)\n");
+    return FALSE;
+  } 
+
+  if (selection->list != NULL) {
+    gprint (GP_ERR, "list-based selection not yet implemented (in parallel mode)\n");
+    return FALSE;
+  } 
+
+  if (selection->useDisplay) {
+    double Rmin, Rmax, Dmin, Dmax, Radius;
+    Graphdata graphsky;
+
+    if (!GetGraphdata (&graphsky, NULL, NULL)) {
+      gprint (GP_ERR, "region display not available\n");
+      return FALSE;
+    }
+    Radius = MAX (fabs(graphsky.xmax), fabs(graphsky.ymax));
+    Dmin = graphsky.coords.crval2 - Radius;
+    Dmax = graphsky.coords.crval2 + Radius;
+    
+    if ((Dmin <= -89) || (Dmax >= 89)) {
+      Rmin = 0;
+      Rmax = 360;
+    } else {
+      double Rmod = MAX (Radius / (cos(Dmin*RAD_DEG)), Radius / (cos(Dmax*RAD_DEG)));
+      Rmin = graphsky.coords.crval1 - Rmod;
+      Rmax = graphsky.coords.crval1 + Rmod;
+    }
+
+    set_skyregion (Rmin, Rmax, Dmin, Dmax);
+    return TRUE;
+  }
+  if (selection->useSkyregion) {
+    return TRUE;
+  }
+  return FALSE;
 }
 
Index: /branches/eam_branches/ipp-20111122/Ohana/src/opihi/include/dvoshell.h
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/opihi/include/dvoshell.h	(revision 33312)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/opihi/include/dvoshell.h	(revision 33313)
@@ -329,4 +329,5 @@
 int           SelectMags            PROTO((int Nphot, int Tphot, int Ns, Average *average, Measure *measure, SecFilt *secfilt, int UL));
 
+int           SetSkyRegions         PROTO((SkyRegionSelection *selection));
 SkyList      *SelectRegions         PROTO((SkyRegionSelection *selection));
 SkyList      *SkyListLoadFile       PROTO((char *filename));
Index: /branches/eam_branches/ipp-20111122/Ohana/src/opihi/lib.shell/VectorIO.c
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/opihi/lib.shell/VectorIO.c	(revision 33312)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/opihi/lib.shell/VectorIO.c	(revision 33313)
@@ -123,5 +123,4 @@
   
   Header header;
-  Header theader;
   FTable ftable;
 
@@ -186,5 +185,5 @@
 	snprintf (vec[Nvec + j]->name, OPIHI_NAME_SIZE, "%s:%d", name, j);
       }
-      ResetVector (vec[Nvec + j], vecType, MAX (Nrows,1));
+      ResetVector (vec[Nvec + j], vecType, Nrows);
     }
 
@@ -215,5 +214,5 @@
   }
 
-  gfits_free_header (&theader);
+  gfits_free_header (&header);
   gfits_free_table (&ftable);
 
Index: /branches/eam_branches/ipp-20111122/Ohana/src/opihi/lib.shell/VectorOps.c
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/opihi/lib.shell/VectorOps.c	(revision 33312)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/opihi/lib.shell/VectorOps.c	(revision 33313)
@@ -185,9 +185,9 @@
   if (in[0].elements.Ptr) {
     if (in[0].type == OPIHI_FLT) {
-      ALLOCATE (out[0].elements.Flt, opihi_flt, out[0].Nelements);
+      ALLOCATE (out[0].elements.Flt, opihi_flt, MAX(1,out[0].Nelements));
       memcpy (out[0].elements.Flt, in[0].elements.Flt, out[0].Nelements*sizeof(opihi_flt));
       out[0].type = OPIHI_FLT;
     } else {
-      ALLOCATE (out[0].elements.Int, opihi_int, out[0].Nelements);
+      ALLOCATE (out[0].elements.Int, opihi_int, MAX(1,out[0].Nelements));
       memcpy (out[0].elements.Int, in[0].elements.Int, out[0].Nelements*sizeof(opihi_int));
       out[0].type = OPIHI_INT;
@@ -201,8 +201,8 @@
   out[0].Nelements = in[0].Nelements;
   if (type == OPIHI_FLT) {
-    ALLOCATE (out[0].elements.Flt, opihi_flt, out[0].Nelements);
+    ALLOCATE (out[0].elements.Flt, opihi_flt, MAX(1,out[0].Nelements));
     out[0].type = OPIHI_FLT;
   } else {
-    ALLOCATE (out[0].elements.Int, opihi_int, out[0].Nelements);
+    ALLOCATE (out[0].elements.Int, opihi_int, MAX(1,out[0].Nelements));
     out[0].type = OPIHI_INT;
   }
@@ -210,8 +210,8 @@
 }
 
-// ResetVector (vecx, OPIHI_FLT, MAX (Npts, 1));
 int ResetVector (Vector *vec, char type, int Nelements) {
 
-  vec[0].Nelements = Nelements;
+  // a vector can only have >= 0 elements
+  vec[0].Nelements = MAX(Nelements,0);
   if (type == OPIHI_FLT) {
     REALLOCATE (vec[0].elements.Flt, opihi_flt, MAX(1, Nelements));
@@ -227,10 +227,10 @@
 int SetVector (Vector *vec, char type, int Nelements) {
 
-  vec[0].Nelements = Nelements;
+  vec[0].Nelements = MAX(Nelements,0);
   if (type == OPIHI_FLT) {
-    ALLOCATE (vec[0].elements.Flt, opihi_flt, Nelements);
+    ALLOCATE (vec[0].elements.Flt, opihi_flt, MAX(1,Nelements));
     vec[0].type = OPIHI_FLT;
   } else {
-    ALLOCATE (vec[0].elements.Int, opihi_int, Nelements);
+    ALLOCATE (vec[0].elements.Int, opihi_int, MAX(1,Nelements));
     vec[0].type = OPIHI_INT;
   }
