Index: /branches/eam_branches/ipp-20111122/Ohana/src/addstar/test/relphot.setphot.parallel.dvo
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/addstar/test/relphot.setphot.parallel.dvo	(revision 33302)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/addstar/test/relphot.setphot.parallel.dvo	(revision 33303)
@@ -158,5 +158,5 @@
 
   # run setphot on the serial db and check that the images now match the expected values
-  exec setphot -update -ubercal testzpt.fits -D CATDIR $catdir
+  exec setphot -reset -update -ubercal testzpt.fits -D CATDIR $catdir
   for i 0 mjd_uc[]
     ckexposure $catdir mjd_uc[$i] zpt_uc[$i] exptime_uc[$i] airmass_uc[$i] $filt_uc:$i setphot_uc
@@ -178,8 +178,9 @@
 
   # run setphot on the parallel db and check that the images now match the expected values
-  exec setphot -parallel -update -ubercal testzpt.fits -D CATDIR $catdir.p0
+  exec setphot -reset -parallel -update -ubercal testzpt.fits -D CATDIR $catdir.p0
 
   # bring the detections back to the local db
-  exec dvodist -in $catdir.p0 >& log.dvodist.in
+  # exec dvodist -in $catdir.p0 >& log.dvodist.in
+  # XXX this should now not be needed
 
   # check the results
@@ -190,14 +191,8 @@
     ckexposure $catdir.p0 mjd_nc[$i] zpt_nc[$i] exptime_nc[$i] airmass_nc[$i] $filt_nc:$i setphot_nc
   end
-
-  # push the detections back out to the parallel db
-  exec dvodist -out $catdir.p0 >& log.dvodist.in
 
   # run relphot on the parallel db and check that the images now match the expected values
   exec relphot -parallel g,r,i -v -region 9.5 10.5 19.5 20.5 -D CATDIR $catdir.p0 -D STAR_TOOFEW 1 -D SIGMA_LIM 0.07 -statmode WT_MEAN -cloud-limit 0.5 -keep-ubercal -D IMAGE_OFFSET 0.5 -update >& log.relphot.p0
 
-  # bring the detections back to the local db
-  exec dvodist -in $catdir.p0 >& log.dvodist.in
-
   for i 0 mjd_uc[]
     ckexposure $catdir.p0 mjd_uc[$i] zpt_uc[$i] exptime_uc[$i] airmass_uc[$i] $filt_uc:$i relphot
@@ -208,4 +203,50 @@
 
   tapDONE
+end
+
+macro qt
+
+  ## SER
+
+  # run setphot on the serial db and check that the images now match the expected values
+  exec setphot -reset -update -ubercal testzpt.fits -D CATDIR $catdir
+  for i 0 mjd_uc[]
+    ckexposure $catdir mjd_uc[$i] zpt_uc[$i] exptime_uc[$i] airmass_uc[$i] $filt_uc:$i setphot_uc
+  end
+  for i 0 mjd_nc[]
+    ckexposure $catdir mjd_nc[$i] zpt_nc[$i] exptime_nc[$i] airmass_nc[$i] $filt_nc:$i setphot_nc
+  end
+
+  # run relphot on the serial db and check that the images now match the expected values
+  exec relphot g,r,i -v -region 9.5 10.5 19.5 20.5 -D CATDIR $catdir -D STAR_TOOFEW 1 -D SIGMA_LIM 0.07 -statmode WT_MEAN -cloud-limit 0.5 -keep-ubercal -D IMAGE_OFFSET 0.5 -update >& log.relphot.s0
+  for i 0 mjd_uc[]
+    ckexposure $catdir mjd_uc[$i] zpt_uc[$i] exptime_uc[$i] airmass_uc[$i] $filt_uc:$i relphot
+  end
+  for i 0 mjd_nc[]
+    ckexposure $catdir mjd_nc[$i] zpt_nc[$i] exptime_nc[$i] airmass_nc[$i] $filt_nc:$i relphot
+  end
+
+  ## PAR
+
+  # run setphot on the parallel db and check that the images now match the expected values
+  exec setphot -reset -parallel -update -ubercal testzpt.fits -D CATDIR $catdir.p0
+
+  # check the results
+  for i 0 mjd_uc[]
+    ckexposure $catdir.p0 mjd_uc[$i] zpt_uc[$i] exptime_uc[$i] airmass_uc[$i] $filt_uc:$i setphot_uc
+  end
+  for i 0 mjd_nc[]
+    ckexposure $catdir.p0 mjd_nc[$i] zpt_nc[$i] exptime_nc[$i] airmass_nc[$i] $filt_nc:$i setphot_nc
+  end
+ 
+  # run relphot on the parallel db and check that the images now match the expected values
+  exec relphot -parallel g,r,i -v -region 9.5 10.5 19.5 20.5 -D CATDIR $catdir.p0 -D STAR_TOOFEW 1 -D SIGMA_LIM 0.07 -statmode WT_MEAN -cloud-limit 0.5 -keep-ubercal -D IMAGE_OFFSET 0.5 -update >& log.relphot.p0
+
+  for i 0 mjd_uc[]
+    ckexposure $catdir.p0 mjd_uc[$i] zpt_uc[$i] exptime_uc[$i] airmass_uc[$i] $filt_uc:$i relphot
+  end
+  for i 0 mjd_nc[]
+    ckexposure $catdir.p0 mjd_nc[$i] zpt_nc[$i] exptime_nc[$i] airmass_nc[$i] $filt_nc:$i relphot
+  end
 end
 
