Index: /branches/eam_branches/ipp-20130207/Ohana/src/delstar/include/delstar.h
===================================================================
--- /branches/eam_branches/ipp-20130207/Ohana/src/delstar/include/delstar.h	(revision 35230)
+++ /branches/eam_branches/ipp-20130207/Ohana/src/delstar/include/delstar.h	(revision 35231)
@@ -38,4 +38,7 @@
 int    VERBOSE;
 int    VERBOSE2;
+int    UPDATE;
+int    IMAGE_DETAILS;
+int    IMAGE_ONLY;
 int    ORPHAN;
 int    MISSED;
Index: /branches/eam_branches/ipp-20130207/Ohana/src/delstar/src/args.c
===================================================================
--- /branches/eam_branches/ipp-20130207/Ohana/src/delstar/src/args.c	(revision 35230)
+++ /branches/eam_branches/ipp-20130207/Ohana/src/delstar/src/args.c	(revision 35231)
@@ -9,7 +9,14 @@
   fprintf (stderr, "  delstar -orphan (region)\n");
   fprintf (stderr, "  delstar -missed (region)\n\n");
+  fprintf (stderr, "  delstar -photcodes (list) : delete by photcode\n\n");
+  fprintf (stderr, "  delstar -dup-images : delete duplicate images (by externID)\n\n");
   fprintf (stderr, "  optional flags:\n");
   fprintf (stderr, "  -v               : verbose mode\n");
   fprintf (stderr, "  -photcode (code) : restrict by photcode\n");
+  fprintf (stderr, "  -update : apply changes (-dup-images only)\n");
+  fprintf (stderr, "  -image-details : list info about the deleted images (-dup-images only)\n");
+  fprintf (stderr, "  -image-only : only examine the image table (changes are NOT saved; -dup-images only)\n");
+  fprintf (stderr, "  -region Rmin Rmax Dmin Dmax : apply changes to this part of the sky\n");
+  
   fprintf (stderr, "\n"); 
   exit (2);
@@ -48,4 +55,25 @@
     VERBOSE = TRUE;
     VERBOSE2 = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+
