Index: /branches/eam_branches/largefiles.20100314/Ohana/src/addstar/test/dvomerge.dvo
===================================================================
--- /branches/eam_branches/largefiles.20100314/Ohana/src/addstar/test/dvomerge.dvo	(revision 27396)
+++ /branches/eam_branches/largefiles.20100314/Ohana/src/addstar/test/dvomerge.dvo	(revision 27397)
@@ -73,8 +73,32 @@
   tapOK {abs($SIGMA) < 0.001} "ra (in - 0) vs ra (out - 0) (SIGMA)"
 
-  exec rm test.in.txt test.cmf
-  exec rm -rf catdir.test1
-  exec rm -rf catdir.test2
-  exec rm -rf catdir.test3
+  # check on updates to imageID
+  catdir catdir.test3
+  imextract imageID
+  sort imageID
+  tapOK {imageID[]  == 4} "image IDs exist"
+  tapOK {imageID[0] == 1} "updated image IDs"
+  tapOK {imageID[1] == 2} "updated image IDs"
+  tapOK {imageID[2] == 3} "updated image IDs"
+  tapOK {imageID[3] == 4} "updated image IDs"
+
+  catdir catdir.test3
+  mextract imageID, time
+  set id = imageID
+  set t = time
+  imextract imageID, time
+
+  for i 0 time[]
+    subset T = t if (id == imageID[$i])
+    set dT = T - time[$i]
+    vstat -q dT 
+    tapOK {abs($MEAN)  < 0.00001} "time for measure ID $i (MEAN)"
+    tapOK {abs($SIGMA) < 0.00001} "time for measure ID $i (SIGMA)"
+  end
+
+  # exec rm test.in.txt test.cmf
+  # exec rm -rf catdir.test1
+  # exec rm -rf catdir.test2
+  # exec rm -rf catdir.test3
 
   tapDONE
@@ -84,5 +108,5 @@
 macro test.dvomerge.create
 
-  tapPLAN 51
+  tapPLAN 21
 
   exec rm -rf catdir.test1
@@ -148,4 +172,33 @@
   tapOK {abs($MEAN)  < 0.001} "ra (in - 0) vs ra (out - 0) (MEAN)"
   tapOK {abs($SIGMA) < 0.001} "ra (in - 0) vs ra (out - 0) (SIGMA)"
+
+  # check on updates to imageID
+  catdir catdir.test3
+  imextract imageID
+  sort imageID
+  tapOK {imageID[]  == 4} "image IDs exist"
+  tapOK {imageID[0] == 1} "updated image IDs"
+  tapOK {imageID[1] == 2} "updated image IDs"
+  tapOK {imageID[2] == 3} "updated image IDs"
+  tapOK {imageID[3] == 4} "updated image IDs"
+
+  catdir catdir.test3
+  mextract imageID, time
+  set id = imageID
+  set t = time
+  imextract imageID, time
+
+  for i 0 time[]
+    subset T = t if (id == imageID[$i])
+    set dT = T - time[$i]
+    vstat -q dT 
+    tapOK {abs($MEAN)  < 0.00001} "time for measure ID $i (MEAN)"
+    tapOK {abs($SIGMA) < 0.00001} "time for measure ID $i (SIGMA)"
+  end
+
+  # exec rm test.in.txt test.cmf
+  # exec rm -rf catdir.test1
+  # exec rm -rf catdir.test2
+  # exec rm -rf catdir.test3
 
   tapDONE
Index: /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/Makefile
===================================================================
--- /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/Makefile	(revision 27396)
+++ /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/Makefile	(revision 27397)
@@ -24,4 +24,5 @@
 $(SRC)/dvomergeUpdate.$(ARCH).o \
 $(SRC)/dvomergeCreate.$(ARCH).o \
+$(SRC)/dvo_image_merge_dbs.$(ARCH).o \
 $(SRC)/SetSignals.$(ARCH).o \
 $(SRC)/ConfigInit.$(ARCH).o \
Index: /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/include/dvomerge.h
===================================================================
--- /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/include/dvomerge.h	(revision 27396)
+++ /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/include/dvomerge.h	(revision 27397)
@@ -27,4 +27,10 @@
 
 SkyRegion UserPatch;  // used by MODE CAT
+
+typedef struct {
+  off_t Nmap;
+  off_t *old;
+  off_t *new;
+} IDmapType;
 
 int        main                   PROTO((int argc, char **argv));
@@ -65,4 +71,7 @@
 uint64_t   CreatePSPSObjectID     PROTO((double ra, double dec));
 
