Index: /trunk/Ohana/src/dvomerge/include/dvomerge.h
===================================================================
--- /trunk/Ohana/src/dvomerge/include/dvomerge.h	(revision 39328)
+++ /trunk/Ohana/src/dvomerge/include/dvomerge.h	(revision 39329)
@@ -41,4 +41,6 @@
 int    REPLACE_TYCHO;
 int    FORCE_MERGE;
+int    ALLOW_MISSING_INPUT_IMAGES;
+
 int    MAX_CLIENTS;
 char  *ALTERNATE_PHOTCODE_FILE;
@@ -53,4 +55,6 @@
 
 int    MATCHED_TABLES;
+int    RESET_STARPAR;
+
 int    REPAIR_BY_OBJID;
 
@@ -74,5 +78,7 @@
   unsigned int *old;
   unsigned int *new;
-  char *notFound;
+  unsigned int  oldIDmax;
+  int *notFoundMeasure;
+  int *notFoundLensing;
 } IDmapType;
 
@@ -222,4 +228,5 @@
 IDmapType *IDmapLoad               PROTO((char *filename));
 int        create_IDmap_lookup     PROTO((IDmapType *IDmap));
+void       dvo_report_image_IDs    PROTO((IDmapType *IDmap));
 
 // dvomerge history functions
@@ -267,2 +274,3 @@
 
 char **load_cptlist (char *filename, int *nlist);
+int ResetStarPar (Catalog *catalog);
Index: /trunk/Ohana/src/dvomerge/src/LoadCatalog.c
===================================================================
--- /trunk/Ohana/src/dvomerge/src/LoadCatalog.c	(revision 39328)
+++ /trunk/Ohana/src/dvomerge/src/LoadCatalog.c	(revision 39329)
@@ -1,4 +1,5 @@
 # include "dvomerge.h"
 # define SKIP_GALPHOT 0
+# define SKIP_STARPAR 0
 
 int LoadCatalog (Catalog *catalog, SkyRegion *region, char *filename, char *mode, int Nsecfilt) {
@@ -12,8 +13,15 @@
   // XXXX TEMP HACK : skip GALPHOT
 
+  catalog[0].catflags = DVO_LOAD_AVERAGE | DVO_LOAD_MEASURE | DVO_LOAD_MISSING | DVO_LOAD_SECFILT | DVO_LOAD_LENSING | DVO_LOAD_LENSOBJ;
 # if (SKIP_GALPHOT)  
-  catalog[0].catflags = DVO_LOAD_AVERAGE | DVO_LOAD_MEASURE | DVO_LOAD_MISSING | DVO_LOAD_SECFILT | DVO_LOAD_LENSING | DVO_LOAD_LENSOBJ | DVO_LOAD_STARPAR;
+  catalog[0].catflags = catalog[0].catflags | DVO_SKIP_GALPHOT;
 # else
-  catalog[0].catflags = DVO_LOAD_AVERAGE | DVO_LOAD_MEASURE | DVO_LOAD_MISSING | DVO_LOAD_SECFILT | DVO_LOAD_LENSING | DVO_LOAD_LENSOBJ | DVO_LOAD_STARPAR | DVO_LOAD_GALPHOT;
+  catalog[0].catflags = catalog[0].catflags | DVO_LOAD_GALPHOT;
+# endif
+
+# if (SKIP_STARPAR)  
+  catalog[0].catflags = catalog[0].catflags | DVO_SKIP_STARPAR;
+# else
+  catalog[0].catflags = catalog[0].catflags | DVO_LOAD_STARPAR;
 # endif
   
@@ -27,2 +35,21 @@
   return (TRUE);
 }
+
+int ResetStarPar (Catalog *catalog) {
+
+  off_t i;
+
+  // we are going to delete the starpar values:
+
+  catalog[0].Nstarpar = 0;
+  catalog[0].Nstarpar_disk = 0;
+  catalog[0].Nstarpar_off = 0;
+
+  REALLOCATE (catalog[0].starpar, StarPar, 1);
+
+  for (i = 0; i < catalog[0].Naverage; i++) {
+    catalog[0].average[i].Nstarpar = 0;
+    catalog[0].average[i].starparOffset = -1;
+  }
+  return TRUE;
+}
Index: /trunk/Ohana/src/dvomerge/src/args.c
===================================================================
--- /trunk/Ohana/src/dvomerge/src/args.c	(revision 39328)
+++ /trunk/Ohana/src/dvomerge/src/args.c	(revision 39329)
@@ -48,4 +48,11 @@
 
   /* extra error messages */
