Index: /branches/eam_branches/ipp-20120405/Ohana/src/dvomerge/Makefile
===================================================================
--- /branches/eam_branches/ipp-20120405/Ohana/src/dvomerge/Makefile	(revision 33899)
+++ /branches/eam_branches/ipp-20120405/Ohana/src/dvomerge/Makefile	(revision 33900)
@@ -43,4 +43,5 @@
 $(SRC)/LoadCatalog.$(ARCH).o \
 $(SRC)/build_links.$(ARCH).o \
+$(SRC)/replace_match.$(ARCH).o \
 $(SRC)/merge_catalogs_new.$(ARCH).o \
 $(SRC)/merge_catalogs_old.$(ARCH).o
@@ -64,4 +65,5 @@
 $(SRC)/LoadCatalog.$(ARCH).o \
 $(SRC)/build_links.$(ARCH).o \
+$(SRC)/replace_match.$(ARCH).o \
 $(SRC)/merge_catalogs_new.$(ARCH).o \
 $(SRC)/merge_catalogs_old.$(ARCH).o
Index: /branches/eam_branches/ipp-20120405/Ohana/src/dvomerge/include/dvomerge.h
===================================================================
--- /branches/eam_branches/ipp-20120405/Ohana/src/dvomerge/include/dvomerge.h	(revision 33899)
+++ /branches/eam_branches/ipp-20120405/Ohana/src/dvomerge/include/dvomerge.h	(revision 33900)
@@ -36,5 +36,6 @@
 int    SKY_DEPTH;
 int    NTHREADS;
-char   *ALTERNATE_PHOTCODE_FILE;
+char  *ALTERNATE_PHOTCODE_FILE;
+int    REPLACE_BY_PHOTCODE;
 
 SkyRegion UserPatch;  // used by MODE CAT
@@ -125,2 +126,4 @@
 int 	   dvomergeUpdate_threaded PROTO((int argc, char **argv));
 int        dvomergeUpdate_catalogs PROTO((char *input, char *output, SkyTable *outsky, SkyList *inlist, int NsecfiltInput, int NsecfiltOutput, IDmapType IDmap, int *secfiltMap));
+
+int        replace_match           PROTO((Average *average_out, Measure *measure_out, Average *average_in, Measure *measure_in));
Index: /branches/eam_branches/ipp-20120405/Ohana/src/dvomerge/src/args.c
===================================================================
--- /branches/eam_branches/ipp-20120405/Ohana/src/dvomerge/src/args.c	(revision 33899)
+++ /branches/eam_branches/ipp-20120405/Ohana/src/dvomerge/src/args.c	(revision 33900)
@@ -15,4 +15,11 @@
     remove_argument (N, argc, argv);
     ALTERNATE_PHOTCODE_FILE = strcreate(argv[N]);
+    remove_argument (N, argc, argv);
+  }
+
+  /* replace measurement, don't duplicate */
+  REPLACE_BY_PHOTCODE = FALSE;
+  if ((N = get_argument (*argc, argv, "-replace"))) {
+    REPLACE_BY_PHOTCODE = TRUE;
     remove_argument (N, argc, argv);
   }
@@ -108,4 +115,11 @@
   }
 