Index: /branches/eam_branches/ipp-20111122/Ohana/src/libdvo/include/dvo.h
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/libdvo/include/dvo.h	(revision 33302)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/libdvo/include/dvo.h	(revision 33303)
@@ -579,4 +579,5 @@
 // functions for parallel DVO
 HostTable    *HostTableLoad (char *catdir, char *rootname);
+int HostTableWaitJobs (HostTable *table, char *file, int lineno);
 
 # endif
Index: /branches/eam_branches/ipp-20111122/Ohana/src/libdvo/src/HostTable.c
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/libdvo/src/HostTable.c	(revision 33302)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/libdvo/src/HostTable.c	(revision 33303)
@@ -1,3 +1,5 @@
 # include "dvo.h"
+# include <sys/types.h>
+# include <sys/wait.h>
 
 void InitHosts (HostInfo *hosts, int Nhosts, int NHOSTS) {
@@ -114,2 +116,71 @@
   return table;
 }
+
+// wait for all children to complete, report output to stdout
+int HostTableWaitJobs (HostTable *table, char *file, int lineno) {
+
+  int i;
+
+  // we have launched table->Nhosts jobs; wait for all of them to complete...
+  // if one (N) failed to launch, we will get an ECHILD error from the last (N) calls
+  int done = FALSE;
+  for (i = 0; !done  && (i < table->Nhosts); i++) {
+    int status = 0;
+
+    // XXX we'll need to pass in WNOHANG and keep retrying if we want to have a timeout...
+    int pid = waitpid (-1, &status, 0);
+    if (!pid) {
+      // this should only occur if we called waitpid with the WNOHANG option
+      fprintf (stderr, "programming error (1)? %s %d", file, lineno);
+      exit (2);
+    }
+    if (pid == -1) {
+      switch (errno) {
+	case ECHILD:
+	  done = TRUE;
+	  break;
+	default:
+	  fprintf (stderr, "programming error (2)? %s %d", file, lineno);
+	  exit (2);
+      }
+    }
+
+    // find the host which has finished
+    int j;
+    int found = FALSE;
+    for (j = 0; j < table->Nhosts; j++) {
+      if (table->hosts[j].pid != pid) continue;
+      found = TRUE;
+      // check on the status of this and report any output?
+      fprintf (stderr, "job finished for %s (%d)\n", table->hosts[j].hostname, pid);
+      // read the stderr and stdout
+      IOBuffer buffer;
+      InitIOBuffer (&buffer, 100);
+      EmptyIOBuffer (&buffer, 100, table->hosts[j].stdio[1]);
+      fprintf (stderr, "--- stdout from %s ---\n", table->hosts[j].hostname);
+      write (STDOUT_FILENO, buffer.buffer, buffer.Nbuffer);
+      fprintf (stderr, "\n");
+	  
+      InitIOBuffer (&buffer, 100);
+      EmptyIOBuffer (&buffer, 100, table->hosts[j].stdio[2]);
+      fprintf (stderr, "--- stderr from %s ---\n", table->hosts[j].hostname);
+      write (STDOUT_FILENO, buffer.buffer, buffer.Nbuffer);
+      fprintf (stderr, "\n");
+      if (WIFEXITED(status)) {
+	fprintf (stderr, "normal completion, exit status is %d\n", WEXITSTATUS(status));
+	if (WEXITSTATUS(status)) {
+	  fprintf (stderr, "job failed on %s\n", table->hosts[j].hostname);
+	  exit (1);
+	}
+      } else {
+	fprintf (stderr, "job exited abnormally on %s\n", table->hosts[j].hostname);
+	exit (1);
+      }
+    }
+    if (!found) {
+      fprintf (stderr, "failed to matched finished job to known host!\n");
+      exit (2);
+    }
+  }
+  return TRUE;
+}
Index: /branches/eam_branches/ipp-20111122/Ohana/src/photdbc/src/CopyFromHostLocation.c
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/photdbc/src/CopyFromHostLocation.c	(revision 33302)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/photdbc/src/CopyFromHostLocation.c	(revision 33303)
@@ -86,4 +86,16 @@
 
     valid:
+
+      // the output (tgtname) could exist and be a link to the same file; delete it if it exists
+      status = stat (tgtname, &filestat);
+      if (!status) {
+	// a tgtfile already exists; get rid of it
+	if (unlink (tgtname)) {
+	  fprintf (stderr, "failed to remove CATDIR file %s\n", tgtname);
+	  success = FALSE;
+	  continue;
+	}
+      }
+
       // read srcname, write to tgtname, get MD5 sum for srcname as we go:
       if (!get_md5_with_copy (srcname, tgtname, srcDigest)) {
Index: /branches/eam_branches/ipp-20111122/Ohana/src/photdbc/src/CopyToHostLocation.c
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/photdbc/src/CopyToHostLocation.c	(revision 33302)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/photdbc/src/CopyToHostLocation.c	(revision 33303)
@@ -11,4 +11,5 @@
   struct stat filestat;
   char srcname[1024];
+  char newname[1024];
   char tgtname[1024];
   char outdir[1024];
@@ -131,6 +132,28 @@
       skylist->regions[i]->hostFlags |= DATA_ON_TGT;
       for (j = 0; success && (j < 4); j++) {
+	sprintf (tgtname, "%s/%s.%s", host->pathname, skylist->regions[i]->name, extname[j]);
 	sprintf (srcname, "%s/%s.%s", catdir, skylist->regions[i]->name, extname[j]);
-	if (!DEBUG && DELETE_ORIGINAL) unlink (srcname);
+	if (!DEBUG && DELETE_ORIGINAL) {
+	  unlink (srcname);
+	} else {
+	  sprintf (newname, "%s/%s.%s.bck", catdir, skylist->regions[i]->name, extname[j]);
+	  status = stat (newname, &filestat);
+	  if (!status) {
+	    // a backup file already exists; get rid of it
+	    if (unlink (newname)) {
+	      fprintf (stderr, "failed to remove old backup file %s\n", newname);
+	      continue;
+	    }
+	  }
+	  if (rename (srcname, newname)) {
+	    fprintf (stderr, "failed to rename %s to %s\n", srcname, newname);
+	    continue;
+	  }
+	  char *absname = abspath (tgtname, 1024);
+	  if (symlink (absname, srcname)) {
+	    fprintf (stderr, "failed to make symlink from %s to %s\n", absname, srcname);
+	  }
+	  free (absname);
+	}
       }
     }
Index: /branches/eam_branches/ipp-20111122/Ohana/src/relphot/include/relphot.h
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/relphot/include/relphot.h	(revision 33302)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/relphot/include/relphot.h	(revision 33303)
@@ -314,4 +314,2 @@
 int CopyAverageTiny (AverageTiny *averageT, Average *average);
 int CopyMeasureTiny (MeasureTiny *measureT, Measure *measure);