+  RESET_STARPAR = FALSE;
+  if ((N = get_argument (*argc, argv, "-reset-starpar"))) {
+    RESET_STARPAR = TRUE;
+    remove_argument (N, argc, argv);
+  }
+
+  /* extra error messages */
   MATCH_BY_EXTERN_ID = FALSE;
   if ((N = get_argument (*argc, argv, "-match-by-extern-id"))) {
@@ -104,4 +111,11 @@
   if ((N = get_argument (*argc, argv, "-replace"))) {
     REPLACE_BY_PHOTCODE = TRUE;
+    remove_argument (N, argc, argv);
+  }
+
+  /* extra error messages */
+  ALLOW_MISSING_INPUT_IMAGES = FALSE;
+  if ((N = get_argument (*argc, argv, "-allow-missing-input-images"))) {
+    ALLOW_MISSING_INPUT_IMAGES = TRUE;
     remove_argument (N, argc, argv);
   }
@@ -271,7 +285,21 @@
 
   /* extra error messages */
+  RESET_STARPAR = FALSE;
+  if ((N = get_argument (*argc, argv, "-reset-starpar"))) {
+    RESET_STARPAR = TRUE;
+    remove_argument (N, argc, argv);
+  }
+
+  /* extra error messages */
   MATCH_BY_EXTERN_ID = FALSE;
   if ((N = get_argument (*argc, argv, "-match-by-extern-id"))) {
     MATCH_BY_EXTERN_ID = TRUE;
+    remove_argument (N, argc, argv);
+  }
+
+  /* extra error messages */
+  ALLOW_MISSING_INPUT_IMAGES = FALSE;
+  if ((N = get_argument (*argc, argv, "-allow-missing-input-images"))) {
+    ALLOW_MISSING_INPUT_IMAGES = TRUE;
     remove_argument (N, argc, argv);
   }
Index: /trunk/Ohana/src/dvomerge/src/build_links.c
===================================================================
--- /trunk/Ohana/src/dvomerge/src/build_links.c	(revision 39328)
+++ /trunk/Ohana/src/dvomerge/src/build_links.c	(revision 39329)
@@ -403,5 +403,9 @@
   N = 0;
 
+  // NOTE that is we choose DVO_SKIP_STARPAR, catalog.starpar is NULL.
+  // this code will let merge_catalogs_old.c do nothing for starpar
   ALLOCATE (next_star, off_t, Nstarpar);
+  if (!starpar) return next_star;
+
   for (i = 0; i < Naverage; i++) {
     if (!average[i].Nstarpar) continue;
@@ -442,4 +446,5 @@
 
   ALLOCATE (next_star, off_t, Nstarpar);
+  if (!starpar) return next_star;
 
   /* reset the Nm, offset values for average */
@@ -514,4 +519,6 @@
   off_t i, k, n, np, N;
   StarPar *tmpstarpar;
+
+  if (!starpar) return NULL;
 
   /* fix order of StarPar (memory intensive, but fast) */
Index: /trunk/Ohana/src/dvomerge/src/dvo_image_merge_dbs.c
===================================================================
--- /trunk/Ohana/src/dvomerge/src/dvo_image_merge_dbs.c	(revision 39328)
+++ /trunk/Ohana/src/dvomerge/src/dvo_image_merge_dbs.c	(revision 39329)
@@ -14,6 +14,8 @@
   IDmap->old = NULL;
   IDmap->new = NULL;
-  IDmap->notFound = NULL;
+  IDmap->notFoundMeasure = NULL;
+  IDmap->notFoundLensing = NULL;
   IDmap->Nmap = 0;
+  IDmap->oldIDmax = 0;
 }
 
@@ -22,5 +24,6 @@
   FREE (IDmap->old);
   FREE (IDmap->new);
-  FREE (IDmap->notFound);
+  FREE (IDmap->notFoundMeasure);
+  FREE (IDmap->notFoundLensing);
 }
 
@@ -65,7 +68,13 @@
   for (iSrc = 0; iSrc < NimagesSrc; iSrc++) {
     iTgt = getTgtIndexByExtID (imagesSrc[iSrc].externID, TgtIndex, TgtExtID, NimagesTgt);
-    if (iTgt < 0) Shutdown ("failure to find matching image: %s\n", imagesSrc[iSrc].name);
+    if ((iTgt < 0) && (!ALLOW_MISSING_INPUT_IMAGES)) {
+      Shutdown ("failure to find matching image: %s\n", imagesSrc[iSrc].name);
+    }
     IDmap[0].old[iSrc] = imagesSrc[iSrc].imageID;
-    IDmap[0].new[iSrc] = imagesTgt[iTgt].imageID;
+    if (iTgt < 0) {
+      IDmap[0].new[iSrc] = 0;
+    } else {
+      IDmap[0].new[iSrc] = imagesTgt[iTgt].imageID;
+    }
   }
 