+  /* replace measurement, don't duplicate */
+  REPLACE_BY_PHOTCODE = FALSE;
+  if ((N = get_argument (*argc, argv, "-replace"))) {
+    REPLACE_BY_PHOTCODE = TRUE;
+    remove_argument (N, argc, argv);
+  }
+
   NTHREADS = 0;
   if ((N = get_argument (*argc, argv, "-threads"))) {
Index: /branches/eam_branches/ipp-20120405/Ohana/src/dvomerge/src/dvomergeUpdate_catalogs.c
===================================================================
--- /branches/eam_branches/ipp-20120405/Ohana/src/dvomerge/src/dvomergeUpdate_catalogs.c	(revision 33899)
+++ /branches/eam_branches/ipp-20120405/Ohana/src/dvomerge/src/dvomergeUpdate_catalogs.c	(revision 33900)
@@ -214,10 +214,6 @@
 
     char tmpline[DVO_MAX_PATH];
-    if (VERBOSE)            { snprintf (tmpline, DVO_MAX_PATH, "%s -v",                command);            strcpy (command, tmpline); }
-
-    // XXX these do not make sense for dvomerge client, where the output is required to exist
-    // if (CATFORMAT)          { snprintf (tmpline, DVO_MAX_PATH, "%s -D CATFORMAT %s",   command, CATFORMAT); strcpy (command, tmpline); }
-    // if (CATMODE)            { snprintf (tmpline, DVO_MAX_PATH, "%s -D CATMODE %s",     command, CATMODE);   strcpy (command, tmpline); }
-    // if (SKY_DEPTH)          { snprintf (tmpline, DVO_MAX_PATH, "%s -D SKY_DEPTH %d",   command, SKY_DEPTH); strcpy (command, tmpline); }
+    if (VERBOSE)             { snprintf (tmpline, DVO_MAX_PATH, "%s -v",       command); strcpy (command, tmpline); }
+    if (REPLACE_BY_PHOTCODE) { snprintf (tmpline, DVO_MAX_PATH, "%s -replace", command); strcpy (command, tmpline); }
 
     fprintf (stderr, "command: %s\n", command);
Index: /branches/eam_branches/ipp-20120405/Ohana/src/dvomerge/src/help.c
===================================================================
--- /branches/eam_branches/ipp-20120405/Ohana/src/dvomerge/src/help.c	(revision 33899)
+++ /branches/eam_branches/ipp-20120405/Ohana/src/dvomerge/src/help.c	(revision 33900)
@@ -51,4 +51,6 @@
   fprintf (stderr, "  -h                    	  : this list\n\n");
   fprintf (stderr, "  -region Rmin Rmax Dmin Dmax : region to merge\n\n");
+  fprintf (stderr, "  -replace                    : replace existing detections of the same photcode\n");
+  fprintf (stderr, "                                (this should only be used to merge reference dbs)\n\n");
   exit (2);
 }
@@ -71,4 +73,6 @@
   fprintf (stderr, "  -h                    	  : this list\n\n");
   fprintf (stderr, "  -region Rmin Rmax Dmin Dmax : region to merge\n\n");
+  fprintf (stderr, "  -replace                    : replace existing detections of the same photcode\n");
+  fprintf (stderr, "                                (this should only be used to merge reference dbs)\n\n");
   exit (2);
 }
Index: /branches/eam_branches/ipp-20120405/Ohana/src/dvomerge/src/merge_catalogs_old.c
===================================================================
--- /branches/eam_branches/ipp-20120405/Ohana/src/dvomerge/src/merge_catalogs_old.c	(revision 33899)
+++ /branches/eam_branches/ipp-20120405/Ohana/src/dvomerge/src/merge_catalogs_old.c	(revision 33900)
@@ -111,4 +111,10 @@
   if (Nave > 1) sort_coords_index (X2, Y2, N2, Nave);
 
