Index: /branches/eam_branches/ipp-20130307/Ohana/src/delstar/Makefile
===================================================================
--- /branches/eam_branches/ipp-20130307/Ohana/src/delstar/Makefile	(revision 35405)
+++ /branches/eam_branches/ipp-20130307/Ohana/src/delstar/Makefile	(revision 35406)
@@ -38,4 +38,5 @@
 $(SRC)/find_matches.$(ARCH).o 	  \
 $(SRC)/parse_time.$(ARCH).o       \
+$(SRC)/ImageIDsOps.$(ARCH).o       \
 $(SRC)/check_permissions.$(ARCH).o \
 $(SRC)/Shutdown.$(ARCH).o          
@@ -49,4 +50,5 @@
 $(SRC)/delete_photcodes.$(ARCH).o \
 $(SRC)/delete_photcodes_single.$(ARCH).o \
+$(SRC)/ImageIDsOps.$(ARCH).o       \
 $(SRC)/Shutdown.$(ARCH).o          
 
Index: /branches/eam_branches/ipp-20130307/Ohana/src/delstar/include/delstar.h
===================================================================
--- /branches/eam_branches/ipp-20130307/Ohana/src/delstar/include/delstar.h	(revision 35405)
+++ /branches/eam_branches/ipp-20130307/Ohana/src/delstar/include/delstar.h	(revision 35406)
@@ -117,5 +117,5 @@
 int delete_duplicate_images (int hostID, char *hostpath, FITS_DB *db);
 int delete_duplicate_image_measures (int hostID, char *hostpath, IndexArray *imageID);
-int delete_duplicate_image_measures_parallel (SkyList *sky);
+int delete_duplicate_image_measures_parallel (SkyList *sky, IndexArray *imageID);
 int delete_duplicate_image_measures_catalog (Catalog *catalog, IndexArray *imageID);
 
@@ -123,2 +123,4 @@
 IndexArray *make_index_array (Image *image, off_t Nimage, int mode);
 
+IndexArray *ImageIDLoad(char *filename);
+int ImageIDSave(char *filename, IndexArray *imageID);
Index: /branches/eam_branches/ipp-20130307/Ohana/src/delstar/src/ImageIDsOps.c
===================================================================
--- /branches/eam_branches/ipp-20130307/Ohana/src/delstar/src/ImageIDsOps.c	(revision 35406)
+++ /branches/eam_branches/ipp-20130307/Ohana/src/delstar/src/ImageIDsOps.c	(revision 35406)
@@ -0,0 +1,133 @@
+# include "delstar.h"
+# define BZERO_INT16 1.0*0x8000
+# define BZERO_INT32 1.0*0x80000000
+# define BZERO_INT64 1.0*0x8000000000000000
+
+IndexArray *ImageIDLoad(char *filename) {
+
+  int i, Ncol;
+  off_t Nrow;
+  Header header;
+  Header theader;
+  Matrix matrix;
+  FTable ftable;
+
+  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");
+    fclose (f);
+    return NULL;
+  }
+  if (!gfits_fread_matrix (f, &matrix, &header)) {
+    if (VERBOSE) fprintf (stderr, "can't read image subset matrix\n");
+    gfits_free_header (&header);
+    fclose (f);
+    return NULL;
+  }
+
+  IndexArray *imageID = NULL;
+  ALLOCATE (imageID, IndexArray, 1);
+
+  gfits_modify (&header, "MIN_ID", OFF_T_FMT, 1, imageID->minID);
+  gfits_modify (&header, "MAX_ID", OFF_T_FMT, 1, imageID->maxID);
+  gfits_modify (&header, "RANGE",  OFF_T_FMT, 1, imageID->range);
+
+  ftable.header = &theader;
+
+  // load data for this header 
+  if (!gfits_load_header (f, &theader)) {
+    fclose (f);
+    return NULL;
+  }
+
+  // read the fits table bytes
+  if (!gfits_fread_ftable_data (f, &ftable, FALSE)) {
+    fclose (f);
+    return NULL;
+  }
+  fclose (f);
+
+  char type[16];
+  unsigned short *value = gfits_get_bintable_column_data (&theader, &ftable, "VALUE", type, &Nrow, &Ncol);
+  myAssert (!strcmp(type, "short"), "wrong column type");
+  myAssert (Nrow == imageID->range, "wrong number of rows in table?");
+
+  // XXX free the fits table data here 
+
+  ALLOCATE (imageID->value, off_t, imageID->range);
+  for (i = 0; i < imageID->range; i++) {
+    imageID->value[i] = value[i];
+  }
+  fprintf (stderr, "loaded data for %lld images\n", (long long) Nrow);
+
+  free (value);
+
+  return imageID;
+}
+
+int ImageIDSave(char *filename, IndexArray *imageID) {
+
+  int i;
+  Header header;
+  Header theader;
+  Matrix matrix;
+  FTable ftable;
+
+  gfits_init_header (&header);
+  header.extend = TRUE;
+  gfits_create_header (&header);
+  gfits_create_matrix (&header, &matrix);
+
+  gfits_modify (&header, "MIN_ID", OFF_T_FMT, 1, imageID->minID);
+  gfits_modify (&header, "MAX_ID", OFF_T_FMT, 1, imageID->maxID);
+  gfits_modify (&header, "RANGE",  OFF_T_FMT, 1, imageID->range);
+
+  gfits_create_table_header (&theader, "BINTABLE", "IMAGE_ID");
+
+  gfits_define_bintable_column (&theader, "I", "VALUE", "value", NULL, 1.0, BZERO_INT16);
+
+  // generate the output array that carries the data
+  gfits_create_table (&theader, &ftable);
+
+  unsigned short *value;
+
+  // create intermediate storage arrays
+  ALLOCATE (value, unsigned short, imageID->range);
+
+  // assign the storage arrays
+  for (i = 0; i < imageID->range; i++) {
+    value[i]   = imageID->value[i];
+  }
+
+  // add the columns to the output array
+  gfits_set_bintable_column (&theader, &ftable, "VALUE", value, imageID->range);
+
+  free (value);
+
+  FILE *f = fopen (filename, "w");
+  if (!f) {
+    fprintf (stderr, "ERROR: cannot open image ID file for output %s\n", filename);
+    return FALSE;
+  }
+
+  gfits_fwrite_header  (f, &header);
+  gfits_fwrite_matrix  (f, &matrix);
+  gfits_fwrite_Theader (f, &theader);
+  gfits_fwrite_table  (f, &ftable);
+
+  gfits_free_header (&header);
+  gfits_free_matrix (&matrix);
+  gfits_free_header (&theader);
+  gfits_free_table (&ftable);
+
+  fclose (f);
+  fflush (f);
+
+  return TRUE;
+}
Index: /branches/eam_branches/ipp-20130307/Ohana/src/delstar/src/args.c
===================================================================
--- /branches/eam_branches/ipp-20130307/Ohana/src/delstar/src/args.c	(revision 35405)
+++ /branches/eam_branches/ipp-20130307/Ohana/src/delstar/src/args.c	(revision 35406)
@@ -328,4 +328,9 @@
     remove_argument (N, &argc, argv);
   }