-int        dvo_image_merge_dbs    PROTO((FITS_DB *out, FITS_DB *in));
-
+int        dvomergeImagesCreate   PROTO((IDmapType *IDmap1, char *input1, IDmapType *IDmap2, char *input2, char *output));
+int        dvomergeImagesUpdate   PROTO((IDmapType *IDmap, char *input, char *output));
+int        dvo_image_merge_dbs    PROTO((IDmapType *IDmap, FITS_DB *out, FITS_DB *in));
+off_t 	   dvo_map_image_ID       PROTO((IDmapType *IDmap, off_t oldID));
+int   	   dvo_update_image_IDs   PROTO((IDmapType *IDmap, Catalog *catalog));
Index: /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/dvo_image_merge_dbs.c
===================================================================
--- /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/dvo_image_merge_dbs.c	(revision 27397)
+++ /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/dvo_image_merge_dbs.c	(revision 27397)
@@ -0,0 +1,73 @@
+# include "dvomerge.h"
+
+// merge db2 into db1
+int dvo_image_merge_dbs (IDmapType *IDmap, FITS_DB *out, FITS_DB *in) {
+
+  Image *images;
+  off_t Nimages;
+  off_t Nout;
+  off_t i, IDstart;
+  int status;
+ 
+  images = gfits_table_get_Image (&in[0].ftable, &Nimages, &in[0].swapped);
+  ALLOCATE (IDmap->old, off_t, Nimages);
+  ALLOCATE (IDmap->new, off_t, Nimages);
+  IDmap->Nmap = Nimages;
+
+ /* adjust header */
+  Nout = 0;
+  gfits_scan (&out[0].header, "NIMAGES", "%lld", 1, (long long *) &Nout);
+  status = gfits_scan (&out[0].header, "IMAGEID", "%lld", 1, (long long *) &IDstart);
+  if (!status) {
+    IDstart = 1;
+  }
+
+  for (i = 0; i < Nimages; i++) {
+    IDmap[0].old[i] = images[i].imageID;
+    images[i].imageID = i + IDstart;
+    IDmap[0].new[i] = images[i].imageID;
+  }
+
+  if (!out[0].swapped) {
+    gfits_convert_Image ((Image *) out[0].ftable.buffer, sizeof(Image), Nout);
+    out[0].swapped = TRUE;
+  }
+
+  Nout += Nimages;
+  IDstart += Nimages;
+  gfits_modify (&out[0].header, "NIMAGES", "%lld", 1, (long long) Nout);
+  gfits_modify (&out[0].header, "IMAGEID", "%lld", 1, (long long) IDstart);
+
+  gfits_add_rows (&out[0].ftable, (char *) images, Nimages, sizeof(Image));
+  return TRUE;
+}
+
+// optimize with sort and bisection
+off_t dvo_map_image_ID (IDmapType *IDmap, off_t oldID) {
+
+  off_t i;
+
+  for (i = 0; i < IDmap->Nmap; i++) {
+    if (IDmap->old[i] != oldID) continue;
+    return (IDmap->new[i]);
+  }
+  return 0;
+}
+
+int dvo_update_image_IDs (IDmapType *IDmap, Catalog *catalog) {
+
+  off_t i, oldID, newID;
+
+  for (i = 0; i < catalog[0].Nmeasure; i++) {
+    oldID = catalog[0].measure[i].imageID;
+    if (oldID == 0) continue;
+
+    newID = dvo_map_image_ID (IDmap, oldID);
+    if (newID == 0) {
+      fprintf (stderr, "cannot find image ID %lld\n", (long long) oldID);
+      exit (2);
+    }
+    catalog[0].measure[i].imageID = newID;
+  }
+  return TRUE;
+}
Index: /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/dvomergeCreate.c
===================================================================
--- /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/dvomergeCreate.c	(revision 27396)
+++ /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/dvomergeCreate.c	(revision 27397)
@@ -11,4 +11,5 @@
   Catalog incatalog, outcatalog;
   char filename[256], *input1, *input2, *output;
+  IDmapType IDmap1, IDmap2;
 
   if (strcasecmp (argv[2], "and")) usage();
@@ -18,4 +19,6 @@
   input2 = argv[3];
   output = argv[5];
+
+  dvomergeImagesCreate (&IDmap1, input1, &IDmap2, input2, output);
 
   // the first input defines the photcode table & db layout
@@ -80,4 +83,5 @@
 	continue;
       }
