Index: /branches/eam_branches/ipp-20130509/Ohana/src/delstar/Makefile
===================================================================
--- /branches/eam_branches/ipp-20130509/Ohana/src/delstar/Makefile	(revision 35729)
+++ /branches/eam_branches/ipp-20130509/Ohana/src/delstar/Makefile	(revision 35730)
@@ -32,4 +32,5 @@
 $(SRC)/delete_duplicate_measures.$(ARCH).o \
 $(SRC)/delete_fix_LAP.$(ARCH).o \
+$(SRC)/delete_fix_LAP_edges.$(ARCH).o \
 $(SRC)/delete_image_photcodes.$(ARCH).o \
 $(SRC)/delete_photcodes.$(ARCH).o \
@@ -43,4 +44,5 @@
 $(SRC)/ImageOpsFixLAP.$(ARCH).o       \
 $(SRC)/ImageSubsetFixLAP.$(ARCH).o       \
+$(SRC)/MeasureEdgeOps.$(ARCH).o       \
 $(SRC)/check_permissions.$(ARCH).o \
 $(SRC)/Shutdown.$(ARCH).o          
@@ -54,4 +56,5 @@
 $(SRC)/delete_duplicate_measures.$(ARCH).o \
 $(SRC)/delete_fix_LAP.$(ARCH).o \
+$(SRC)/delete_fix_LAP_edges.$(ARCH).o \
 $(SRC)/delete_photcodes.$(ARCH).o \
 $(SRC)/delete_photcodes_single.$(ARCH).o \
@@ -59,4 +62,5 @@
 $(SRC)/ImageOpsFixLAP.$(ARCH).o       \
 $(SRC)/ImageSubsetFixLAP.$(ARCH).o       \
+$(SRC)/MeasureEdgeOps.$(ARCH).o       \
 $(SRC)/Shutdown.$(ARCH).o          
 
Index: /branches/eam_branches/ipp-20130509/Ohana/src/delstar/include/delstar.h
===================================================================
--- /branches/eam_branches/ipp-20130509/Ohana/src/delstar/include/delstar.h	(revision 35729)
+++ /branches/eam_branches/ipp-20130509/Ohana/src/delstar/include/delstar.h	(revision 35730)
@@ -35,4 +35,13 @@
 } ImageSubset;
 
+typedef struct {
+  double R;
+  double D;
+  int objID;
+  int catID;
+  int detID;
+  int imageID;
+} MeasureEdge;
+
 /* global variables set in parameter file */
 char   ImageCat[DVO_MAX_PATH];
@@ -49,4 +58,5 @@
 char  *IMAGES;
 char  *IMSTATS_FILE;
+char  *MEASURE_EDGE_FILE;
 
 double NSIGMA;
@@ -80,5 +90,5 @@
 
 int    MODE;
-enum {MODE_NONE, MODE_IMAGENAME, MODE_IMAGEFILE, MODE_TIME, MODE_ORPHAN, MODE_MISSED, MODE_PHOTCODES, MODE_DUP_IMAGES, MODE_DUP_MEASURES, MODE_FIX_LAP, MODE_FIX_LAP_STATS};
+enum {MODE_NONE, MODE_IMAGENAME, MODE_IMAGEFILE, MODE_TIME, MODE_ORPHAN, MODE_MISSED, MODE_PHOTCODES, MODE_DUP_IMAGES, MODE_DUP_MEASURES, MODE_FIX_LAP, MODE_FIX_LAP_STATS, MODE_FIX_LAP_EDGES};
 
 char DateKeyword[64], DateMode[64], UTKeyword[64], MJDKeyword[64], JDKeyword[64];
@@ -172,2 +182,10 @@
 void BumpValidImage (int Seq);
 