@@ -124,5 +133,7 @@
   for (iSrc = 0; iSrc < NimagesSrc; iSrc++) {
     iTgt = getTgtIndexByTimeAndPhotcode (imagesSrc[iSrc].tzero, imagesSrc[iSrc].tzero + (int) imagesSrc[iSrc].exptime, imagesSrc[iSrc].photcode, TgtIndex, TgtTimes, TgtCodes, NimagesTgt);
-    if (iTgt < 0) Shutdown ("failure to match images: %s\n", imagesSrc[iSrc].name);
+    if ((iTgt < 0) && (!ALLOW_MISSING_INPUT_IMAGES)) {
+      Shutdown ("failure to find matching image: %s\n", imagesSrc[iSrc].name);
+    }
     IDmap[0].old[iSrc] = imagesSrc[iSrc].imageID;
     IDmap[0].new[iSrc] = imagesTgt[iTgt].imageID;
@@ -197,4 +208,90 @@
 }
 
+# if (0)
+// merge db2 into db1, skipping any from 'src' with the same EXTERN_ID as 'tgt'
+int dvo_image_merge_dbs_skip_duplicates (IDmapType *IDmap, FITS_DB *tgt, FITS_DB *stc) {
+
+  off_t NimagesSrc, NimagesTgt;
+  off_t Ntgt;
+  off_t i, IDstart;
+ 
+  IDmap->old = NULL;
+  IDmap->new = NULL;
+
+  // it is OK if there are no images in the database, but there should be no imageIDs to map...
+  if (src->dbstate == LCK_EMPTY) {
+    return TRUE;
+  }
+
+  // load both image tables
+  Images *imagesSrc = gfits_table_get_Image (&src[0].ftable, &NimagesSrc, &src[0].scaledValue, &src[0].nativeOrder);
+  if (!imagesSrc) {
+    fprintf (stderr, "ERROR: failed to read images (src)\n");
+    exit (2);
+  }
+
+  Images *imagesTgt = gfits_table_get_Image (&tgt[0].ftable, &NimagesTgt, &tgt[0].scaledValue, &tgt[0].nativeOrder);
+  if (!imagesTgt) {
+    fprintf (stderr, "ERROR: failed to read images (tgt)\n");
+    exit (2);
+  }
+
+  // generate an index for target extern IDs:
+  off_t  *TgtIndex;
+  unsigned int *TgtExtID;
+  ALLOCATE (TgtIndex, off_t,        NimagesTgt);
+  ALLOCATE (TgtExtID, unsigned int, NimagesTgt);
+
+  // save the Index & EXTERN_ID for all TGT images
+  off_t iSrc, iTgt;
+  for (iTgt = 0; iTgt < NimagesTgt; iTgt++) {
+    TgtIndex[iTgt] = iTgt;
+    TgtExtID[iTgt] = imagesTgt[iTgt].externID;
+  }
+
+  // sort the index, start, and stop by the start times:
+  SortTgtByExtID (TgtExtID, TgtIndex, NimagesTgt);
+
+  // identify the src images which are NOT in tgt
+  off_t *keepSrc = NULL;
+  ALLOCATE (keepSrc, off_t, NimagesSrc);
+  memset (keepSrc, 0, NimagesSrc*sizeof(off_t));
+
+  off_t Nkeep = 0;
+  for (iSrc = 0; iSrc < NimagesSrc; iSrc++) {
+    iTgt = getTgtIndexByExtID (imagesSrc[iSrc].externID, TgtIndex, TgtExtID, NimagesTgt);
+    if (iTgt >= 0) continue;
+    keepSrc[iSrc] = 1;
+    Nkeep ++;
+  }
+
+  // append the new image data to the end of the tgt structure, adjusting imageID as we go:
+  int status = gfits_scan (&tgt[0].header, "IMAGEID", OFF_T_FMT, 1,  &IDstart);
+  if (!status) {
+    IDstart = 1;
+  }
+
+  off_t jSrc = 0;
+  REALLOCATE (imagesTgt, Image, NimagesTgt + Nkeep);
+
+  for (iSrc = 0; iSrc < NimagesSrc; iSrc++) {
+    if (!keepSrc[iSrc]) continue; // skip images already in the image table
+    imagesTgt[NimagesTgt + jSrc] = imagesSrc[iSrc];
+    imagesTgt[NimagesTgt + jSrc].imageID = jSrc + IDstart;
+    jSrc ++;
+  }
+  myAssert (jSrc == Nkeep, "oops");
+
+  Ntgt += Nkeep;
+  IDstart += Nkeep;
+  gfits_modify (&tgt[0].header, "NIMAGES", OFF_T_FMT, 1,  Ntgt);
+  gfits_modify (&tgt[0].header, "IMAGEID", OFF_T_FMT, 1,  IDstart);
+
+  // XXX need to update ftable with the full Image table
+  // gfits_add_rows (&tgt[0].ftable, (char *) images, Nimages, sizeof(Image));
+  return TRUE;
+}
+# endif
+
 // map this ID to the new table
 // XXX isn't the map just ID_new = ID_old + offset ?? (probably not)