+      dvo_update_image_IDs (&IDmap1, &incatalog);
       merge_catalogs_new (&outsky[0].regions[i], &outcatalog, &incatalog);
       dvo_catalog_unlock (&incatalog);
@@ -100,4 +104,5 @@
 	continue;
       }
+      dvo_update_image_IDs (&IDmap2, &incatalog);
       merge_catalogs_old (&outsky[0].regions[i], &outcatalog, &incatalog, RADIUS);
       dvo_catalog_unlock (&incatalog);
@@ -120,6 +125,10 @@
   }
 
+  exit (0);
+}
+
   /*** update the image table ***/
-  { 
+int dvomergeImagesCreate (IDmapType *IDmap1, char *input1, IDmapType *IDmap2, char *input2, char *output) { 
+
     FITS_DB in1DB;
     FITS_DB in2DB;
@@ -157,5 +166,5 @@
 
     // convert database table to internal structure & add to output image db
-    dvo_image_merge_dbs(&outDB, &in1DB);
+    dvo_image_merge_dbs(IDmap1, &outDB, &in1DB);
     dvo_image_unlock (&in1DB); // unlock input1
 
@@ -177,5 +186,5 @@
 
     // convert database table to internal structure & add to output image db
-    dvo_image_merge_dbs(&outDB, &in2DB);
+    dvo_image_merge_dbs(IDmap2, &outDB, &in2DB);
     dvo_image_unlock (&in2DB); // unlock input2
 
@@ -185,31 +194,6 @@
     SetProtect (FALSE);
     dvo_image_unlock (&outDB); // unlock output
+
+    return TRUE;
   }
 
-  exit (0);
-}
-
-// merge db2 into db1
-int dvo_image_merge_dbs (FITS_DB *out, FITS_DB *in) {
-
-  Image *images;
-  off_t Nimages;
-  off_t Nout;
- 
-  images = gfits_table_get_Image (&in[0].ftable, &Nimages, &in[0].swapped);
-
- /* adjust header */
-  Nout = 0;
-  gfits_scan (&out[0].header, "NIMAGES", "%lld", 1, (long long *) &Nout);
-
-  if (!out[0].swapped) {
-    gfits_convert_Image ((Image *) out[0].ftable.buffer, sizeof(Image), Nout);
-    out[0].swapped = TRUE;
-  }
-
-  Nout += Nimages;
-  gfits_modify (&out[0].header, "NIMAGES", "%lld", 1, (long long) Nout);
-
-  gfits_add_rows (&out[0].ftable, (char *) images, Nimages, sizeof(Image));
-  return TRUE;
-}
Index: /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/dvomergeUpdate.c
===================================================================
--- /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/dvomergeUpdate.c	(revision 27396)
+++ /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/dvomergeUpdate.c	(revision 27397)
@@ -9,4 +9,5 @@
   Catalog incatalog, outcatalog;
   char filename[256], *input, *output;
+  IDmapType IDmap;
 
   if (strcasecmp (argv[2], "into")) usage();
@@ -21,4 +22,6 @@
     exit (1);
   }
+
+  dvomergeImagesUpdate (&IDmap, input, output);
 
   // load the sky table for the existing database
@@ -59,4 +62,5 @@
 	continue;
       }
+      dvo_update_image_IDs (&IDmap, &incatalog);
       merge_catalogs_old (&outsky[0].regions[i], &outcatalog, &incatalog, RADIUS);
       dvo_catalog_unlock (&incatalog);
@@ -79,64 +83,53 @@
   }
 