-
-int HostTableWaitJobs (HostTable *table, char *file, int lineno);
Index: /branches/eam_branches/ipp-20111122/Ohana/src/relphot/src/ImageSubset.c
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/relphot/src/ImageSubset.c	(revision 33302)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/relphot/src/ImageSubset.c	(revision 33303)
@@ -43,5 +43,5 @@
   if (!gfits_load_header (f, &theader)) {
     fclose (f);
-    return (NULL);
+    return NULL;
   }
 
Index: /branches/eam_branches/ipp-20111122/Ohana/src/relphot/src/args.c
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/relphot/src/args.c	(revision 33302)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/relphot/src/args.c	(revision 33303)
@@ -394,4 +394,10 @@
   }
 
+  KEEP_UBERCAL = FALSE;
+  if ((N = get_argument (argc, argv, "-keep-ubercal"))) {
+    remove_argument (N, &argc, argv);
+    KEEP_UBERCAL = TRUE;
+  }
+
   /* define time */
   TimeSelect = FALSE;
Index: /branches/eam_branches/ipp-20111122/Ohana/src/relphot/src/load_catalogs.c
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/relphot/src/load_catalogs.c	(revision 33302)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/relphot/src/load_catalogs.c	(revision 33303)
@@ -121,4 +121,5 @@
     // options / arguments that can affect relphot_client -load:
     // VERBOSE, VERBOSE2
+    // KEEP_UBERCAL
     // RESET (-reset)
     // TimeSelect -time
@@ -138,4 +139,5 @@
     if (VERBOSE2)      { snprintf (tmpline, 1024, "%s -vv",             command); 		     strcpy (command, tmpline); }
     if (RESET)         { snprintf (tmpline, 1024, "%s -reset",          command); 		     strcpy (command, tmpline); }
+    if (KEEP_UBERCAL)  { snprintf (tmpline, 1024, "%s -keep-ubercal",   command); 		     strcpy (command, tmpline); }
     if (DophotSelect)  { snprintf (tmpline, 1024, "%s -dophot %d",      command, DophotValue);       strcpy (command, tmpline); }
     if (ImagSelect)    { snprintf (tmpline, 1024, "%s -instmag %f %f",  command, ImagMin, ImagMax);  strcpy (command, tmpline); }
Index: /branches/eam_branches/ipp-20111122/Ohana/src/relphot/src/reload_catalogs.c
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/relphot/src/reload_catalogs.c	(revision 33302)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/relphot/src/reload_catalogs.c	(revision 33303)
@@ -1,5 +1,3 @@
 # include "relphot.h"
-# include <sys/types.h>
-# include <sys/wait.h>
 
 # define DEBUG 1
@@ -157,4 +155,5 @@
     if (VERBOSE2)      { snprintf (tmpline, 1024, "%s -vv",             command); 		     			    strcpy (command, tmpline); }
     if (RESET)         { snprintf (tmpline, 1024, "%s -reset",          command); 		     			    strcpy (command, tmpline); }
+    if (KEEP_UBERCAL)  { snprintf (tmpline, 1024, "%s -keep-ubercal",   command); 		     strcpy (command, tmpline); }
     if (AreaSelect)    { snprintf (tmpline, 1024, "%s -area %f %f %f %f", command, AreaXmin, AreaXmax, AreaYmin, AreaYmax); strcpy (command, tmpline); }
     if (TimeSelect) { 
@@ -198,71 +197,2 @@
   return (TRUE);
 }      