+MeasureEdge *delete_fix_LAP_edges (off_t *nmeasure_edge);
+MeasureEdge *delete_fix_LAP_edges_parallel (SkyList *sky, off_t *nmeasure_edge);
+MeasureEdge *delete_fix_LAP_edges_get_measures (Catalog *catalog, MeasureEdge *measure_edge, off_t *Nmeasure_edge_in, off_t *NMEASURE_EDGE_IN);
+int          delete_fix_LAP_edges_find_dups (MeasureEdge *measure_edge, off_t Nmeasure_edge);
+
+MeasureEdge *MeasureEdgeMerge (MeasureEdge *measure_edge_all, off_t *Nmeasure_edge_in, off_t *NMEASURE_EDGE_IN, MeasureEdge *measure_edge, off_t Nmeasure_edge);
+int MeasureEdgeSave(char *filename, MeasureEdge *measure_edge, off_t Nmeasure_edge);
+MeasureEdge *MeasureEdgeLoad(char *filename, off_t *Nmeasure_edge);
Index: /branches/eam_branches/ipp-20130509/Ohana/src/delstar/src/MeasureEdgeOps.c
===================================================================
--- /branches/eam_branches/ipp-20130509/Ohana/src/delstar/src/MeasureEdgeOps.c	(revision 35730)
+++ /branches/eam_branches/ipp-20130509/Ohana/src/delstar/src/MeasureEdgeOps.c	(revision 35730)
@@ -0,0 +1,193 @@
+# include "delstar.h"
+# define FT_BZERO_INT32 1.0*0x80000000
+
+# define GET_COLUMN(OUT,NAME,TYPE) \
+  TYPE *OUT = gfits_get_bintable_column_data (&theader, &ftable, NAME, type, &Nrow, &Ncol); \
+  myAssert (!strcmp(type, #TYPE), "wrong column type");
+
+MeasureEdge *MeasureEdgeLoad(char *filename, off_t *Nmeasure_edge) {
+
+  int Ncol;
+  off_t i;
+  off_t Nrow;
+  Header header;
+  Header theader;
+  Matrix matrix;
+  FTable ftable;
+
+  *Nmeasure_edge= 0;
+  MeasureEdge *measure_edge = NULL;
+
+  FILE *f = fopen (filename, "r");
+  if (!f) {
+    fprintf (stderr, "ERROR: cannot open image subset file %s\n", filename);
+    return FALSE;
+  }
+
+  /* load in PHU segment (ignore) */
+  if (!gfits_fread_header (f, &header)) {
+    if (VERBOSE) fprintf (stderr, "can't read image subset header\n");
+    fclose (f);
+    return FALSE;
+  }
+  if (!gfits_fread_matrix (f, &matrix, &header)) {
+    if (VERBOSE) fprintf (stderr, "can't read image subset matrix\n");
+    gfits_free_header (&header);
+    fclose (f);
+    return FALSE;
+  }
+
+  ftable.header = &theader;
+
+  // load data for this header 
+  if (!gfits_load_header (f, &theader)) {
+    if (VERBOSE) fprintf (stderr, "can't read table header\n");
+    fclose (f);
+    return FALSE;
+  }
+
+  // read the fits table bytes
+  if (!gfits_fread_ftable_data (f, &ftable, FALSE)) {
+    if (VERBOSE) fprintf (stderr, "can't read table data\n");
+    fclose (f);
+    return FALSE;
+  }
+  fclose (f);
+
+  char type[16];
+
+  GET_COLUMN (R      ,     "RA",        double);
+  GET_COLUMN (D      ,     "DEC",       double);
+  GET_COLUMN (objID  ,     "OBJ_ID",    int);
+  GET_COLUMN (catID  ,     "CAT_ID",    int);
+  GET_COLUMN (detID  ,     "DET_ID",    int);
+  GET_COLUMN (imageID,     "IMAGE_ID",  int);
+
+  ALLOCATE (measure_edge, MeasureEdge, Nrow);
+
+  // merge the new arrays into the single array?
+  for (i = 0; i < Nrow; i++) {
+    measure_edge[i].R        = R[i]     ;
+    measure_edge[i].D        = D[i]    ;
+    measure_edge[i].objID    = objID[i]  ;
+    measure_edge[i].catID    = catID[i]  ;
+    measure_edge[i].detID    = detID[i]  ;
+    measure_edge[i].imageID  = imageID[i];
+  }
+  fprintf (stderr, "loaded data for %lld measures\n", (long long) Nrow);
+
+  free (R       );
+  free (D       );
+  free (objID   );
+  free (catID   );
+  free (detID   );
+  free (imageID );
+
+  *Nmeasure_edge = Nrow;
+  return measure_edge;
+}
+
+int MeasureEdgeSave(char *filename, MeasureEdge *measure_edge, off_t Nmeasure_edge) {
+
+  Header header;
+  Header theader;
+  Matrix matrix;
+  FTable ftable;
+
+  gfits_init_header (&header);
+  header.extend = TRUE;
+  gfits_create_header (&header);
+  gfits_create_matrix (&header, &matrix);
+
+  gfits_create_table_header (&theader, "BINTABLE", "MEASURE_EDGE");
+
+  // create the table layout
+  gfits_define_bintable_column (&theader, "D",   "RA",       "tmp",        "tmp", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "D",   "DEC",      "tmp",        "tmp", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "J",   "OBJ_ID",   "tmp",        "tmp", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "J",   "CAT_ID",   "tmp",        "tmp", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "J",   "DET_ID",   "tmp",        "tmp", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "J",   "IMAGE_ID", "tmp",        "tmp", 1.0, 0.0);
+
+  // generate the output array that carries the data
+  gfits_create_table (&theader, &ftable);
+
+  double *R, *D;
+  int *imageID, *objID, *catID, *detID; 
+
+  ALLOCATE (R      , double, Nmeasure_edge);
+  ALLOCATE (D      , double, Nmeasure_edge);
+  ALLOCATE (objID  , int,    Nmeasure_edge);
+  ALLOCATE (catID  , int,    Nmeasure_edge);
+  ALLOCATE (detID  , int,    Nmeasure_edge);
+  ALLOCATE (imageID, int,    Nmeasure_edge);
+
+  // assign the storage arrays
+  off_t i;
+  for (i = 0; i < Nmeasure_edge; i++) {
+    R[i]        = measure_edge[i].R;
+    D[i]        = measure_edge[i].D;
+    objID[i]    = measure_edge[i].objID;
+    catID[i]    = measure_edge[i].catID;
+    detID[i]    = measure_edge[i].detID;
+    imageID[i]  = measure_edge[i].imageID;
+  }
+
+  // add the columns to the output array
+  gfits_set_bintable_column (&theader, &ftable, "RA",       R,       Nmeasure_edge);
+  gfits_set_bintable_column (&theader, &ftable, "DEC",      D,       Nmeasure_edge);
+  gfits_set_bintable_column (&theader, &ftable, "OBJ_ID",   objID,   Nmeasure_edge);
+  gfits_set_bintable_column (&theader, &ftable, "CAT_ID",   catID,   Nmeasure_edge);
+  gfits_set_bintable_column (&theader, &ftable, "DET_ID",   detID,   Nmeasure_edge);
+  gfits_set_bintable_column (&theader, &ftable, "IMAGE_ID", imageID, Nmeasure_edge);
+
+  free (R       );
+  free (D       );
+  free (objID   );
+  free (catID   );
+  free (detID   );
+  free (imageID );
+
+  FILE *f = fopen (filename, "w");
+  if (!f) {
+    fprintf (stderr, "ERROR: cannot open image subset file for output %s\n", filename);
+    return FALSE;
+  }
+
+  gfits_fwrite_header  (f, &header);
+  gfits_fwrite_matrix  (f, &matrix);
+  gfits_fwrite_Theader (f, &theader);
+  gfits_fwrite_table   (f, &ftable);
+
+  gfits_free_header (&header);
+  gfits_free_matrix (&matrix);
+  gfits_free_header (&theader);
+  gfits_free_table (&ftable);
+
+  fclose (f);
+  fflush (f);
+
+  return TRUE;
+}
+
+MeasureEdge *MeasureEdgeMerge (MeasureEdge *measure_edge_all, off_t *Nmeasure_edge_in, off_t *NMEASURE_EDGE_IN, MeasureEdge *measure_edge, off_t Nmeasure_edge) {
+
+  off_t Nmeasure_edge_all = *Nmeasure_edge_in;
+  off_t NMEASURE_EDGE_ALL = *NMEASURE_EDGE_IN;
+
+  off_t Nstart = Nmeasure_edge_all;
+
+  Nmeasure_edge_all += Nmeasure_edge;
+  NMEASURE_EDGE_ALL += Nmeasure_edge;
+  REALLOCATE (measure_edge_all, MeasureEdge, NMEASURE_EDGE_ALL);
+  
+  off_t i;
+  for (i = 0; i < Nmeasure_edge; i++) {
+    measure_edge_all[i + Nstart] = measure_edge[i];
+  }
+
+  *Nmeasure_edge_in = Nmeasure_edge_all;
+  *NMEASURE_EDGE_IN = NMEASURE_EDGE_ALL;
+  return measure_edge_all;
+}
+
Index: /branches/eam_branches/ipp-20130509/Ohana/src/delstar/src/args.c
===================================================================
--- /branches/eam_branches/ipp-20130509/Ohana/src/delstar/src/args.c	(revision 35729)
+++ /branches/eam_branches/ipp-20130509/Ohana/src/delstar/src/args.c	(revision 35730)
@@ -193,4 +193,9 @@
     remove_argument (N, &argc, argv);
   }
+  if ((N = get_argument (argc, argv, "-fix-LAP-edges"))) {
+    if (MODE != MODE_NONE) usage();
+    MODE = MODE_FIX_LAP_EDGES;
+    remove_argument (N, &argc, argv);
+  }
   if ((N = get_argument (argc, argv, "-photcodes"))) {
     if (MODE != MODE_NONE) usage();
@@ -397,4 +402,21 @@
     if (!IMAGES) delstar_client_usage();
   }
+  if ((N = get_argument (argc, argv, "-fix-LAP-edges"))) {
+    if (MODE != MODE_NONE) usage();
+    MODE = MODE_FIX_LAP_EDGES;
+    remove_argument (N, &argc, argv);
+  }
+
+  MEASURE_EDGE_FILE = NULL;
+  if (MODE == MODE_FIX_LAP_EDGES) {
+    N = get_argument (argc, argv, "-measures");
+    if (N == 0) {
+      fprintf (stderr, "delstar_client -fix-LAP-edge needs -measures (FILE)\n");
+      exit (2);
+    }
+    remove_argument (N, &argc, argv);
+    MEASURE_EDGE_FILE = strcreate (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
 
   IMSTATS_FILE = NULL;
Index: /branches/eam_branches/ipp-20130509/Ohana/src/delstar/src/delete_fix_LAP_edges.c
===================================================================
--- /branches/eam_branches/ipp-20130509/Ohana/src/delstar/src/delete_fix_LAP_edges.c	(revision 35730)
+++ /branches/eam_branches/ipp-20130509/Ohana/src/delstar/src/delete_fix_LAP_edges.c	(revision 35730)
@@ -0,0 +1,310 @@
+# include "delstar.h"
+
+// this function identifies detections to be deleted as being duplicates based on imageID
+// + detID *** at the edges of catalogs ***
+
+// unlike many other versions of dvo operations, this function needs to gather detections
+// back to the master program and then do the analysis (more like relphot).  the first
+// block of the code slurps the data from the catalogs, the second block looks for duplicates
+
+MeasureEdge *delete_fix_LAP_edges (off_t *nmeasure_edge) {
+
+  int i;
+  Catalog catalog;
+
+  // load the current sky table (layout of all SkyRegions) 
+  SkyTable *sky = SkyTableLoadOptimal (CATDIR, NULL, NULL, TRUE, -1, VERBOSE);
+  if (!sky) {
+    fprintf (stderr, "ERROR running loading sky table from %s\n", CATDIR);
+    exit (2);
+  }
+  SkyTableSetFilenames (sky, CATDIR, "cpt");
+
+  // determine the populated SkyRegions overlapping the requested area (default depth)
+  SkyList *skylist = SINGLE_CPT ? SkyRegionByCPT (sky, SINGLE_CPT) : SkyListByPatch (sky, -1, &UserPatch);
+  if (!skylist) {
+    fprintf (stderr, "ERROR setting up skylist for %s\n", CATDIR);
+    exit (2);
+  }
+
+  // launch the remote jobs
+  if (PARALLEL && !HOST_ID) {
+    MeasureEdge *measure_edge = delete_fix_LAP_edges_parallel (skylist, nmeasure_edge);
+    return measure_edge;
+  }
+
+  // XXX accumulate detections in a local structure:
+  off_t Nmeasure_edge = 0;
+  off_t NMEASURE_EDGE = 1000;
+  MeasureEdge *measure_edge = NULL;
+  ALLOCATE (measure_edge, MeasureEdge, NMEASURE_EDGE);
+
+  // delete detections from region
+  for (i = 0; i < skylist[0].Nregions; i++) {
+
+    // does this host ID match the desired location for the table?
+    if (!HostTableTestHost(skylist[0].regions[i], HOST_ID)) continue;
+
+    // set up the basic catalog info
+    char hostfile[1024];
+    snprintf (hostfile, 1024, "%s/%s.cpt", HOSTDIR, skylist[0].regions[i]->name);
+    catalog.filename  = HOST_ID ? hostfile : skylist[0].filename[i];
+    catalog.Nsecfilt  = GetPhotcodeNsecfilt ();
+    catalog.catflags = LOAD_AVES | LOAD_MEAS | LOAD_MISS | LOAD_SECF;
+
+    if (VERBOSE) fprintf (stderr, "deleting from %s\n", catalog.filename);
+
+    // an error exit status here is a significant error
+    if (!dvo_catalog_open (&catalog, skylist[0].regions[i], VERBOSE2, "a")) {
+      fprintf (stderr, "ERROR: failure to open catalog file %s\n", catalog.filename);
+      exit (2);
+    }
+    if (!catalog.Naves_disk) {
+      if (VERBOSE2) fprintf (stderr, "no data in %s, skipping\n", catalog.filename);
+      dvo_catalog_unlock (&catalog);
+      dvo_catalog_free (&catalog);
+      continue;
+    }
+
+    // off_t NaverageStart = catalog.Naverage;
+    // off_t NmeasureStart = catalog.Nmeasure;
+    measure_edge = delete_fix_LAP_edges_get_measures (&catalog, measure_edge, &Nmeasure_edge, &NMEASURE_EDGE);
+
+    dvo_catalog_unlock (&catalog);
+    dvo_catalog_free (&catalog);
+  }
+
+  *nmeasure_edge = Nmeasure_edge;
+  return measure_edge;
+}
+
+// CATDIR is supplied globally
+MeasureEdge *delete_fix_LAP_edges_parallel (SkyList *sky, off_t *nmeasure_edge) {
+
+  char uniquer[12];
+  int TIME = time(NULL);
+  int PID = getpid();
+  snprintf (uniquer, 12, "%05d.%05d", PID, TIME % 100000);
+
+  // launch the delstar_client jobs to the parallel hosts
+
+  // load the list of hosts
+  HostTable *table = HostTableLoad (CATDIR, sky->hosts);
+  if (!table) {
+    fprintf (stderr, "ERROR: failure reading Host Table %s for database %s\n", sky->hosts, CATDIR);
+    exit (1);
+  }    
+
+  int i, j;
+  for (i = 0; i < table->Nhosts; i++) {
+
+    if (sky->Nregions < table->Nhosts) {
+      // do any of the regions want this host?
+      int wantThisHost = FALSE;
+      for (j = 0; j < sky->Nregions; j++) {
+	if (HostTableTestHost (sky->regions[j], table->hosts[i].hostID)) {
+	  wantThisHost = TRUE;
+	  break;
+	}
+      }
+      if (!wantThisHost) {
+	// fprintf (stderr, "skip host %s\n", table->hosts[i].hostname);
+	continue;
+      }
+    }
+
+    // ensure that the paths are absolute path names
+    char *tmppath = abspath (table->hosts[i].pathname, DVO_MAX_PATH);
+    free (table->hosts[i].pathname);
+    table->hosts[i].pathname = tmppath;
+
+    ALLOCATE (table->hosts[i].results, char, 1024);
+    snprintf (table->hosts[i].results, 1024, "%s/delstar.fixLAPedges.measures.%s.dat", table->hosts[i].pathname, uniquer);
+
+    char command[1024];
+    snprintf (command, 1024, "delstar_client -hostID %d -D CATDIR %s -hostdir %s -measures %s -region %f %f %f %f -fix-LAP-edges", 
+	      table->hosts[i].hostID, CATDIR, table->hosts[i].pathname, table->hosts[i].results,
+	      UserPatch.Rmin, UserPatch.Rmax, UserPatch.Dmin, UserPatch.Dmax);
+
+    char tmpline[1024];
+    if (VERBOSE)    { snprintf (tmpline, 1024, "%s -v",      command);             strcpy (command, tmpline); }
+    if (VERBOSE2)   { snprintf (tmpline, 1024, "%s -vv",     command);             strcpy (command, tmpline); }
+    if (SINGLE_CPT) { snprintf (tmpline, 1024, "%s -cpt %s", command, SINGLE_CPT); strcpy (command, tmpline); }
+    // if (UPDATE)     { snprintf (tmpline, 1024, "%s -update", command);             strcpy (command, tmpline); }
+
+    fprintf (stderr, "command: %s\n", command);
+
+    if (PARALLEL_MANUAL) continue;
+
+    if (PARALLEL_SERIAL) {
+      int status = system (command);
+      if (status) {
+	fprintf (stderr, "ERROR running delstar_client\n");
+	exit (2);
+      }
+    } else {
+      // launch the job on the remote machine (no handshake)
+      int errorInfo = 0;
+      int pid = rconnect ("ssh", table->hosts[i].hostname, command, table->hosts[i].stdio, &errorInfo, FALSE);
+      if (!pid) {
+	fprintf (stderr, "failure to start %s (error %d)\n", table->hosts[i].hostname, errorInfo);
+	exit (1);
+      }
+      table->hosts[i].pid = pid; // save for future reference
+    }
+  }
+
+  if (PARALLEL_MANUAL) {
+    fprintf (stderr, "run the client commands above.  when these are done, hit return\n");
+    getchar();
+  }
+  if (!PARALLEL_MANUAL && !PARALLEL_SERIAL) {
+    HostTableWaitJobsGetIO (table, __FILE__, __LINE__, VERBOSE);
+  }
+
+  off_t Nmeasure_edge_all = 0;
+  off_t NMEASURE_EDGE_ALL = 1000;
+  MeasureEdge *measure_edge_all = NULL;
+  ALLOCATE (measure_edge_all, MeasureEdge, NMEASURE_EDGE_ALL);
+  
+  for (i = 0; i < table->Nhosts; i++) {
+    if (!table->hosts[i].results) continue;
+    off_t Nmeasure_edge = 0;
+    MeasureEdge *measure_edge = MeasureEdgeLoad (table->hosts[i].results, &Nmeasure_edge);
+    if (!measure_edge) {
+      fprintf (stderr, "failed to read data from %s\n", table->hosts[i].hostname);
+      continue;
+    }
+    // merge new measures into a single array
+    measure_edge_all = MeasureEdgeMerge (measure_edge_all, &Nmeasure_edge_all, &NMEASURE_EDGE_ALL, measure_edge, Nmeasure_edge);
+  }
+
+  *nmeasure_edge = Nmeasure_edge_all;
+  return measure_edge_all;
+}
+
+MeasureEdge *delete_fix_LAP_edges_get_measures (Catalog *catalog, MeasureEdge *measure_edge, off_t *Nmeasure_edge_in, off_t *NMEASURE_EDGE_IN) {
+
+  off_t i, j, m;
+
+  off_t Nmeasure_edge = *Nmeasure_edge_in;
+  off_t NMEASURE_EDGE = *NMEASURE_EDGE_IN;
+
+  // boundaries of the catalog file
+  double Rmin, Rmax, Dmin, Dmax;
+  gfits_scan (&catalog[0].header, "RA0",  "%lf", 1, &Rmin);
+  gfits_scan (&catalog[0].header, "DEC0", "%lf", 1, &Dmin);
+  gfits_scan (&catalog[0].header, "RA1",  "%lf", 1, &Rmax);
+  gfits_scan (&catalog[0].header, "DEC1", "%lf", 1, &Dmax);
+
+# define GAP 2.0
+  double dD = GAP / 3600.0;
+  double dR = dD / cos(RAD_DEG * 0.5 * (Dmin + Dmax));
+  
+  double Rgapmin = Rmin + dR;
+  double Rgapmax = Rmax - dR;
+  double Dgapmin = Dmin + dD;
+  double Dgapmax = Dmax - dD;
+
+  // XXX should deal with pole, but not yet...
+  for (i = 0; i < catalog[0].Naverage; i++) {
+    if (catalog[0].average[i].R < Rgapmin) goto save_measures;
+    if (catalog[0].average[i].R > Rgapmax) goto save_measures;
+    if (catalog[0].average[i].D < Dgapmin) goto save_measures;
+    if (catalog[0].average[i].D > Dgapmax) goto save_measures;
+    continue;
+    
+  save_measures:
+    m = catalog[0].average[i].measureOffset;
+    for (j = 0; j < catalog[0].average[i].Nmeasure; j++) {
+      measure_edge[Nmeasure_edge].R       = catalog[0].average[i].R;
+      measure_edge[Nmeasure_edge].D       = catalog[0].average[i].D;
+      measure_edge[Nmeasure_edge].objID   = catalog[0].measure[m+j].objID;
+      measure_edge[Nmeasure_edge].catID   = catalog[0].measure[m+j].catID;
+      measure_edge[Nmeasure_edge].detID   = catalog[0].measure[m+j].detID;
+      measure_edge[Nmeasure_edge].imageID = catalog[0].measure[m+j].imageID;
+    }
+    Nmeasure_edge ++;
+    CHECK_REALLOCATE (measure_edge, MeasureEdge, NMEASURE_EDGE, Nmeasure_edge, 1000);
+  }
+
+  *Nmeasure_edge_in = Nmeasure_edge;
+  *NMEASURE_EDGE_IN = NMEASURE_EDGE;
+  
+  return measure_edge;
+}
+
+// this function makes the needed modifications to the measure table (to imageIDs) and updates
+// the array measureDrop to mark the entries we want to remove
+
+// needed modifications:
+// * delete all photcodes corresponding to 2mass, synth, or wise (not gpc1 or stack)
+// * delete all duplicates
+// * check the imageID 
+// * re-assign the imageID if needed
+
+int delete_fix_LAP_edges_find_dups (MeasureEdge *measure_edge, off_t Nmeasure_edge) {
+
+  off_t i;
+
+  // XXX TEST
+  FILE *f = fopen ("delstar.fixLAPedge.dat", "w");
+  for (i = 0; i < Nmeasure_edge; i++) {
+    fprintf (f, "0x%08x 0x%08x | 0x%08x 0x%08x | %8.4f %8.4f\n", measure_edge[i].imageID, measure_edge[i].detID, measure_edge[i].objID, measure_edge[i].catID, measure_edge[i].R, measure_edge[i].D);
+  }
+  fclose (f);
+
+  uint64_t *fullID;
+  int *seq, *duplicates;
+
+  ALLOCATE (fullID,     uint64_t, Nmeasure_edge);
+  ALLOCATE (seq,             int, Nmeasure_edge);
+  ALLOCATE (duplicates,      int, Nmeasure_edge);
+
+  // memset (measureDrop, 0, sizeof(off_t) * Nmeasure_edge);
+  memset (duplicates,  0, sizeof(int) * Nmeasure_edge);
+
+  // make an array of the full IDs
+  for (i = 0; i < Nmeasure_edge; i++) {
+    fullID[i] = ((uint64_t) (measure_edge[i].imageID) << 32) | (measure_edge[i].detID);
+    seq[i] = i;
+  }
+
+  // sort the array and sequence number
+  sort_fullIDs (fullID, seq, Nmeasure_edge);
+
+  uint64_t current = fullID[0];	      // current unique value
+  int count = 0;		      // number of duplicates for the current unique value
+  duplicates[0] = count;	      // duplicate sequence
+
+  for (i = 1; i < Nmeasure_edge; i++) {
+    off_t j = seq[i];
+    int newID = (measure_edge[j].imageID == 0) || (fullID[i] != current);
+    if (newID) {
+      count = 0;
+      current = fullID[i];
+    } else {
+      count ++;
+    }
+    duplicates[i] = count;
+  }
+    
+  // mark the measures to be dropped
+  for (i = 0; i < Nmeasure_edge; i++) {
+    off_t j = seq[i];
+
+    int keep = TRUE;
+    if (duplicates[i]) keep = FALSE;
+
+    if (!keep) {
+      // measureDrop[j] = TRUE;
+      fprintf (stderr, "0x%08x 0x%08x | 0x%08x 0x%08x | %8.4f %8.4f\n", measure_edge[j].imageID, measure_edge[j].detID, measure_edge[j].objID, measure_edge[j].catID, measure_edge[j].R, measure_edge[j].D);
+    }
+  }
+
+  FREE (fullID);
+  FREE (seq);
+  FREE (duplicates);
+
+  return TRUE;
+}
Index: /branches/eam_branches/ipp-20130509/Ohana/src/delstar/src/delstar.c
===================================================================
--- /branches/eam_branches/ipp-20130509/Ohana/src/delstar/src/delstar.c	(revision 35729)
+++ /branches/eam_branches/ipp-20130509/Ohana/src/delstar/src/delstar.c	(revision 35730)
@@ -46,4 +46,15 @@
 	break;
       }
+    case MODE_FIX_LAP_EDGES: {
+      off_t Nmeasure_edge = 0;
+      MeasureEdge *measure_edge = delete_fix_LAP_edges(&Nmeasure_edge);
+      if (!measure_edge) {
+	fprintf (stderr, "problem loading edge measures\n"); 
+	exit (1);
+      }
+      delete_fix_LAP_edges_find_dups (measure_edge, Nmeasure_edge);
+      exit (0);
+      break;
+    }
     case MODE_FIX_LAP_STATS: {
 	off_t Nimage;
Index: /branches/eam_branches/ipp-20130509/Ohana/src/delstar/src/delstar_client.c
===================================================================
--- /branches/eam_branches/ipp-20130509/Ohana/src/delstar/src/delstar_client.c	(revision 35729)
+++ /branches/eam_branches/ipp-20130509/Ohana/src/delstar/src/delstar_client.c	(revision 35730)
@@ -43,4 +43,19 @@
     }
 
+    case MODE_FIX_LAP_EDGES: {
+      off_t Nmeasure_edge = 0;
+      MeasureEdge *measure_edge = delete_fix_LAP_edges(&Nmeasure_edge);
+      if (!measure_edge) {
+	fprintf (stderr, "problem loading edge measures\n"); 
+	exit (1);
+      }
+      if (!MeasureEdgeSave (MEASURE_EDGE_FILE, measure_edge, Nmeasure_edge)) {
+	fprintf (stderr, "problem saving edge measures\n"); 
+	exit (1);
+      }
+      exit (0);
+      break;
+    }
+
     case MODE_IMAGEFILE:
       break;