@@ -257,13 +354,15 @@
     if (newID == 0) {
       if (oldID > lastID) {
-	fprintf (stderr, "problem with image IDs : input out of range\n");
+	// this is a case where the measure->imageIDs are not consistent with the image->imageIDs
+	fprintf (stderr, "problem with image IDs (measure) : input out of range\n");
 	fprintf (stderr, "old ID: "OFF_T_FMT", last ID: "OFF_T_FMT"\n", oldID, lastID);
 	exit (2);
       }
-      if (!IDmap->notFound[oldID]) {
-	fprintf (stderr, "cannot find image ID "OFF_T_FMT"\n",  oldID);
-	IDmap->notFound[oldID] = TRUE;
+      if (!IDmap->notFoundMeasure[oldID]) {
+	// this is a case where the measure->imageIDs are not found in the OUTPUT image->imageIDs
 	// once we discover an imageID is not found, record that fact so we do not complain for every detection
+	fprintf (stderr, "cannot find image ID "OFF_T_FMT" with at least one measure\n",  oldID);
       }
+      IDmap->notFoundMeasure[oldID]++;
       // optionally exit here? or wait until end to report an error?
       // exit (2);
@@ -280,13 +379,14 @@
     if (newID == 0) {
       if (oldID > lastID) {
-	fprintf (stderr, "problem with image IDs : input out of range\n");
+	// this is a case where the measure->imageIDs are not consistent with the image->imageIDs
+	fprintf (stderr, "problem with image IDs (lensing) : input out of range\n");
 	fprintf (stderr, "old ID: "OFF_T_FMT", last ID: "OFF_T_FMT"\n", oldID, lastID);
 	exit (2);
       }
-      if (!IDmap->notFound[oldID]) {
+      if (!IDmap->notFoundLensing[oldID]) {
+	// once we discover an imageID is not found, record that fact so we do not complain for every detection
 	fprintf (stderr, "cannot find image ID "OFF_T_FMT"\n",  oldID);
-	IDmap->notFound[oldID] = TRUE;
-	// once we discover an imageID is not found, record that fact so we do not complain for every detection
       }
+      IDmap->notFoundLensing[oldID] ++;
       // optionally exit here? or wait until end to report an error?
       // exit (2);
@@ -298,4 +398,19 @@
 
   return TRUE;
+}
+
+void dvo_report_image_IDs (IDmapType *IDmap) {
+
+  off_t i;
+
+  for (i = 0; i < IDmap->oldIDmax + 1; i++) {
+    if (!IDmap->notFoundMeasure[i]) continue;
+    fprintf (stderr, "SKIP IMAGE MEASURE: "OFF_T_FMT", %d measures\n", i, IDmap->notFoundMeasure[i]);
+  }
+  for (i = 0; i < IDmap->oldIDmax + 1; i++) {
+    if (!IDmap->notFoundLensing[i]) continue;
+    fprintf (stderr, "SKIP IMAGE LENSING: "OFF_T_FMT", %d lensings\n", i, IDmap->notFoundLensing[i]);
+  }
+  return;
 }
 
@@ -415,6 +530,8 @@
     oldIDmax = IDmap->old[i];
   }
-  ALLOCATE (IDmap->notFound, char, oldIDmax + 1);
-  memset (IDmap->notFound, 0, sizeof(char) * (oldIDmax + 1));
+  IDmap->oldIDmax = oldIDmax;
+
+  ALLOCATE_ZERO (IDmap->notFoundMeasure, int, oldIDmax + 1);
+  ALLOCATE_ZERO (IDmap->notFoundLensing, int, oldIDmax + 1);
   return TRUE;
 }
Index: /trunk/Ohana/src/dvomerge/src/dvomergeUpdate_catalogs.c
===================================================================
--- /trunk/Ohana/src/dvomerge/src/dvomergeUpdate_catalogs.c	(revision 39328)
+++ /trunk/Ohana/src/dvomerge/src/dvomergeUpdate_catalogs.c	(revision 39329)
@@ -181,4 +181,9 @@
       LoadCatalog (&outcatalog, outlist[0].regions[j], outcatalog.filename, "w", NsecfiltOutput);
 
+      if (RESET_STARPAR) {
+	myAssert (MATCHED_TABLES, "must use -matched-tables to reset starpar");
+	ResetStarPar (&outcatalog);
+      }
+
       if (UPDATE_CATFORMAT) {
 	outcatalog.catformat = dvo_catalog_catformat (UPDATE_CATFORMAT);
@@ -239,4 +244,7 @@
     dvo_catalog_free (&incatalog);
   }
+
+  dvo_report_image_IDs (IDmap);
+
   return TRUE;
 }
