Index: /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/Makefile
===================================================================
--- /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/Makefile	(revision 27383)
+++ /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/Makefile	(revision 27384)
@@ -22,8 +22,12 @@
 DVOMERGE = \
 $(SRC)/dvomerge.$(ARCH).o \
+$(SRC)/dvomergeUpdate.$(ARCH).o \
+$(SRC)/dvomergeCreate.$(ARCH).o \
 $(SRC)/SetSignals.$(ARCH).o \
 $(SRC)/ConfigInit.$(ARCH).o \
 $(SRC)/Shutdown.$(ARCH).o \
-$(SRC)/usage.$(ARCH).o \
+$(SRC)/help.$(ARCH).o \
+$(SRC)/args.$(ARCH).o \
+$(SRC)/psps_ids.$(ARCH).o \
 $(SRC)/SkyTablePopulatedRange.$(ARCH).o \
 $(SRC)/LoadCatalog.$(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 27383)
+++ /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/include/dvomerge.h	(revision 27384)
@@ -22,4 +22,5 @@
 char   CATMODE[16];    /* raw, mef, split, mysql */
 char   CATFORMAT[16];  /* internal, elixir, loneos, panstarrs */
+char   ImageCat[256];
 float  RADIUS;
 int    SKY_DEPTH;
@@ -28,4 +29,6 @@
 
 int        main                   PROTO((int argc, char **argv));
+int        dvomergeCreate         PROTO((int argc, char **argv));
+int        dvomergeUpdate         PROTO((int argc, char **argv));
 
 int        ConfigInit             PROTO((int *argc, char **argv));
@@ -38,8 +41,11 @@
 
 void       usage                  PROTO((void));
-int        SkyTablePopulatedRange PROTO((int *ns, int *ne, SkyTable *sky, int Nstart));
+void 	   help 		  PROTO((int argc, char **argv));
+int  	   args 		  PROTO((int *argc, char **argv));
+
+int        SkyTablePopulatedRange PROTO((off_t *ns, off_t *ne, SkyTable *sky, off_t Nstart));
 
 SkyList   *SkyTablePopulatedList  PROTO((SkyTable *sky));
-SkyList   *SkyTablePopulatedList_old  PROTO((SkyTable *sky, int Ns, int Ne));
+SkyList   *SkyTablePopulatedList_old  PROTO((SkyTable *sky, off_t Ns, off_t Ne));
 
 int        LoadCatalog            PROTO((Catalog *catalog, SkyRegion *region, char *filename, char *mode));
@@ -48,9 +54,15 @@
 int        merge_catalogs_old     PROTO((SkyRegion *region, Catalog *output, Catalog *input, double RADIUS));
 
-int 	  *init_measure_links     PROTO((Average *average, int Naverage, Measure *measure, int Nmeasure));
-int 	  *init_missing_links     PROTO((Average *average, int Naverage, Missing *missing, int Nmissing));
-int 	  *build_measure_links    PROTO((Average *average, int Naverage, Measure *measure, int Nmeasure));
-int 	   add_meas_link     	  PROTO((Average *average, int *next, int Nmeasure, int NMEASURE));
-int 	   add_miss_link     	  PROTO((Average *average, int *next, int Nmissing));
-Measure   *sort_measure     	  PROTO((Average *average, int Naverage, Measure *measure, int Nmeasure, int *next));
-Missing   *sort_missing     	  PROTO((Average *average, int Naverage, Missing *missing, int Nmissing, int *next_miss));
+off_t 	  *init_measure_links     PROTO((Average *average, off_t Naverage, Measure *measure, off_t Nmeasure));
+off_t 	  *init_missing_links     PROTO((Average *average, off_t Naverage, Missing *missing, off_t Nmissing));
+off_t 	  *build_measure_links    PROTO((Average *average, off_t Naverage, Measure *measure, off_t Nmeasure));
+int   	   add_meas_link     	  PROTO((Average *average, off_t *next, off_t Nmeasure, off_t NMEASURE));
+int   	   add_miss_link     	  PROTO((Average *average, off_t *next, off_t Nmissing));
+Measure   *sort_measure     	  PROTO((Average *average, off_t Naverage, Measure *measure, off_t Nmeasure, off_t *next));
+Missing   *sort_missing     	  PROTO((Average *average, off_t Naverage, Missing *missing, off_t Nmissing, off_t *next_miss));
+
+uint64_t   CreatePSPSDetectionID  PROTO((double tobs, int ccdid, int detID));
+uint64_t   CreatePSPSObjectID     PROTO((double ra, double dec));
+
+int        dvo_image_merge_dbs    PROTO((FITS_DB *out, FITS_DB *in));
+
Index: /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/ConfigInit.c
===================================================================
--- /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/ConfigInit.c	(revision 27383)
+++ /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/ConfigInit.c	(revision 27384)
@@ -4,10 +4,10 @@
 
   double ZERO_POINT;
+  char RadiusWord[80];
   char *config, *file;
-  char CatdirPhotcodeFile[256];
-  char MasterPhotcodeFile[256];
 
   /*** load configuration info ***/
   file = SelectConfigFile (argc, argv, "ptolemy");