+  UPDATE = FALSE;
+  if ((N = get_argument (argc, argv, "-update"))) {
+    UPDATE = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+
+  IMAGE_DETAILS = FALSE;
+  if ((N = get_argument (argc, argv, "-image-details"))) {
+    IMAGE_DETAILS = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+
+  // we should never delete the images before the measures (or we won't know what to delete)
+  // -image-only is for testing
+  IMAGE_ONLY = FALSE;
+  if ((N = get_argument (argc, argv, "-image-only"))) {
+    IMAGE_ONLY = TRUE;
+    UPDATE = FALSE;
     remove_argument (N, &argc, argv);
   }
@@ -256,4 +284,23 @@
   }
 
+  UPDATE = FALSE;
+  if ((N = get_argument (argc, argv, "-update"))) {
+    UPDATE = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+
+  IMAGE_DETAILS = FALSE;
+  if ((N = get_argument (argc, argv, "-image-details"))) {
+    IMAGE_DETAILS = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+
+  IMAGE_ONLY = FALSE;
+  if ((N = get_argument (argc, argv, "-image-only"))) {
+    IMAGE_ONLY = TRUE;
+    UPDATE = FALSE;
+    remove_argument (N, &argc, argv);
+  }
+
   /* specify portion of the sky */
   UserPatch.Rmin = 0;
Index: /branches/eam_branches/ipp-20130207/Ohana/src/delstar/src/delete_duplicate_images.c
===================================================================
--- /branches/eam_branches/ipp-20130207/Ohana/src/delstar/src/delete_duplicate_images.c	(revision 35230)
+++ /branches/eam_branches/ipp-20130207/Ohana/src/delstar/src/delete_duplicate_images.c	(revision 35231)
@@ -8,6 +8,6 @@
 int delete_duplicate_images (int hostID, char *hostpath, FITS_DB *db) {
 
-  off_t Nimage;
-  Image *image;
+  off_t i, Nimage;
+  Image *image, *outimage;
 
   image = gfits_table_get_Image (&db[0].ftable, &Nimage, &db[0].swapped);
@@ -19,5 +19,36 @@
   IndexArray *imageID = find_duplicates (image, Nimage);
 
-  delete_duplicate_image_measures (hostID, hostpath, imageID);
+  if (!IMAGE_ONLY) {
+    delete_duplicate_image_measures (hostID, hostpath, imageID);
+  }
+
+  if (!UPDATE) return TRUE;
+
+  /* delete the identified images */
+  off_t Noutimage = 0;
+  ALLOCATE (outimage, Image, Nimage);
+  for (i = 0; i < Nimage; i++) {
+    if (image[i].imageID == 0) continue;
+    off_t Ni = image[i].imageID - imageID->minID;
+    myAssert (Ni >= 0, "oops");
+    myAssert (Ni < imageID->range, "oops");
+ 
+    // imageID->value[Ni] is TRUE if we want to delete the image
+    if (imageID->value[Ni]) continue;
+    outimage[Noutimage] = image[i];
+    Noutimage ++;
+  }
+  free (image);
+  
+  fprintf (stderr, "removing "OFF_T_FMT" images (leaving "OFF_T_FMT" of "OFF_T_FMT")\n",  Nimage - Noutimage, Noutimage, Nimage);
+  // gfits_table_set_Image (&db[0].ftable, outimage, Noutimage);
+
+  gfits_modify (&db[0].theader, "NAXIS2", OFF_T_FMT, 1,  Noutimage);
+  gfits_modify (&db[0].header, "NIMAGES", OFF_T_FMT, 1,  Noutimage);
+  db[0].theader.Naxis[1] = Noutimage;
+  db[0].ftable.buffer = (char *) outimage;
+
+  if (!dvo_image_save (db, VERBOSE)) return FALSE;
+  if (!dvo_image_unlock (db)) return FALSE;
 
   return TRUE;
@@ -77,5 +108,9 @@
 
     delete_duplicate_image_measures_catalog (&catalog, imageID);
-    dvo_catalog_save_complete (&catalog, VERBOSE2);
+
+    if (UPDATE) {
+      dvo_catalog_save_complete (&catalog, VERBOSE2);
+    }
+
     dvo_catalog_unlock (&catalog);
     dvo_catalog_free (&catalog);
@@ -342,4 +377,10 @@
   if (VERBOSE) fprintf (stderr, "ending with Nave, Nmeas: "OFF_T_FMT" "OFF_T_FMT"\n",  catalog[0].Naverage,  catalog[0].Nmeasure);
 
+  off_t NdelAves = Naverage - catalog[0].Naverage;
+  off_t NdelMeas = Nmeasure - catalog[0].Nmeasure;
+  if (NdelAves || NdelMeas) {
+    fprintf (stderr, "deleting "OFF_T_FMT" measures and "OFF_T_FMT" averages : %s\n",  NdelMeas, NdelAves, catalog[0].filename);
+  }
+
   FREE (measureDrop);
   FREE (measureSeqRaw);
@@ -406,11 +447,21 @@
     imageID->value[Ni] = TRUE;
     Ndelete[Nx] ++;
+
     // mark the parentID for deletion as well..
-  }
-
-  for (i = 0; i < Nimage; i++) {
+    // XXX this is probably bad : it assumes all chips
+    // should be deleted for a given exposure
+    off_t parentID = image[i].parentID;
+    if (parentID) {
+      off_t Np = parentID - imageID->minID;
+      myAssert (Np >= 0, "oops");
+      myAssert (Np < imageID->range, "oops");
+      imageID->value[Np] = TRUE;
+    }
+  }
+
+  for (i = 0; IMAGE_DETAILS && (i < Nimage); i++) {
     off_t Ni = image[i].imageID - imageID->minID;
     if (!imageID->value[Ni]) continue;
-    fprintf (stderr, "delete image (i) " OFF_T_FMT ", extID = %d\n", i, image[i].externID);
+    fprintf (stderr, "delete image (i) " OFF_T_FMT ", extID = %d : %s\n", i, image[i].externID, image[i].name);
   }
 