@@ -306,17 +314,19 @@
 	       UserPatch.Rmin, UserPatch.Rmax, UserPatch.Dmin, UserPatch.Dmax, RADIUS);
 
-    if (VERBOSE)             { strextend (&command, "-v"); }
-    if (VERIFY)              { strextend (&command, "-verify"); }
-    if (VERIFY_CATALOG_ONLY) { strextend (&command, "-verify-catalogs"); }
-    if (REPLACE_BY_PHOTCODE) { strextend (&command, "-replace"); }
-    if (REPLACE_TYCHO)       { strextend (&command, "-replace-tycho"); }
-    if (PARALLEL_INPUT)      { strextend (&command, "-parallel-input"); }
-    if (FORCE_MERGE)         { strextend (&command, "-force-merge"); }
-    if (MATCHED_TABLES)      { strextend (&command, "-matched-tables"); }
-    if (MATCH_BY_EXTERN_ID)  { strextend (&command, "-match-by-extern-id"); }
-    if (UPDATE_CATFORMAT)    { strextend (&command, "-update-catformat %s", UPDATE_CATFORMAT); }
-    if (UPDATE_CATCOMPRESS)  { strextend (&command, "-update-catcompress %s", UPDATE_CATCOMPRESS); }
-    if (CPTLIST_FILENAME)    { strextend (&command, "-restrict-cpt %s", CPTLIST_FILENAME); }
-    if (REPAIR_BY_OBJID)     { strextend (&command, "-repair-by-objid"); }
+    if (VERBOSE)                    { strextend (&command, "-v"); }
+    if (VERIFY)                     { strextend (&command, "-verify"); }
+    if (VERIFY_CATALOG_ONLY)        { strextend (&command, "-verify-catalogs"); }
+    if (REPLACE_BY_PHOTCODE)        { strextend (&command, "-replace"); }
+    if (REPLACE_TYCHO)              { strextend (&command, "-replace-tycho"); }
+    if (PARALLEL_INPUT)             { strextend (&command, "-parallel-input"); }
+    if (FORCE_MERGE)                { strextend (&command, "-force-merge"); }
+    if (MATCHED_TABLES)             { strextend (&command, "-matched-tables"); }
+    if (MATCH_BY_EXTERN_ID)         { strextend (&command, "-match-by-extern-id"); }
+    if (RESET_STARPAR)              { strextend (&command, "-reset-starpar"); }
+    if (ALLOW_MISSING_INPUT_IMAGES) { strextend (&command, "-allow-missing-input-images"); }
+    if (UPDATE_CATFORMAT)           { strextend (&command, "-update-catformat %s", UPDATE_CATFORMAT); }
+    if (UPDATE_CATCOMPRESS)         { strextend (&command, "-update-catcompress %s", UPDATE_CATCOMPRESS); }
+    if (CPTLIST_FILENAME)           { strextend (&command, "-restrict-cpt %s", CPTLIST_FILENAME); }
+    if (REPAIR_BY_OBJID)            { strextend (&command, "-repair-by-objid"); }
 
     // add some config variables:
Index: /trunk/Ohana/src/dvomerge/src/dvorepairFixWarpIDs.c
===================================================================
--- /trunk/Ohana/src/dvomerge/src/dvorepairFixWarpIDs.c	(revision 39328)
+++ /trunk/Ohana/src/dvomerge/src/dvorepairFixWarpIDs.c	(revision 39329)
@@ -26,7 +26,4 @@
     exit (2);
   }
-
-  fprintf (stderr, "is this mode tested?\n");
-  exit (2);
 
   char *catdir_list  = argv[1];