+
   config = LoadConfigFile (file);
   if (config == (char *) NULL) {
@@ -18,9 +18,8 @@
   if (VERBOSE) fprintf (stderr, "loaded config file: %s\n", file);
 
-  GetConfig (config, "PHOTCODE_FILE",          	"%s",  0, MasterPhotcodeFile);
+
   GetConfig (config, "GSCFILE",                	"%s",  0, GSCFILE);
   ScanConfig (config, "CATMODE",                "%s",  0, CATMODE);
   ScanConfig (config, "CATFORMAT",              "%s",  0, CATFORMAT);
-  ScanConfig (config, "RADIUS",                 "%f",  0, &RADIUS);
   GetConfig (config, "SKY_DEPTH",              "%d",  0, &SKY_DEPTH);
   if (SKY_DEPTH > 4) {
@@ -36,4 +35,9 @@
   SetZeroPoint (ZERO_POINT);
 
+  /* set the default search radius */
+  if (!ScanConfig (config, "ADDSTAR_RADIUS", "%s", 0, RadiusWord)) {
+    GetConfig (config, "RADIUS", "%s", 0, RadiusWord);
+  }
+  RADIUS = atof (RadiusWord);
   if (RADIUS < 1e-6) {
       fprintf (stderr, "non-sensical correlation radius %f\n", RADIUS);
Index: /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/SkyTablePopulatedRange.c
===================================================================
--- /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/SkyTablePopulatedRange.c	(revision 27383)
+++ /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/SkyTablePopulatedRange.c	(revision 27384)
@@ -1,7 +1,7 @@
 # include "dvomerge.h"
 
-int SkyTablePopulatedRange (int *ns, int *ne, SkyTable *sky, int Nstart) {
+int SkyTablePopulatedRange (off_t *ns, off_t *ne, SkyTable *sky, off_t Nstart) {
 
-  int Ns, Ne;
+  off_t Ns, Ne;
 
   // given the starting sky region, find the populated range at or below this region
@@ -26,6 +26,6 @@
 SkyList *SkyTablePopulatedList (SkyTable *sky) {
 
-  int i, N, NREGIONS;
-  SkyList *list, *subset;
+  off_t i, N, NREGIONS;
+  SkyList *list;
 
   N = 0;
@@ -54,7 +54,7 @@
 }
 
-SkyList *SkyTablePopulatedList_old (SkyTable *sky, int Ns, int Ne) {
+SkyList *SkyTablePopulatedList_old (SkyTable *sky, off_t Ns, off_t Ne) {
 
-  int i, ns, ne, N, NREGIONS;
+  off_t i, ns, ne, N, NREGIONS;
   SkyList *list, *subset;
 
Index: /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/args.c
===================================================================
--- /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/args.c	(revision 27383)
+++ /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/args.c	(revision 27384)
@@ -1,16 +1,8 @@
 # include "dvomerge.h"
-static void help (void);
 
-int args (int argc, char **argv) {
+/*** check for command line options ***/
+int args (int *argc, char **argv) {
   
-  int i, N, CONFIRM;
-
-  /* check for help request */
-  if (get_argument (argc, argv, "-help") ||
-      get_argument (argc, argv, "-h")) {
-    help ();
-  }
-
-  /*** check for command line options ***/
+  int N, CONFIRM;
 
   /*** provide additional data ***/ 
@@ -21,14 +13,14 @@
   UserPatch.Dmax = +90;
   CONFIRM = TRUE;
-  if ((N = get_argument (argc, argv, "-region"))) {
-    remove_argument (N, &argc, argv);
+  if ((N = get_argument (*argc, argv, "-region"))) {
+    remove_argument (N, argc, argv);
     UserPatch.Rmin = atof (argv[N]);
-    remove_argument (N, &argc, argv);
+    remove_argument (N, argc, argv);
     UserPatch.Rmax = atof (argv[N]);
-    remove_argument (N, &argc, argv);
+    remove_argument (N, argc, argv);
     UserPatch.Dmin = atof (argv[N]);
-    remove_argument (N, &argc, argv);
+    remove_argument (N, argc, argv);
     UserPatch.Dmax = atof (argv[N]);
-    remove_argument (N, &argc, argv);
+    remove_argument (N, argc, argv);
     CONFIRM = FALSE;
   }
@@ -36,52 +28,10 @@
   /* extra error messages */
   VERBOSE = FALSE;
-  if ((N = get_argument (argc, argv, "-v"))) {
+  if ((N = get_argument (*argc, argv, "-v"))) {
     VERBOSE = TRUE;
-    remove_argument (N, &argc, argv);
+    remove_argument (N, argc, argv);
   }
 
-  if (argc == 2) {
-    if (CONFIRM) {
-      fprintf (stderr, "you are splitting the entire sky in one pass\n");
-      fprintf (stderr, "this could be a time consuming operation.  type Ctrl-C within 5 seconds to cancel\n");
-      for (i = 5; i > 0; i--) {
-	fprintf (stderr, "%d.. ", i);
-	usleep (1000000);
-      }
-      fprintf (stderr, "\n");
-    }    
-    return (TRUE);
-  }
-
-  fprintf (stderr, "USAGE: dvosplit (newlevel) [-region (Rmin) (Rmax) (Dmin) (Dmax)]\n");
-  exit (2);
+  if ((*argc != 6) && (*argc != 4)) usage();
+  return TRUE;
 }
-
-static void help () {
-
-  fprintf (stderr, "USAGE\n");
-  fprintf (stderr, "  dvosplit (newlevel)\n\n");
-  fprintf (stderr, "  optional flags:\n");
-  fprintf (stderr, "  -region ra ra dec dec 	  : migrate catalogs in specified region\n");
-  fprintf (stderr, "  -v                    	  : verbose mode\n");
-  fprintf (stderr, "  -help                 	  : this list\n");
-  fprintf (stderr, "  -h                    	  : this list\n\n");
-  exit (2);
-}
-
-/** addstar modes:
- 
-    addstar (image.smp)  - add cmp/smp image data to db
-    addstar -ref (file.dat) (photcode) 
-    addstar -cat (USNO/2MASS/GSC) -region (ra dec - ra dec)
-
-    -replace : ref/cat - replace existing match (photcode/time)
-    -match   : ref/cat - only add measures to existing averages
-
-    ref types: 
-    ASCII - RA,DEC,M,dM in a table
-
-    addstar 
-
-**/
-
Index: /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/build_links.c
===================================================================
--- /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/build_links.c	(revision 27383)
+++ /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/build_links.c	(revision 27384)
@@ -3,12 +3,12 @@
 /* build the initial links assuming the table is sorted, 
    not partial, and has a correct set of average[].measureOffset,Nmeasure values */
-int *init_measure_links (Average *average, int Naverage, Measure *measure, int Nmeasure) {
-
-  int i, j, N;
-  int *next;
+off_t *init_measure_links (Average *average, off_t Naverage, Measure *measure, off_t Nmeasure) {
+
+  off_t i, j, N;
+  off_t *next;
 
   N = 0;
 
-  ALLOCATE (next, int, Nmeasure);
+  ALLOCATE (next, off_t, Nmeasure);
   for (i = 0; i < Naverage; i++, N++) {
     for (j = 0; j < average[i].Nmeasure - 1; j++, N++) {
@@ -31,13 +31,114 @@
 }
 
+/* average[].measureOffset, average[].Nmeasure are valid within an addstar run */
+int add_meas_link (Average *average, off_t *next, off_t Nmeasure, off_t NMEASURE) {
+
+  off_t k, m;
+
+  /* if we have trouble, check validity of next[m] : m < Nmeasure */
+  m = average[0].measureOffset;  
+
+  for (k = 0; k < average[0].Nmeasure - 1; k++)  {
+    m = next[m];
+    if (m >= NMEASURE) {
+      fprintf (stderr, "WARNING: m out of bounds (3)\n");
+    }
+  }
+
+  /* set up references */
+  next[Nmeasure] = -1;
+  if (Nmeasure >= NMEASURE) {
+    fprintf (stderr, "WARNING: Nmeasure out of bounds (1)\n");
+  }
+
+  if (m == -1) {
+    average[0].measureOffset = Nmeasure;
+  } else {
+    next[m] = Nmeasure;
+    if (m >= NMEASURE) {
+      fprintf (stderr, "WARNING: m out of bounds (4)\n");
+    }
+  }
+
+  return (TRUE);
+}
+
+Measure *sort_measure (Average *average, off_t Naverage, Measure *measure, off_t Nmeasure, off_t *next) {
+
+  off_t i, k, n, N;
+  Measure *tmpmeasure;
+
+  /* fix order of Measure (memory intensive, but fast) */
+  N = 0; 
+  ALLOCATE (tmpmeasure, Measure, Nmeasure);
+  for (i = 0; i < Naverage; i++) {
+    n = average[i].measureOffset;
+    average[i].measureOffset = N;
+    for (k = 0; k < average[i].Nmeasure; k++, N++) {
+      tmpmeasure[N] = measure[n]; 
+      tmpmeasure[N].averef = i;
+      n = next[n];
+    }
+  }
+  free (measure);
+  return (tmpmeasure);
+}
+
+/* construct measure links which are valid FOR THIS LOAD
+ * - if we have a full load, we will get links which can
+ *   be used by other programs (eg, relphot, etc)
+ * - if we have a partial load, the links are only valid
+ *   for that partial load
+ */ 
+
+off_t *build_measure_links (Average *average, off_t Naverage, Measure *measure, off_t Nmeasure) {
+
+  off_t i, m, k, Nm, averef;
+  off_t *next;
+
+  ALLOCATE (next, off_t, Nmeasure);
+
+  /* reset the Nm, offset values for average */
+  for (i = 0; i < Naverage; i++) {
+    average[i].measureOffset = -1;
+    average[i].Nmeasure     =  0;
+  }
+
+  for (Nm = 0; Nm < Nmeasure; Nm++) {
+    averef = measure[Nm].averef;
+    m = average[averef].measureOffset;  
+    next[Nm] = -1;
+
+    if (m == -1) { /* no links yet for source */
+      average[averef].measureOffset = Nm;
+      average[averef].Nmeasure     = 1;
+      continue;
+    }
+
+    for (k = 0; next[m] != -1; k++) {
+      m = next[m];
+      if (m >= Nmeasure) {
+	fprintf (stderr, "WARNING: m out of bounds (1)\n");
+      }
+    }
+
+    average[averef].Nmeasure = k + 2;
+    next[m] = Nm;
+    if (m >= Nmeasure) {
+      fprintf (stderr, "WARNING: m out of bounds (2)\n");
+    }
+  }
+  return (next);
+}
+
 /* build the initial links assuming the table is sorted */
-int *init_missing_links (Average *average, int Naverage, Missing *missing, int Nmissing) {
-
-  int i, j, N;
-  int *next;
+off_t *init_missing_links (Average *average, off_t Naverage, Missing *missing, off_t Nmissing) {
+
+  off_t i, j, N;
+  off_t *next;
 
   N = 0;
 
-  ALLOCATE (next, int, Nmissing);
+  ALLOCATE (next, off_t, Nmissing);
   for (i = 0; i < Naverage; i++) {
     for (j = 0; j < average[i].Nmissing - 1; j++, N++) {
@@ -57,40 +158,7 @@
 }
 
-/* average[].measureOffset, average[].Nmeasure are valid within an addstar run */
-int add_meas_link (Average *average, int *next, int Nmeasure, int NMEASURE) {
-
-  int k, m;
-
-  /* if we have trouble, check validity of next[m] : m < Nmeasure */
-  m = average[0].measureOffset;  
-
-  for (k = 0; k < average[0].Nmeasure - 1; k++)  {
-    m = next[m];
-    if (m >= NMEASURE) {
-      fprintf (stderr, "WARNING: m out of bounds (3)\n");
-    }
-  }
-
-  /* set up references */
-  next[Nmeasure] = -1;
-  if (Nmeasure >= NMEASURE) {
-    fprintf (stderr, "WARNING: Nmeasure out of bounds (1)\n");
-  }
-
-  if (m == -1) {
-    average[0].measureOffset = Nmeasure;
-  } else {
-    next[m] = Nmeasure;
-    if (m >= NMEASURE) {
-      fprintf (stderr, "WARNING: m out of bounds (4)\n");
-    }
-  }
-
-  return (TRUE);
-}
-
-int add_miss_link (Average *average, int *next, int Nmissing) {
-
-  int k, m;
+int add_miss_link (Average *average, off_t *next, off_t Nmissing) {
+
+  off_t k, m;
 
   /* there may be 0 Nmiss; this is not true for Nmeas */
@@ -109,78 +177,10 @@
 }
 
-/* construct measure links which are valid FOR THIS LOAD
- * - if we have a full load, we will get links which can
- *   be used by other programs (eg, relphot, etc)
- * - if we have a partial load, the links are only valid
- *   for that partial load
- */ 
-
-int *build_measure_links (Average *average, int Naverage, Measure *measure, int Nmeasure) {
-
-  int i, m, k, Nm, averef;
-  int *next;
-
-  ALLOCATE (next, int, Nmeasure);
-
-  /* reset the Nm, offset values for average */
-  for (i = 0; i < Naverage; i++) {
-    average[i].measureOffset = -1;
-    average[i].Nmeasure     =  0;
-  }
-
-  for (Nm = 0; Nm < Nmeasure; Nm++) {
-    averef = measure[Nm].averef;
-    m = average[averef].measureOffset;  
-    next[Nm] = -1;
-
-    if (m == -1) { /* no links yet for source */
-      average[averef].measureOffset = Nm;
-      average[averef].Nmeasure     = 1;
-      continue;
-    }
-
-    for (k = 0; next[m] != -1; k++) {
-      m = next[m];
-      if (m >= Nmeasure) {
-	fprintf (stderr, "WARNING: m out of bounds (1)\n");
-      }
-    }
-
-    average[averef].Nmeasure = k + 2;
-    next[m] = Nm;
-    if (m >= Nmeasure) {
-      fprintf (stderr, "WARNING: m out of bounds (2)\n");
-    }
-  }
-  return (next);
-}
-
 /* Missing does not carry enough information to reconstruct the links
    we must always save the missing table, if it exists */
 
-Measure *sort_measure (Average *average, int Naverage, Measure *measure, int Nmeasure, int *next) {
-
-  int i, k, n, N;
-  Measure *tmpmeasure;
-
-  /* fix order of Measure (memory intensive, but fast) */
-  N = 0; 
-  ALLOCATE (tmpmeasure, Measure, Nmeasure);
-  for (i = 0; i < Naverage; i++) {
-    n = average[i].measureOffset;
-    average[i].measureOffset = N;
-    for (k = 0; k < average[i].Nmeasure; k++, N++) {
-      tmpmeasure[N] = measure[n]; 
-      tmpmeasure[N].averef = i;
-      n = next[n];
-    }
-  }
-  free (measure);
-  return (tmpmeasure);
-}
-
-Missing *sort_missing (Average *average, int Naverage, Missing *missing, int Nmissing, int *next) {
-
-  int i, k, n, N;
+Missing *sort_missing (Average *average, off_t Naverage, Missing *missing, off_t Nmissing, off_t *next) {
+
+  off_t i, k, n, N;
   Missing *tmpmissing;
 
Index: /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/dvomerge.c
===================================================================
--- /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/dvomerge.c	(revision 27383)
+++ /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/dvomerge.c	(revision 27384)
@@ -1,140 +1,21 @@
 # include "dvomerge.h"
 
-// dvomerge (catdir.in1) and (catdir.in2) to (catdir.output) [-region Rmin Rmax Dmin Dmax] [
-// merge sources from (catdir.from) into (catdir.to)
 int main (int argc, char **argv) {
 
-  int i, j, Ns, Ne, depth1, depth2;
-  SkyTable *outsky, *insky1, *insky2;
-  SkyList *inlist;
-  Catalog incatalog, outcatalog;
-  char filename[256], *input1, *input2, *output;
+  SetSignals ();
+  help (argc, argv);
+  ConfigInit (&argc, argv);
+  args (&argc, argv);
 
-  SetSignals ();
-  ConfigInit (&argc, argv);
-
-  if (argc != 6) usage();
-  if (strcasecmp (argv[2], "and")) usage();
-  if (strcasecmp (argv[4], "to")) usage();
-
-  input1 = argv[1];
-  input2 = argv[3];
-  output = argv[5];
-
-  // the first input define the photcode table & db layout
-  sprintf (filename, "%s/Photcodes.dat", input1);
-  if (!LoadPhotcodes (filename, NULL, FALSE)) {
-    fprintf (stderr, "error loading photcode table %s\n", filename);
-    exit (1);
-  }
-  // save the photcodes in the output catdir
-  sprintf (filename, "%s/Photcodes.dat", output);
-  if (!check_file_access (filename, TRUE, TRUE, TRUE)) {
-    fprintf (stderr, "error creating output catdir %s\n", output);
-    exit (1);
-  }
-  if (!SavePhotcodesFITS (filename)) {
-    fprintf (stderr, "error saving photcode table %s\n", filename);
-    exit (1);
-  }
-
-  // load the sky table for the existing database
-  insky1 = SkyTableLoadOptimal (input1, NULL, NULL, FALSE, SKY_DEPTH_HST, VERBOSE);
-  SkyTableSetFilenames (insky1, input1, "cpt");
-
-  insky2 = SkyTableLoadOptimal (input2, NULL, NULL, FALSE, SKY_DEPTH_HST, VERBOSE);
-  SkyTableSetFilenames (insky2, input2, "cpt");
-
-  // generate an output table populated at the desired depth
-  outsky = SkyTableLoadOptimal (output, NULL, GSCFILE, TRUE, SKY_DEPTH, VERBOSE);
-  SkyTableSetFilenames (outsky, output, "cpt");
-
-  // loop over the populatable output tables; check for data in input1 and/or input2
-  // in the corresponding regions
-
-  SkyTablePopulatedRange (&Ns, &Ne, insky1, 0);
-  depth1 = insky1[0].regions[Ns].depth;
-  
-  SkyTablePopulatedRange (&Ns, &Ne, insky2, 0);
-  depth2 = insky2[0].regions[Ns].depth;
-
-  // loop over the populatable output regions
-  for (i = 0; i < outsky[0].Nregions; i++) {
-    if (!outsky[0].regions[i].table) continue;
-    fprintf (stderr, "output: %s\n", outsky[0].regions[i].name);
-
-    // load / create output catalog
-    LoadCatalog (&outcatalog, &outsky[0].regions[i], outsky[0].filename[i], "w");
-
-    // combine only tables at equal or larger depth
-      
-    // load in all of the tables from input1 for this region
-    inlist = SkyListByBounds (insky1, depth1, outsky[0].regions[i].Rmin, outsky[0].regions[i].Rmax, outsky[0].regions[i].Dmin, outsky[0].regions[i].Dmax);
-    for (j = 0; j < inlist[0].Nregions; j++) {
-      fprintf (stderr, "input 1: %s\n", inlist[0].regions[j][0].name);
-
-      // load input catalog (1)
-      LoadCatalog (&incatalog, inlist[0].regions[j], inlist[0].filename[j], "r");
-
-      // skip empty input catalogs
-      if (!incatalog.Naves_disk) {
-	dvo_catalog_unlock (&incatalog);
-	dvo_catalog_free (&incatalog);
-	continue;
-      }
-      merge_catalogs_new (&outsky[0].regions[i], &outcatalog, &incatalog);
-      dvo_catalog_unlock (&incatalog);
-      dvo_catalog_free (&incatalog);
-    }
-    SkyListFree (inlist);
-
-    // load in all of the tables from input2 for this region
-    inlist = SkyListByBounds (insky2, depth2, outsky[0].regions[i].Rmin, outsky[0].regions[i].Rmax, outsky[0].regions[i].Dmin, outsky[0].regions[i].Dmax);
-    for (j = 0; j < inlist[0].Nregions; j++) {
-      fprintf (stderr, "input 2: %s\n", inlist[0].regions[j][0].name);
-
-      // load input catalog (1)
-      LoadCatalog (&incatalog, inlist[0].regions[j], inlist[0].filename[j], "r");
-
-      // skip empty input catalogs
-      if (!incatalog.Naves_disk) {
-	dvo_catalog_unlock (&incatalog);
-	dvo_catalog_free (&incatalog);
-	continue;
-      }
-      merge_catalogs_old (&outsky[0].regions[i], &outcatalog, &incatalog, RADIUS);
-      dvo_catalog_unlock (&incatalog);
-      dvo_catalog_free (&incatalog);
-    }
-    SkyListFree (inlist);
-
-    outcatalog.catflags = LOAD_AVES | LOAD_MEAS | LOAD_MISS | LOAD_SECF;
-    dvo_catalog_save (&outcatalog, VERBOSE);
-    dvo_catalog_unlock (&outcatalog);
-    dvo_catalog_free (&outcatalog);
-  }
-
-  // save the output sky table copy
-  sprintf (filename, "%s/SkyTable.fits", output);
-  check_file_access (filename, TRUE, TRUE, VERBOSE);
-  if (!SkyTableSave (outsky, filename)) {
-    fprintf (stderr, "ERROR: failed to save sky table for %s\n", output);
-    exit (1);
-  }
-
-  exit (0);
+  if (argc == 6) dvomergeCreate (argc, argv);
+  if (argc == 4) dvomergeUpdate (argc, argv);
+  usage();
+  exit (2); // cannot reach here.
 }
 
-/* 
+/* we have two possible modes of operation:
 
-   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.  
+   Create : dvomerge (in1) and (in2) to (out) -- create a new db from two input dbs
+   Update : dvomerge (in) into (out)          -- merge a new db into an existing db
 
-   generality questions:
-   * optional
-
-
-
-   */
-
+*/
Index: /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/dvomergeCreate.c
===================================================================
--- /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/dvomergeCreate.c	(revision 27384)
+++ /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/dvomergeCreate.c	(revision 27384)
@@ -0,0 +1,215 @@
+# include "dvomerge.h"
+
+// dvomergeCreate (catdir.in1) and (catdir.in2) to (catdir.output)
+// the output db may have a different SKY_DEPTH from the input dbs
+int dvomergeCreate (int argc, char **argv) {
+
+  int depth1, depth2;
+  off_t i, j, Ns, Ne;
+  SkyTable *outsky, *insky1, *insky2;
+  SkyList *inlist;
+  Catalog incatalog, outcatalog;
+  char filename[256], *input1, *input2, *output;
+
+  if (strcasecmp (argv[2], "and")) usage();
+  if (strcasecmp (argv[4], "to")) usage();
+
+  input1 = argv[1];
+  input2 = argv[3];
+  output = argv[5];
+
+  // the first input defines the photcode table & db layout
+  sprintf (filename, "%s/Photcodes.dat", input1);
+  if (!LoadPhotcodes (filename, NULL, FALSE)) {
+    fprintf (stderr, "error loading photcode table %s\n", filename);
+    exit (1);
+  }
+  // save the photcodes in the output catdir
+  sprintf (filename, "%s/Photcodes.dat", output);
+  if (!check_file_access (filename, TRUE, TRUE, VERBOSE)) {
+    fprintf (stderr, "error creating output catdir %s\n", output);
+    exit (1);
+  }
+  if (!SavePhotcodesFITS (filename)) {
+    fprintf (stderr, "error saving photcode table %s\n", filename);
+    exit (1);
+  }
+
+  // load the sky table for the existing database
+  insky1 = SkyTableLoadOptimal (input1, NULL, NULL, FALSE, SKY_DEPTH_HST, VERBOSE);
+  SkyTableSetFilenames (insky1, input1, "cpt");
+
+  insky2 = SkyTableLoadOptimal (input2, NULL, NULL, FALSE, SKY_DEPTH_HST, VERBOSE);
+  SkyTableSetFilenames (insky2, input2, "cpt");
+
+  // generate an output table populated at the desired depth
+  outsky = SkyTableLoadOptimal (output, NULL, GSCFILE, TRUE, SKY_DEPTH, VERBOSE);
+  SkyTableSetFilenames (outsky, output, "cpt");
+
+  // loop over the populatable output tables; check for data in input1 and/or input2
+  // in the corresponding regions
+
+  SkyTablePopulatedRange (&Ns, &Ne, insky1, 0);
+  depth1 = insky1[0].regions[Ns].depth;
+  
+  SkyTablePopulatedRange (&Ns, &Ne, insky2, 0);
+  depth2 = insky2[0].regions[Ns].depth;
+
+  // loop over the populatable output regions
+  for (i = 0; i < outsky[0].Nregions; i++) {
+    if (!outsky[0].regions[i].table) continue;
+    if (VERBOSE) fprintf (stderr, "output: %s\n", outsky[0].regions[i].name);
+
+    // load / create output catalog
+    LoadCatalog (&outcatalog, &outsky[0].regions[i], outsky[0].filename[i], "w");
+
+    // combine only tables at equal or larger depth
+      
+    // load in all of the tables from input1 for this region
+    inlist = SkyListByBounds (insky1, depth1, outsky[0].regions[i].Rmin, outsky[0].regions[i].Rmax, outsky[0].regions[i].Dmin, outsky[0].regions[i].Dmax);
+    for (j = 0; j < inlist[0].Nregions; j++) {
+      if (VERBOSE) fprintf (stderr, "input 1: %s\n", inlist[0].regions[j][0].name);
+
+      // load input catalog (1)
+      LoadCatalog (&incatalog, inlist[0].regions[j], inlist[0].filename[j], "r");
+
+      // skip empty input catalogs
+      if (!incatalog.Naves_disk) {
+	dvo_catalog_unlock (&incatalog);
+	dvo_catalog_free (&incatalog);
+	continue;
+      }
+      merge_catalogs_new (&outsky[0].regions[i], &outcatalog, &incatalog);
+      dvo_catalog_unlock (&incatalog);
+      dvo_catalog_free (&incatalog);
+    }
+    SkyListFree (inlist);
+
+    // load in all of the tables from input2 for this region
+    inlist = SkyListByBounds (insky2, depth2, outsky[0].regions[i].Rmin, outsky[0].regions[i].Rmax, outsky[0].regions[i].Dmin, outsky[0].regions[i].Dmax);
+    for (j = 0; j < inlist[0].Nregions; j++) {
+      if (VERBOSE) fprintf (stderr, "input 2: %s\n", inlist[0].regions[j][0].name);
+
+      // load input catalog (1)
+      LoadCatalog (&incatalog, inlist[0].regions[j], inlist[0].filename[j], "r");
+
+      // skip empty input catalogs
+      if (!incatalog.Naves_disk) {
+	dvo_catalog_unlock (&incatalog);
+	dvo_catalog_free (&incatalog);
+	continue;
+      }
+      merge_catalogs_old (&outsky[0].regions[i], &outcatalog, &incatalog, RADIUS);
+      dvo_catalog_unlock (&incatalog);
+      dvo_catalog_free (&incatalog);
+    }
+    SkyListFree (inlist);
+
+    outcatalog.catflags = LOAD_AVES | LOAD_MEAS | LOAD_MISS | LOAD_SECF;
+    dvo_catalog_save (&outcatalog, VERBOSE);
+    dvo_catalog_unlock (&outcatalog);
+    dvo_catalog_free (&outcatalog);
+  }
+
+  // save the output sky table copy
+  sprintf (filename, "%s/SkyTable.fits", output);
+  check_file_access (filename, TRUE, TRUE, VERBOSE);
+  if (!SkyTableSave (outsky, filename)) {
+    fprintf (stderr, "ERROR: failed to save sky table for %s\n", output);
+    exit (1);
+  }
+
+  /*** update the image table ***/
+  { 
+    FITS_DB in1DB;
+    FITS_DB in2DB;
+    FITS_DB outDB;
+    int    status;
+
+    /*** 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);
+
+    // output image table should not already exist
+    if (outDB.dbstate != LCK_EMPTY) {
+      Shutdown ("ERROR: image table %s already exists", outDB.filename);
+    }
+    dvo_image_create (&outDB, GetZeroPoint());
+
+
+    /*** load input1/Images.dat ***/
+    sprintf (ImageCat, "%s/Images.dat", input1);
+    in1DB.mode   = dvo_catalog_catmode (CATMODE);
+    in1DB.format = dvo_catalog_catformat (CATFORMAT);
+    status       = dvo_image_lock (&in1DB, ImageCat, 3600.0, LCK_XCLD);  // shorter timeout?
+    if (!status) Shutdown ("ERROR: failure to lock image catalog %s", in1DB.filename);
+
+    // load the image table 
+    if (in1DB.dbstate == LCK_EMPTY) {
+      Shutdown ("can't find input (1) image catalog %s", in1DB.filename);
+    }
+    if (!dvo_image_load (&in1DB, VERBOSE, TRUE)) {
+      Shutdown ("can't read input (1) image catalog %s", in1DB.filename);
+    }
+
+    // convert database table to internal structure & add to output image db
+    dvo_image_merge_dbs(&outDB, &in1DB);
+    dvo_image_unlock (&in1DB); // unlock input1
+
+
+    /*** load input2/Images.dat ***/
+    sprintf (ImageCat, "%s/Images.dat", input2);
+    in2DB.mode   = dvo_catalog_catmode (CATMODE);
+    in2DB.format = dvo_catalog_catformat (CATFORMAT);
+    status       = dvo_image_lock (&in2DB, ImageCat, 3600.0, LCK_XCLD);  // shorter timeout?
+    if (!status) Shutdown ("ERROR: failure to lock image catalog %s", in2DB.filename);
+
+    /* load the image table */
+    if (in2DB.dbstate == LCK_EMPTY) {
+      Shutdown ("can't find input (2) image catalog %s", in2DB.filename);
+    }
+    if (!dvo_image_load (&in2DB, VERBOSE, TRUE)) {
+      Shutdown ("can't read input (2) image catalog %s", in2DB.filename);
+    }
+
+    // convert database table to internal structure & add to output image db
+    dvo_image_merge_dbs(&outDB, &in2DB);
+    dvo_image_unlock (&in2DB); // unlock input2
+
+    // write out the image table
+    SetProtect (TRUE);
+    dvo_image_save (&outDB, VERBOSE);
+    SetProtect (FALSE);
+    dvo_image_unlock (&outDB); // unlock output
+  }
+
+  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 27384)
+++ /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/dvomergeUpdate.c	(revision 27384)
@@ -0,0 +1,142 @@
+# include "dvomerge.h"
+
+int dvomergeUpdate (int argc, char **argv) {
+
+  int depth;
+  off_t i, j, Ns, Ne;
+  SkyTable *outsky, *insky;
+  SkyList *inlist;
+  Catalog incatalog, outcatalog;
+  char filename[256], *input, *output;
+
+  if (strcasecmp (argv[2], "into")) usage();
+
+  input  = argv[1];
+  output = argv[3];
+
+  // the first input defines the photcode table & db layout
+  sprintf (filename, "%s/Photcodes.dat", input);
+  if (!LoadPhotcodes (filename, NULL, FALSE)) {
+    fprintf (stderr, "error loading photcode table %s\n", filename);
+    exit (1);
+  }
+
+  // load the sky table for the existing database
+  insky = SkyTableLoadOptimal (input, NULL, NULL, FALSE, SKY_DEPTH_HST, VERBOSE);
+  SkyTableSetFilenames (insky, input, "cpt");
+
+  // generate an output table populated at the desired depth
+  outsky = SkyTableLoadOptimal (output, NULL, NULL, TRUE, SKY_DEPTH, VERBOSE);
+  SkyTableSetFilenames (outsky, output, "cpt");
+
+  // loop over the populatable output tables; check for data in input in the corresponding regions
+
+  SkyTablePopulatedRange (&Ns, &Ne, insky, 0);
+  depth = insky[0].regions[Ns].depth;
+  
+  // loop over the populatable output regions
+  for (i = 0; i < outsky[0].Nregions; i++) {
+    if (!outsky[0].regions[i].table) continue;
+    if (VERBOSE) fprintf (stderr, "output: %s\n", outsky[0].regions[i].name);
+
+    // load / create output catalog
+    LoadCatalog (&outcatalog, &outsky[0].regions[i], outsky[0].filename[i], "a");
+
+    // combine only tables at equal or larger depth
+      
+    // load in all of the tables from input for this region
+    inlist = SkyListByBounds (insky, depth, outsky[0].regions[i].Rmin, outsky[0].regions[i].Rmax, outsky[0].regions[i].Dmin, outsky[0].regions[i].Dmax);
+    for (j = 0; j < inlist[0].Nregions; j++) {
+      if (VERBOSE) fprintf (stderr, "input : %s\n", inlist[0].regions[j][0].name);
+
+      // load input catalog
+      LoadCatalog (&incatalog, inlist[0].regions[j], inlist[0].filename[j], "r");
+
+      // skip empty input catalogs
+      if (!incatalog.Naves_disk) {
+	dvo_catalog_unlock (&incatalog);
+	dvo_catalog_free (&incatalog);
+	continue;
+      }
+      merge_catalogs_old (&outsky[0].regions[i], &outcatalog, &incatalog, RADIUS);
+      dvo_catalog_unlock (&incatalog);
+      dvo_catalog_free (&incatalog);
+    }
+    SkyListFree (inlist);
+
+    outcatalog.catflags = LOAD_AVES | LOAD_MEAS | LOAD_MISS | LOAD_SECF;
+    dvo_catalog_save (&outcatalog, VERBOSE);
+    dvo_catalog_unlock (&outcatalog);
+    dvo_catalog_free (&outcatalog);
+  }
+
+  // save the output sky table copy
+  sprintf (filename, "%s/SkyTable.fits", output);
+  check_file_access (filename, TRUE, TRUE, VERBOSE);
+  if (!SkyTableSave (outsky, filename)) {
+    fprintf (stderr, "ERROR: failed to save sky table for %s\n", output);
+    exit (1);
+  }
+
+  /*** 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);
+}
+
+/* 
+
+   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.  
+
+   generality questions:
+   * optional
+
+
+
+   */
+
Index: /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/help.c
===================================================================
--- /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/help.c	(revision 27384)
+++ /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/help.c	(revision 27384)
@@ -0,0 +1,42 @@
+# include "dvomerge.h"
+
+void usage (void) {
+  fprintf (stderr, "USAGE: dvomerge (input1) and (input2) to (output)\n");
+  fprintf (stderr, "   OR: dvomerge (input) into (output)\n");
+  exit (2);
+}
+
+void help (int argc, char **argv) {
+
+  /* check for help request */
+  if (get_argument (argc, argv, "-help")) goto show_help;
+  if (get_argument (argc, argv, "-h"))    goto show_help;
+  return;
+
+show_help:
+
+  fprintf (stderr, "USAGE\n");
+  fprintf (stderr, "  dvosplit (newlevel)\n\n");
+  fprintf (stderr, "  optional flags:\n");
+  fprintf (stderr, "  -region ra ra dec dec 	  : migrate catalogs in specified region\n");
+  fprintf (stderr, "  -v                    	  : verbose mode\n");
+  fprintf (stderr, "  -help                 	  : this list\n");
+  fprintf (stderr, "  -h                    	  : this list\n\n");
+  exit (2);
+}
+
+/** addstar modes:
+ 
+    addstar (image.smp)  - add cmp/smp image data to db
+    addstar -ref (file.dat) (photcode) 
+    addstar -cat (USNO/2MASS/GSC) -region (ra dec - ra dec)
+
+    -replace : ref/cat - replace existing match (photcode/time)
+    -match   : ref/cat - only add measures to existing averages
+
+    ref types: 
+    ASCII - RA,DEC,M,dM in a table
+
+    addstar 
+
+**/
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 27383)
+++ /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/merge_catalogs_new.c	(revision 27384)
@@ -66,6 +66,8 @@
   
   if (VERBOSE) {
-      fprintf (stderr, "%d: using %d stars (%d measures) for catalog\n", i, 
-	       output[0].Naverage, output[0].Nmeasure);
+      fprintf (stderr, "%lld: using %lld stars (%lld measures) for catalog\n", 
+	       (long long) i, 
+	       (long long) output[0].Naverage, 
+	       (long long) output[0].Nmeasure);
   }
   return (TRUE);
Index: /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/merge_catalogs_old.c
===================================================================
--- /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/merge_catalogs_old.c	(revision 27383)
+++ /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/merge_catalogs_old.c	(revision 27384)
@@ -1,3 +1,4 @@
 # include "dvomerge.h"
+# define PSPS_ID TRUE
 
 # define IN_REGION(R,D) ( \
@@ -119,10 +120,10 @@
     /* negative dX: j is too large */
     dX = X1[i] - X2[j];
-    if (dX <= -2*RADIUS) {
+    if (dX <= -1.02*RADIUS) {
       i++;
       continue;
     }
     /* positive dX, i is too large */
-    if (dX >= 2*RADIUS) {
+    if (dX >= 1.02*RADIUS) {
       j++;
       continue;
@@ -131,5 +132,5 @@
     Jmin = -1;
     Rmin = RADIUS2;
-    for (J = j; (dX > -2*RADIUS) && (J < Nave); J++) {
+    for (J = j; (dX > -1.02*RADIUS) && (J < Nave); J++) {
       /* find closest match for this detection */
       dX = X1[i] - X2[J];
@@ -161,5 +162,5 @@
     }
 
-    /** add measurements for this input average object **/
+    /** add ALL measurements for this input average object **/
     for (Nin = 0; Nin < input[0].average[N].Nmeasure; Nin ++) {
       offset = input[0].average[N].measureOffset + Nin;
@@ -169,5 +170,5 @@
 	
       // set the new measurements
-      output[0].measure[Nmeas]          = input[0].measure[offset];
+      output[0].measure[Nmeas] = input[0].measure[offset];
 
       Rin = input[0].average[N].R - input[0].measure[offset].dR / 3600.0;
@@ -177,8 +178,10 @@
       output[0].measure[Nmeas].dR       = 3600.0*(output[0].average[n].R - Rin);  // XXX update these based on choice of astromety
       output[0].measure[Nmeas].dD       = 3600.0*(output[0].average[n].D - Din);  // XXX update these based on choice of astromety
-      output[0].measure[Nmeas].dbFlags  = 0;
+      output[0].measure[Nmeas].dbFlags  = 0;  // XXX why reset these?
       output[0].measure[Nmeas].averef   = n;
       output[0].measure[Nmeas].objID    = output[0].average[n].objID;
       output[0].measure[Nmeas].catID    = output[0].catID;
+
+      // fprintf (stderr, "Nave : %lld, Nmeas : %lld, dR: %f, dD: %f, catID: %d\n", (long long) n, (long long) Nmeas, output[0].measure[Nmeas].dR, output[0].measure[Nmeas].dD, output[0].measure[i].catID);
 
       // rationalize dR
@@ -197,6 +200,8 @@
 		 output[0].average[n].R, output[0].average[n].D, Rin, Din,
 		 X1[i], X2[Jmin], Y1[i], Y2[Jmin]);
+	// XXX abort on this? -- this is a bad failure...
       }
       input[0].found[N] = Nmeas;
+      output[0].average[n].Nmeasure ++;
       Nmeas ++;
     }
@@ -205,16 +210,17 @@
        Nm is recalculated in build_meas_links if loaded table is not sorted */
     output[0].found[n] = Nmeas;
-    output[0].average[n].Nmeasure ++;
     i++;
   }
+
+# if (0)
+  fprintf (stderr, "--- 1 ---\n");
+  for (i = 0; i < Nmeas; i++) {
+    fprintf (stderr, "Nave : %d, Nmeas : %lld, dR: %f, dD: %f, catID: %d\n", output[0].measure[i].averef, (long long) i, output[0].measure[i].dR, output[0].measure[i].dD, output[0].measure[i].catID);
+  }
+# endif
 
   /** incorporate unmatched image stars, if this star is in field of this catalog **/
   /* these new entries are all written out in UPDATE mode */ 
   for (i = 0; i < Nstars; i++) {
-
-    N = N1[i];
-    if (input[0].found[N] >= 0) continue;
-    if (!IN_REGION (input[0].average[N].R, input[0].average[N].D)) continue;
-
     /* make sure there is space for next entry */
     if (Nmeas + input[0].average[N].Nmeasure >= NMEAS) {
@@ -229,4 +235,8 @@
     }
 
+    N = N1[i];
+    if (input[0].found[N] >= 0) continue;
+    if (!IN_REGION (input[0].average[N].R, input[0].average[N].D)) continue;
+
     output[0].average[Nave].R         	   = input[0].average[N].R;
     output[0].average[Nave].D         	   = input[0].average[N].D;
@@ -238,7 +248,7 @@
     output[0].average[Nave].Nextend        = 0;
 
-    output[0].average[Nave].measureOffset = Nmeas;
-    output[0].average[Nave].missingOffset = -1;
-    output[0].average[Nave].extendOffset  = -1;
+    output[0].average[Nave].measureOffset  = Nmeas;
+    output[0].average[Nave].missingOffset  = -1;
+    output[0].average[Nave].extendOffset   = -1;
 
     output[0].average[Nave].uR        	   = 0;
@@ -253,7 +263,12 @@
     output[0].average[Nave].Npos    	   = 0;
 
-    output[0].average[Nave].objID     	   = objID;
-    output[0].average[Nave].catID     	   = catID;
-    output[0].average[Nave].flags         = 0;
+    output[0].average[Nave].objID     	   = objID; // we create objID values in the context of the output db
+    output[0].average[Nave].catID     	   = catID; // we create catID values in the context of the output db
+    output[0].average[Nave].flags          = 0;  // XXX why reset these?
+    if (PSPS_ID) {
+      output[0].average[Nave].extID = CreatePSPSObjectID(output[0].average[Nave].R, output[0].average[Nave].D);
+    } else {
+      output[0].average[Nave].extID = 0;
+    }
 
     objID ++;
@@ -288,4 +303,8 @@
       Nmeas ++;
     }
+    int Ngroup = input[0].average[N].Nmeasure;
+    for (j = 0; j < Ngroup - 1; j++) {
+	next_meas[Nmeas - Ngroup + j] = Nmeas - Ngroup + j + 1;
+    }
     Nave ++;
   }
@@ -294,5 +313,12 @@
   REALLOCATE (output[0].measure, Measure, Nmeas);
  
-# define NOSORT TRUE
+# if (0)
+  fprintf (stderr, "--- 2 ---\n");
+  for (i = 0; i < Nmeas; i++) {
+    fprintf (stderr, "Nave : %d, Nmeas : %lld, dR: %f, dD: %f, catID: %d\n", output[0].measure[i].averef, (long long) i, output[0].measure[i].dR, output[0].measure[i].dD, output[0].measure[i].catID);
+  }
+# endif
+
+# define NOSORT FALSE
   if (NOSORT) {
     output[0].sorted = FALSE;
@@ -301,4 +327,11 @@
     output[0].measure = sort_measure (output[0].average, Nave, output[0].measure, Nmeas, next_meas);
   }
+
+# if (0)
+  fprintf (stderr, "--- 3 ---\n");
+  for (i = 0; i < Nmeas; i++) {
+    fprintf (stderr, "Nave : %d, Nmeas : %lld, dR: %f, dD: %f, catID: %d\n", output[0].measure[i].averef, (long long) i, output[0].measure[i].dR, output[0].measure[i].dD, output[0].measure[i].catID);
+  }
+# endif
 
   /* note stars which have been found in this catalog */
@@ -316,5 +349,5 @@
   output[0].Nmeasure = Nmeas;
   output[0].Nsecf_mem = Nave*Nsecfilt;
-  if (VERBOSE) fprintf (stderr, "Nstars, Nave, Nmeas: %d %d %d, (%d matches)\n", Nstars, Nave, Nmeas, Nmatch);
+  if (VERBOSE) fprintf (stderr, "Nstars, Nave, Nmeas: %lld %lld %lld, (%lld matches)\n", (long long) Nstars, (long long) Nave, (long long) Nmeas, (long long) Nmatch);
 
   free (next_meas);
Index: /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/psps_ids.c
===================================================================
--- /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/psps_ids.c	(revision 27384)
+++ /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/psps_ids.c	(revision 27384)
@@ -0,0 +1,34 @@
+# include "dvomerge.h"
+
+// Compute IDs for PSPS based on recipe they defined
+
+uint64_t
+CreatePSPSDetectionID(double tobs, int ccdid, int detID)
+{
+    // t0 for detection id is 2007-01-01 00:00:00 utc
+    double  t0 = 54101.0;
+    double diff = floor( 100000. * (tobs - t0) );
+    int itmp = diff;
+
+    // ccdid must be < 100
+    uint64_t detectid = 1000000000*((uint64_t) itmp) + 10000000 * ((uint64_t) ccdid) +
+             ((uint64_t) detID);
+
+    return detectid;
+}
+    
+uint64_t
+CreatePSPSObjectID(double ra, double dec)
+{
+    double zh = 0.0083333;
+    double zid = (dec + 90.) / zh;             // 0 - 180*60*2 = 21600 < 15 bits
+    int izone = (int) floor(zid);
+    double zresid = zid -  ((float) izone);    // 0.0 - 1.0
+
+    uint64_t part1, part2, part3;
+    part1 = (uint64_t)( izone  * 10000000000000LL) ; 
+    part2 = ((uint64_t)(ra * 1000000.)) * 10000 ; // 0 - 360*1e6 = 3.6e8 (< 29 bits)
+    part3 = (int) (zresid * 10000.0) ; // 0 - 10000 (1 bit == 30/10000 arcsec) (< 14 bits)
+
+    return part1 + part2 + part3;
+}
Index: /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/usage.c
===================================================================
--- /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/usage.c	(revision 27383)
+++ /branches/eam_branches/largefiles.20100314/Ohana/src/dvomerge/src/usage.c	(revision 27384)
@@ -3,4 +3,5 @@
 void usage (void) {
   fprintf (stderr, "USAGE: dvomerge (input1) and (input2) to (output)\n");
+  fprintf (stderr, "   OR: dvomerge (input) into (output)\n");
   exit (2);
 }