-
-// wait for all children to complete, report output to stdout
-int HostTableWaitJobs (HostTable *table, char *file, int lineno) {
-
-  int i;
-
-  // we have launched table->Nhosts jobs; wait for all of them to complete...
-  // if one (N) failed to launch, we will get an ECHILD error from the last (N) calls
-  int done = FALSE;
-  for (i = 0; !done  && (i < table->Nhosts); i++) {
-    int status = 0;
-
-    // XXX we'll need to pass in WNOHANG and keep retrying if we want to have a timeout...
-    int pid = waitpid (-1, &status, 0);
-    if (!pid) {
-      // this should only occur if we called waitpid with the WNOHANG option
-      fprintf (stderr, "programming error (1)? %s %d", file, lineno);
-      exit (2);
-    }
-    if (pid == -1) {
-      switch (errno) {
-	case ECHILD:
-	  done = TRUE;
-	  break;
-	default:
-	  fprintf (stderr, "programming error (2)? %s %d", file, lineno);
-	  exit (2);
-      }
-    }
-
-    // find the host which has finished
-    int j;
-    int found = FALSE;
-    for (j = 0; j < table->Nhosts; j++) {
-      if (table->hosts[j].pid != pid) continue;
-      found = TRUE;
-      // check on the status of this and report any output?
-      fprintf (stderr, "job finished for %s (%d)\n", table->hosts[j].hostname, pid);
-      // read the stderr and stdout
-      IOBuffer buffer;
-      InitIOBuffer (&buffer, 100);
-      EmptyIOBuffer (&buffer, 100, table->hosts[j].stdio[1]);
-      fprintf (stderr, "--- stdout from %s ---\n", table->hosts[j].hostname);
-      write (STDOUT_FILENO, buffer.buffer, buffer.Nbuffer);
-      fprintf (stderr, "\n");
-	  
-      InitIOBuffer (&buffer, 100);
-      EmptyIOBuffer (&buffer, 100, table->hosts[j].stdio[2]);
-      fprintf (stderr, "--- stderr from %s ---\n", table->hosts[j].hostname);
-      write (STDOUT_FILENO, buffer.buffer, buffer.Nbuffer);
-      fprintf (stderr, "\n");
-      if (WIFEXITED(status)) {
-	fprintf (stderr, "normal completion, exit status is %d\n", WEXITSTATUS(status));
-	if (WEXITSTATUS(status)) {
-	  fprintf (stderr, "job failed on %s\n", table->hosts[j].hostname);
-	  exit (1);
-	}
-      } else {
-	fprintf (stderr, "job exited abnormally on %s\n", table->hosts[j].hostname);
-	exit (1);
-      }
-    }
-    if (!found) {
-      fprintf (stderr, "failed to matched finished job to known host!\n");
-      exit (2);
-    }
-  }
-  return TRUE;
-}
Index: /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/include/setphot.h
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/include/setphot.h	(revision 33302)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/include/setphot.h	(revision 33303)
@@ -19,14 +19,18 @@
 
 /* global variables set in parameter file */
-char         ImageCat[256];
-char         CATDIR[256];
+# define MAX_PATH_LENGTH 1024
+char         ImageCat[MAX_PATH_LENGTH];
+char        *CATDIR;
 int          HOST_ID;
 char        *HOSTDIR;
 char        *IMAGES;
 int          VERBOSE;
+int          RESET;
 int          UBERCAL; // load the supplied ubercal zero point fits table (with flat-field corrections)
 int          NO_METADATA; // the supplied ubercal data has no descriptive metadata
-int          VERBOSE;
 int          UPDATE;
+int          PARALLEL;
+int          PARALLEL_MANUAL;
+int          PARALLEL_SERIAL;
 
 /***** prototypes ****/
Index: /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/ImageSubset.c
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/ImageSubset.c	(revision 33302)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/ImageSubset.c	(revision 33303)
@@ -39,10 +39,15 @@
 
   // load data for this header 
-  if (!gfits_load_header (f, &theader)) return (NULL);
+  if (!gfits_load_header (f, &theader)) {
+    fclose (f);
+    return NULL;
+  }
 
   // read the fits table bytes
-  if (!gfits_fread_ftable_data (f, &ftable, FALSE)) return (NULL);
-  
-  // XXX close the fits file here
+  if (!gfits_fread_ftable_data (f, &ftable, FALSE)) {
+    fclose (f);
+    return NULL;
+  }
+  fclose (f);
 
   // a bit annoying : we read the entire block of data (180M), then extract the columns, then set the image structure values.
@@ -153,4 +158,7 @@
   gfits_free_table (&ftable);
 
+  fclose (f);
+  fflush (f);
+
   return TRUE;
 }