+  if (REPLACE_BY_PHOTCODE && output[0].Nmeasure && !output[0].sorted) {
+    fprintf (stderr, "ERROR: attempt to merge with replace into an unsorted database\n");
+    exit (3);
+  }
+
+
   /* set up pointers for linked list of measure */
   if (output[0].sorted && (output[0].Nmeasure >= output[0].Nmeas_disk)) {
@@ -186,4 +192,12 @@
       offset = input[0].average[N].measureOffset + Nin;
 
+      if (REPLACE_BY_PHOTCODE) {
+	// index to first measure for this object
+	int Mout = output[0].average[n].measureOffset;  
+	if (replace_match(&output[0].average[n], &output[0].measure[Mout], &input[0].average[N], &input[0].measure[offset])) {
+	  input[0].found[N] = Mout;
+	  continue;
+	}
+      }
       /* add to end of measurement list */
       add_meas_link (&output[0].average[n], next_meas, Nmeas, NMEAS);
Index: /branches/eam_branches/ipp-20120405/Ohana/src/dvomerge/src/replace_match.c
===================================================================
--- /branches/eam_branches/ipp-20120405/Ohana/src/dvomerge/src/replace_match.c	(revision 33900)
+++ /branches/eam_branches/ipp-20120405/Ohana/src/dvomerge/src/replace_match.c	(revision 33900)
@@ -0,0 +1,57 @@
+# include "dvomerge.h"
+
+// average and measure pointers to the objects of interest and their first / current measurement
+int replace_match (Average *average_out, Measure *measure_out, Average *average_in, Measure *measure_in) {
+
+  int Nout;
+  unsigned int averef;
+  unsigned int catID;
+  double Rin, Din;
+
+  // find the matching photcode in the object's list of measurements
+  for (Nout = 0; Nout < average_out[0].Nmeasure; Nout ++) {
+    if (measure_out[Nout].photcode != measure_in[0].photcode) continue;
+    
+    // set the new measurements
+    averef = measure_out[Nout].averef;
+    catID  = measure_out[Nout].catID;
+    measure_out[Nout] = measure_in[0];
+
+    Rin = average_in[0].R - measure_in[0].dR / 3600.0;
+    Din = average_in[0].D - measure_in[0].dD / 3600.0;
+
+    /** dR,dD now represent arcsec **/
+    measure_out[Nout].dR       = 3600.0*(average_out[0].R - Rin);
+    measure_out[Nout].dD       = 3600.0*(average_out[0].D - Din);
+    measure_out[Nout].dbFlags  = 0;  // XXX why reset these?
+    measure_out[Nout].averef   = averef;
+    measure_out[Nout].objID    = average_out[0].objID;
+    measure_out[Nout].catID    = catID;
+
+    // rationalize dR
+    if (measure_out[Nout].dR > +180.0*3600.0) {
+      // average on high end of boundary, move star up
+      Rin += 360.0;
+      measure_out[Nout].dR = 3600.0*(average_out[0].R - Rin);
+    }
+    if (measure_out[Nout].dR < -180.0*3600.0) {
+      // average on low end of boundary, move star down
+      Rin -= 360.0;
+      measure_out[Nout].dR = 3600.0*(average_out[0].R - Rin);
+    }
+
+    // warn on surprisingly distant detections
+    if (fabs(measure_out[Nout].dR) > 10*RADIUS) {
+      // ok take declination into account and check again.
+      double cosD = cos(RAD_DEG*Din);
+      if (fabs(measure_out[Nout].dR*cosD) > 10*RADIUS) {
+
+	fprintf (stderr, "surprisingly distant detection: %10.6f,%10.6f vs %10.6f,%10.6f\n", 
+		 average_out[0].R, average_out[0].D, Rin, Din);
+      }
+    }
+    return TRUE; // found the matched entry
+  }
+  return FALSE; // did not find the matched entry
+}
+
Index: /branches/eam_branches/ipp-20120405/Ohana/src/dvomerge/test/dvomerge.parallel.sh
===================================================================
--- /branches/eam_branches/ipp-20120405/Ohana/src/dvomerge/test/dvomerge.parallel.sh	(revision 33899)
+++ /branches/eam_branches/ipp-20120405/Ohana/src/dvomerge/test/dvomerge.parallel.sh	(revision 33900)
@@ -5,3 +5,3 @@
  cp HostTable.dat catdir.merge/
  dvodist -out catdir.merge
- dvomerge -parallel-manual catdir.grizy into catdir.merge
+ dvomerge -parallel catdir.grizy into catdir.merge
Index: /branches/eam_branches/ipp-20120405/Ohana/src/dvomerge/test/dvomerge.replace.sh
===================================================================
--- /branches/eam_branches/ipp-20120405/Ohana/src/dvomerge/test/dvomerge.replace.sh	(revision 33900)
+++ /branches/eam_branches/ipp-20120405/Ohana/src/dvomerge/test/dvomerge.replace.sh	(revision 33900)
@@ -0,0 +1,8 @@
+#!/bin/csh -f
+
+ rm -rf catdir.merge.save
+ rm -rf catdir.merge
+ rsync -auv catdir.2mass/ catdir.merge/
+ dvomerge catdir.grizy into catdir.merge
+ rsync -auv catdir.merge/ catdir.merge.save/
+ dvomerge -replace catdir.2mass into catdir.merge