-  /*** update the image table ***/
-  { 
-    FITS_DB inDB;
-    FITS_DB outDB;
-    int    status;
-
-    /*** load input1/Images.dat ***/
-    sprintf (ImageCat, "%s/Images.dat", input);
-    inDB.mode   = dvo_catalog_catmode (CATMODE);
-    inDB.format = dvo_catalog_catformat (CATFORMAT);
-    status       = dvo_image_lock (&inDB, ImageCat, 3600.0, LCK_XCLD);  // shorter timeout?
-    if (!status) Shutdown ("ERROR: failure to lock image catalog %s", inDB.filename);
-
-    // load the image table 
-    if (inDB.dbstate == LCK_EMPTY) {
-      Shutdown ("can't find input (1) image catalog %s", inDB.filename);
-    }
-    if (!dvo_image_load (&inDB, VERBOSE, TRUE)) {
-      Shutdown ("can't read input (1) image catalog %s", inDB.filename);
-    }
-
-    /*** load output/Images.dat ***/
-    sprintf (ImageCat, "%s/Images.dat", output);
-    outDB.mode   = dvo_catalog_catmode (CATMODE);
-    outDB.format = dvo_catalog_catformat (CATFORMAT);
-    status       = dvo_image_lock (&outDB, ImageCat, 3600.0, LCK_XCLD);  // shorter timeout?
-    if (!status) Shutdown ("ERROR: failure to lock image catalog %s", outDB.filename);
-
-    /* load the image table */
-    if (outDB.dbstate == LCK_EMPTY) {
-      Shutdown ("can't find input (2) image catalog %s", outDB.filename);
-    }
-    if (!dvo_image_load (&outDB, VERBOSE, TRUE)) {
-      Shutdown ("can't read input (2) image catalog %s", outDB.filename);
-    }
-
-    // convert database table to internal structure & add to output image db
-    dvo_image_merge_dbs(&outDB, &inDB);
-    dvo_image_unlock (&inDB); // unlock input
-
-    SetProtect (TRUE);
-    dvo_image_save (&outDB, VERBOSE);
-    SetProtect (FALSE);
-    dvo_image_unlock (&outDB); // unlock output
-  }
-
   exit (0);
 }
 
-/* 
+/*** update the image table ***/
+int dvomergeImagesUpdate (IDmapType *IDmap, char *input, char *output) { 
 
-   for the upgrade of the synth database, at a minimum I need to use an output format that uses
-   doubles for the astrometry.  Optionally I should merge in the 2MASS photometry measurements, since that
-   would be quite useful for comparison.  
+  FITS_DB inDB;
+  FITS_DB outDB;
+  int    status;
 
-   generality questions:
-   * optional
+  /*** load input1/Images.dat ***/
+  sprintf (ImageCat, "%s/Images.dat", input);
+  inDB.mode   = dvo_catalog_catmode (CATMODE);
+  inDB.format = dvo_catalog_catformat (CATFORMAT);
+  status       = dvo_image_lock (&inDB, ImageCat, 3600.0, LCK_XCLD);  // shorter timeout?
+  if (!status) Shutdown ("ERROR: failure to lock image catalog %s", inDB.filename);
 
+  // load the image table 
+  if (inDB.dbstate == LCK_EMPTY) {
+    Shutdown ("can't find input (1) image catalog %s", inDB.filename);
+  }
+  if (!dvo_image_load (&inDB, VERBOSE, TRUE)) {
+    Shutdown ("can't read input (1) image catalog %s", inDB.filename);
+  }
 
+  /*** load output/Images.dat ***/
+  sprintf (ImageCat, "%s/Images.dat", output);
+  outDB.mode   = dvo_catalog_catmode (CATMODE);
+  outDB.format = dvo_catalog_catformat (CATFORMAT);
+  status       = dvo_image_lock (&outDB, ImageCat, 3600.0, LCK_XCLD);  // shorter timeout?
+  if (!status) Shutdown ("ERROR: failure to lock image catalog %s", outDB.filename);
 
-   */
+  /* load the image table */
+  if (outDB.dbstate == LCK_EMPTY) {
+    Shutdown ("can't find input (2) image catalog %s", outDB.filename);
+  }
+  if (!dvo_image_load (&outDB, VERBOSE, TRUE)) {
+    Shutdown ("can't read input (2) image catalog %s", outDB.filename);
+  }
 
+  // convert database table to internal structure & add to output image db
+  dvo_image_merge_dbs(IDmap, &outDB, &inDB);
+  dvo_image_unlock (&inDB); // unlock input
+
+  SetProtect (TRUE);
+  dvo_image_save (&outDB, VERBOSE);
+  SetProtect (FALSE);
+  dvo_image_unlock (&outDB); // unlock output
+
+  return TRUE;
+}
Index: /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/merge_catalogs_new.c
===================================================================
--- /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/merge_catalogs_new.c	(revision 27396)
+++ /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/merge_catalogs_new.c	(revision 27397)
@@ -64,4 +64,10 @@
   output[0].Nmeasure = Nmeasure;
   output[0].Nsecf_mem = Naverage * Nsecfilt;
+
+  // If we are using dvomergeCreate to split an existing catalog, then the max objID in
+  // each of the new subdivisions of the original catalog is the max objID of the original
+  // catalog.  It is not allowed to use dvomerge to unify catalogs to a lower-resolution
+  // partition.
+  output[0].objID = input[0].objID; // new max value, save on catalog close
   
   if (VERBOSE) {