Index: /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/initialize_setphot.c
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/initialize_setphot.c	(revision 33302)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/initialize_setphot.c	(revision 33303)
@@ -31,4 +31,36 @@
   if ((N = get_argument (argc, argv, "-v"))) {
     VERBOSE = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+
+  RESET = FALSE;
+  if ((N = get_argument (argc, argv, "-reset"))) {
+    RESET = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+
+  PARALLEL = FALSE;
+  if ((N = get_argument (argc, argv, "-parallel"))) {
+    PARALLEL = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+  // this is a test mode : rather than launching the remote jobs and waiting for completion,
+  // setphot will simply list the remote command and wait for the user to signal completion
+  PARALLEL_MANUAL = FALSE;
+  if ((N = get_argument (argc, argv, "-parallel-manual"))) {
+    PARALLEL = TRUE; // -parallel-manual implies -parallel
+    PARALLEL_MANUAL = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+  // this is a test mode : rather than launching the setphot_client jobs remotely, they are 
+  // run in serial via 'system'
+  PARALLEL_SERIAL = FALSE;
+  if ((N = get_argument (argc, argv, "-parallel-serial"))) {
+    if (PARALLEL_MANUAL) {
+      fprintf (stderr, "ERROR: cannot mix -parallel-manual and -parallel-serial\n");
+      exit (1);
+    }
+    PARALLEL = TRUE; // -parallel-serial implies -parallel
+    PARALLEL_SERIAL = TRUE;
     remove_argument (N, &argc, argv);
   }
@@ -82,5 +114,11 @@
   if (VERBOSE) fprintf (stderr, "loaded config file: %s\n", file);
 
-  GetConfig (config, "CATDIR",                 "%s",  0, CATDIR);
+  // force CATDIR to be absolute (so parallel mode will work)
+  char *tmpcatdir = NULL;
+  ALLOCATE (tmpcatdir, char, MAX_PATH_LENGTH);
+  GetConfig (config, "CATDIR",                 "%s",  0, tmpcatdir);
+  CATDIR = abspath (tmpcatdir, MAX_PATH_LENGTH);
+  free (tmpcatdir);
+
   sprintf (ImageCat, "%s/Images.dat", CATDIR);
 
Index: /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/initialize_setphot_client.c
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/initialize_setphot_client.c	(revision 33302)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/initialize_setphot_client.c	(revision 33303)
@@ -33,4 +33,10 @@
   }
 
+  RESET = FALSE;
+  if ((N = get_argument (argc, argv, "-reset"))) {
+    RESET = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+
   UBERCAL = FALSE;
   if ((N = get_argument (argc, argv, "-ubercal"))) {
@@ -61,11 +67,10 @@
   if (!HOSTDIR) goto usage;
 
-  CATDIR[0] = 0;
   if ((N = get_argument (argc, argv, "-catdir"))) {
     remove_argument (N, &argc, argv);
-    strcpy (CATDIR, argv[N]);
+    CATDIR = strcreate (argv[N]);
     remove_argument (N, &argc, argv);
   }
-  if (!CATDIR[0]) goto usage;
+  if (!CATDIR) goto usage;
 
   IMAGES = NULL;
@@ -81,5 +86,5 @@
 
 usage:
-  fprintf (stderr, "USAGE: setphot_client -hostname (hostname) -catdir (catdir) -hostdir (hostdir) -images (images) [options]\n");
+  fprintf (stderr, "USAGE: setphot_client -hostID (hostID) -catdir (catdir) -hostdir (hostdir) -images (images) [options]\n");
   fprintf (stderr, "  options:\n");
   fprintf (stderr, "    -v : verbose mode\n");
Index: /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/match_zpts_to_images.c
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/match_zpts_to_images.c	(revision 33302)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/match_zpts_to_images.c	(revision 33303)
@@ -38,4 +38,12 @@
   // sort the zpts
   sort_zpts_by_time (zpts, Nzpts);
+
+  if (RESET) {
+    for (i = 0; i < Nimage; i++) {
+      image[i].Mcal = 0.0;
+      image[i].dMcal = NAN;
+      image[i].flags &= ~ID_IMAGE_PHOTOM_NOCAL; // clear the NOCAL flag
+    }
+  }
 
   NImatch = 0; // matched images
Index: /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/setphot.c
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/setphot.c	(revision 33302)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/setphot.c	(revision 33303)
@@ -21,6 +21,7 @@
     zpts = load_zpt_ubercal (argv[1], &Nzpts, &flatcorrTable);
 
-    char flatcorrfile[64];
-    snprintf (flatcorrfile, 64, "%s/flatcorr.fits", CATDIR);
+    char flatcorrfile[MAX_PATH_LENGTH];
+    int size = snprintf (flatcorrfile, MAX_PATH_LENGTH, "%s/flatcorr.fits", CATDIR);
+    assert (size < MAX_PATH_LENGTH);
     FlatCorrectionSave(&flatcorrTable, flatcorrfile);
     // XXX should this program save any old copy of this file?
Index: /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/update_dvo_setphot.c
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/update_dvo_setphot.c	(revision 33302)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/uniphot/src/update_dvo_setphot.c	(revision 33303)
@@ -14,5 +14,4 @@
   SkyTableSetFilenames (sky, CATDIR, "cpt");
   
-# define PARALLEL 1
   if (PARALLEL && !HOST_ID) {
     update_dvo_setphot_parallel (sky, image, Nimage);
@@ -105,24 +104,49 @@
   for (i = 0; i < table->Nhosts; i++) {
 
+    // ensure that the paths are absolute path names
+    char *tmppath = abspath (table->hosts[i].pathname, MAX_PATH_LENGTH);
+    free (table->hosts[i].pathname);
+    table->hosts[i].pathname = tmppath;
+
     char command[1024];
-    snprintf (command, 1024, "setphot_client -test -hostname %s -catdir %s -hostdir %s -images %s", 
-	      table->hosts[i].hostname, CATDIR, table->hosts[i].pathname, imageFile);
+    snprintf (command, 1024, "setphot_client -hostID %d -catdir %s -hostdir %s -images %s", 
+	      table->hosts[i].hostID, CATDIR, table->hosts[i].pathname, imageFile);
 
     fprintf (stderr, "command: %s\n", command);
 
-    // launch the job on the remote machine (no handshake)
-    int errorInfo = 0;
-    int pid = rconnect ("ssh", table->hosts[i].hostname, command, table->hosts[i].stdio, &errorInfo, FALSE);
-    if (!pid) {
-      if (DEBUG) fprintf (stderr, "failure to start %s (error %d)\n", table->hosts[i].hostname, errorInfo);
-      exit (1);
+    char tmpline[1024];
+    if (VERBOSE)       { snprintf (tmpline, 1024, "%s -v",              command);                    strcpy (command, tmpline); }
+    if (RESET)         { snprintf (tmpline, 1024, "%s -reset",          command); 		     strcpy (command, tmpline); }
+    if (UPDATE)        { snprintf (tmpline, 1024, "%s -update",         command); 		     strcpy (command, tmpline); }
+    if (UBERCAL)       { snprintf (tmpline, 1024, "%s -ubercal",        command); 		     strcpy (command, tmpline); }
+
+    if (PARALLEL_MANUAL) continue;
+
+    if (PARALLEL_SERIAL) {
+      int status = system (command);
+      if (status) {
+	fprintf (stderr, "ERROR running setphot_client\n");
+	exit (2);
+      }
+    } else {
+      // launch the job on the remote machine (no handshake)
+      int errorInfo = 0;
+      int pid = rconnect ("ssh", table->hosts[i].hostname, command, table->hosts[i].stdio, &errorInfo, FALSE);
+      if (!pid) {
+	if (DEBUG) fprintf (stderr, "failure to start %s (error %d)\n", table->hosts[i].hostname, errorInfo);
+	exit (1);
+      }
+      table->hosts[i].pid = pid; // save for future reference
     }
-    table->hosts[i].pid = pid; // save for future reference
-
-    // check that all hosts started OK?
   }
 
-  // watch for stdout / stderr from those jobs...
-  // wait for all of them to complete...
+  // wait for the remote jobs to be completed
+  if (PARALLEL_MANUAL) {
+    fprintf (stderr, "run the setphot_client commands above.  when these are done, hit return\n");
+    getchar();
+  }
+  if (!PARALLEL_MANUAL && !PARALLEL_SERIAL) {
+    HostTableWaitJobs (table, __FILE__, __LINE__);
+  }
 
   return (TRUE);