+  if ((N = get_argument (argc, argv, "-dup-images"))) {
+    if (MODE != MODE_NONE) usage();
+    MODE = MODE_DUP_IMAGES;
+    remove_argument (N, &argc, argv);
+  }
 
   if (MODE == MODE_NONE) delstar_client_usage ();
Index: /branches/eam_branches/ipp-20130307/Ohana/src/delstar/src/delete_duplicate_images.c
===================================================================
--- /branches/eam_branches/ipp-20130307/Ohana/src/delstar/src/delete_duplicate_images.c	(revision 35405)
+++ /branches/eam_branches/ipp-20130307/Ohana/src/delstar/src/delete_duplicate_images.c	(revision 35406)
@@ -84,5 +84,5 @@
   // launch the remote jobs
   if (PARALLEL && !hostID) {
-    int status = delete_duplicate_image_measures_parallel (skylist);
+    int status = delete_duplicate_image_measures_parallel (skylist, imageID);
     return status;
   }
@@ -132,11 +132,10 @@
   // write out the subset table of image information
   char imageFile[512];
-  snprintf (imageFile, 512, "%s/Images.subset.dat", CATDIR);
-
-  if (!ImageSubsetSave (imageFile, image, Nimage)) {
-    fprintf (stderr, "failed to write image subset\n");
+  snprintf (imageFile, 512, "%s/ImageIDs.tmp.fits", CATDIR);
+
+  if (!ImageIDSave (imageFile, imageID)) {
+    fprintf (stderr, "failed to write image ID table\n");
     exit (1);
   }
-
 
   // launch the delstar_client jobs to the parallel hosts
@@ -167,6 +166,4 @@
 
     fprintf (stderr, "command: %s\n", command);
-
-    fprintf (stderr, "parallel version is not ready (need to save / load the imageID array\n");
 
     if (PARALLEL_MANUAL) continue;
Index: /branches/eam_branches/ipp-20130307/Ohana/src/delstar/src/delstar_client.c
===================================================================
--- /branches/eam_branches/ipp-20130307/Ohana/src/delstar/src/delstar_client.c	(revision 35405)
+++ /branches/eam_branches/ipp-20130307/Ohana/src/delstar/src/delstar_client.c	(revision 35406)
@@ -6,23 +6,23 @@
 int main (int argc, char **argv) {
 
+  char imageFile[512];
+
   SetSignals ();
   ConfigInit (&argc, argv);
   args_client (argc, argv);
 
-  // load the current sky table (layout of all SkyRegions) 
-  SkyTable *sky = SkyTableLoadOptimal (CATDIR, NULL, NULL, TRUE, -1, VERBOSE);
-  if (!sky) {
-      fprintf (stderr, "ERROR running loading sky table from %s\n", CATDIR);
-      exit (2);
-  }
-  SkyTableSetFilenames (sky, CATDIR, "cpt");
-
-  SkyList *skylist = SkyListByPatch (sky, -1, &UserPatch);
-  if (!skylist) {
-      fprintf (stderr, "ERROR setting up skylist for %s\n", CATDIR);
-      exit (2);
-  }
-
   switch (MODE) {
+    case MODE_DUP_IMAGES:
+      // read the subset table of image information
+      snprintf (imageFile, 512, "%s/ImageIDs.tmp.fits", CATDIR);
+      
+      IndexArray *imageID = ImageIDLoad (imageFile);
+      if (!imageID) {
+	fprintf (stderr, "failed to read image ID table\n");
+	exit (1);
+      }
+      if (!delete_duplicate_image_measures (HOST_ID, HOSTDIR, imageID)) exit (1);
+      exit (0);
+      break;
     case MODE_IMAGEFILE:
       break;
