Index: trunk/Ohana/src/dvomerge/Makefile
===================================================================
--- trunk/Ohana/src/dvomerge/Makefile	(revision 34277)
+++ trunk/Ohana/src/dvomerge/Makefile	(revision 34405)
@@ -33,4 +33,5 @@
 $(SRC)/dvomergeUpdate_catalogs.$(ARCH).o \
 $(SRC)/dvomergeUpdate_threaded.$(ARCH).o \
+$(SRC)/dvomergeHistory.$(ARCH).o \
 $(SRC)/dvomergeFromList.$(ARCH).o \
 $(SRC)/dvomergeImageIDs.$(ARCH).o \
@@ -56,4 +57,5 @@
 $(SRC)/dvomerge_client.$(ARCH).o \
 $(SRC)/dvomergeUpdate_catalogs.$(ARCH).o \
+$(SRC)/dvomergeHistory.$(ARCH).o \
 $(SRC)/dvomergeImageIDs.$(ARCH).o \
 $(SRC)/dvo_image_merge_dbs.$(ARCH).o \
Index: trunk/Ohana/src/dvomerge/doc/failsafe.txt
===================================================================
--- trunk/Ohana/src/dvomerge/doc/failsafe.txt	(revision 34277)
+++ trunk/Ohana/src/dvomerge/doc/failsafe.txt	(revision 34405)
@@ -1,2 +1,28 @@
+
+20120809
+
+more on failsafe
+
+I need to improve the technique I'm using for failsafe ops / rerun.
+
+ * Image.dat PHU keywords:
+   DVO_DB_ID : %s : hex string with 32 byte "unique" string for DB
+   DM_NMERGE : %d : number of databases merged into this onea
+   DM_nnnnnn : %s : DVO_DB_ID of merge (nnnnn)
+
+   Note: nnnnnn may be greater than NMERGE if entries are skipped
+     (only a total of NMERGE nnnnnn values are allowed)
+
+ * region.cpt PHU keywords:
+   DM_NMERGE : %d : number of databases merged into this one (needed?)
+   MS_nnnnnn : %d : size of merged db entry nnnnnn
+   MT_nnnnnn : %s : date/time of merged db entry nnnnnn
+   
+ Is there a reason for the image entries?  (additional record keeping)
+
+ 
+
+
+201206??
 
 we have a problem with dvomerge and flaky hosts.  the problem is that
Index: trunk/Ohana/src/dvomerge/include/dvomerge.h
===================================================================
--- trunk/Ohana/src/dvomerge/include/dvomerge.h	(revision 34277)
+++ trunk/Ohana/src/dvomerge/include/dvomerge.h	(revision 34405)
@@ -44,4 +44,35 @@
   char *notFound;
 } IDmapType;
+
+// struct to describe a sequence of dvomerges (Image.dat header)
+typedef struct {
+  int Nmerge;
+  char **IDs;
+} dmhImage;
+
+// struct to describe a sequence of dvomerges (Object table : cpt header)
+typedef struct {
+  int   Nmerge;
+  off_t  *size;
+  time_t *time;
+  char  **date;
+} dmhObject;
+
+// data on a single table, populated when a new file is merged
+typedef struct {
+  off_t  size;
+  time_t time;
+  char  *date;
+} dmhObjectStats;
+
+// struct to describe the current status of a single output file:
+// is it on this machine (valid)? have we already merged or not (missed)?
+// what is the collection of past merges (history)?  what is the real filename?
+typedef struct {
+  int valid;		      // is this object table on this machine?
+  int missed;		      // did we fail to merge into this table yet?
+  dmhObject *history;	      // complete sequence of previous merges
+  char *filename;	      // true filename on disk 
+} OutputStatus;
 
 int        main                   PROTO((int argc, char **argv));
@@ -130,2 +161,21 @@
 IDmapType *IDmapLoad               PROTO((char *filename));
 int        create_IDmap_lookup     PROTO((IDmapType *IDmap));
+
+// dvomerge history functions
+OutputStatus *OutputStatusInit (int N);
+int OutputStatusFree (OutputStatus *outstat, int N);
+
+int dmhObjectAdd (dmhObject *history, Header *header, dmhObjectStats *inStats);
+int dmhObjectCheck (dmhObject *history, dmhObjectStats *inStats);
+dmhObject *dmhObjectRead (char *filename);
+
+void dmhObjectStatsFree (dmhObjectStats *stats);
+dmhObjectStats *dmhObjectStatsRead (char *filename);
+
+int dmhImageAdd (FITS_DB *db, dmhImage *history, char *dbID);
+dmhImage *dmhImageRead (FITS_DB *db) ;
+int dmhImageCheck (dmhImage *history, char *dbID);
+
+char *dmhImageReadID (FITS_DB *db);
+int dvoCreateID (char *catdir);
+
Index: trunk/Ohana/src/dvomerge/include/dvoverify.h
===================================================================
--- trunk/Ohana/src/dvomerge/include/dvoverify.h	(revision 34277)
+++ trunk/Ohana/src/dvomerge/include/dvoverify.h	(revision 34405)
@@ -34,4 +34,5 @@
 int    NNotSorted;
 int    CHECK_TOPLEVEL;
+int    CHECK_IMAGE_ID;
 int    LIST_MISSING;
 
@@ -52,2 +53,5 @@
 void AddFailures (char *filename);
 char **GetFailures (int *N);
+
+int LoadImageIDs (char *catdir);
+int CheckImageID (Catalog *catalog);
Index: trunk/Ohana/src/dvomerge/src/dvomergeHistory.c
===================================================================
--- trunk/Ohana/src/dvomerge/src/dvomergeHistory.c	(revision 34405)
+++ trunk/Ohana/src/dvomerge/src/dvomergeHistory.c	(revision 34405)
@@ -0,0 +1,277 @@
+# include "dvomerge.h"
+
+// We track the dvomerge history (dmh) in the headers of the Image table (Image.dat) and
+// each of the Object tables (CPT files).  In the Image table, we track the IDs of the dvo
+// databases which have been merged.  In the object tables, we track the date and size of
+// the CPT files already merged.  When we merge a new dvodb, we block against re-merging
+// any Object table if the current one matches one of the already ingested tables.
+
+// XXX should I require all IDs to be in sequence?  The sequence has no meaning except to
+// ensure the keyword numbering.  If we require the sequence, then it simplifies the code
+// somewhat
+
+// we have a sequence of dvomerge events.  
+// in the image table header, we want to track the IDs of the databases 
+// which have been merged
+
+// some (possible?) functions needed to track the history
+
+// user must pass in a char * of length DVO_DBID_LEN
+char *dmhImageReadID (FITS_DB *db) {
+
+  char dbID[33];
+  int status = gfits_scan (&db->header, "DVO_DBID", "%s", 1, dbID);      
+  if (!status) {
+    return NULL;
+  }
+
+  char *ID = strcreate (dbID);
+  return ID;
+}
+
+dmhImage *dmhImageRead (FITS_DB *db) {
+
+  if (!db) return FALSE;
+  if (!db->header.buffer) return FALSE;
+
+  dmhImage *history = NULL;
+  ALLOCATE (history, dmhImage, 1);
+
+  // should track the number in the header (would overwrite)
+  int status = gfits_scan (&db->header, "NMERGE", "%d", 1, &history->Nmerge); 
+  if (!status) {
+    history->Nmerge = 0;
+  }
+
+  // ALLOCATE full list
+  ALLOCATE (history->IDs, char *, history->Nmerge);
+
+  int i;
+  char name[16], ID[80];
+  for (i = 0; i < history->Nmerge; i++) {
+    snprintf (name, 16, "DM_%05d", i);
+    status = gfits_scan (&db->header, name, "%s", 1, ID);
+    if (!status) {
+      fprintf (stderr, "failed to read %s\n", name);
+      exit (6);
+    }
+    history->IDs[i] = strcreate (ID);
+  }
+  return history;
+}
+
+// compare stats for the input to the full history for the output
+// have we merged this file?
+int dmhImageCheck (dmhImage *history, char *dbID) {
+
+  // if the input catalog does not exist, we did not miss it
+  // if the output catalog does not exist, we must have missed it
+
+  if (!dbID) return FALSE; // no ID to merge, probably an error to get here
+  if (!history) return FALSE; // we must not have merged since it does not exist
+
+  int i;
+  for (i = 0; i < history->Nmerge; i++) {
+    // do we match this size?
+    if (!strcmp(history->IDs[i], dbID)) return TRUE; // we match (already merged)
+  }
+  return FALSE; // no match, not yet merged
+}
+
+int dmhImageAdd (FITS_DB *db, dmhImage *history, char *dbID) {
+
+  // update the arrays
+  int last = history->Nmerge;
+
+  history->Nmerge ++;
+  REALLOCATE (history->IDs, char *, history->Nmerge);
+
+  history->IDs[last] = strcreate (dbID);
+
+  char name[16];
+  snprintf (name, 16, "DM_%05d", last);
+  gfits_modify (&db->header, name, "%s", 1, dbID);
+
+  gfits_modify (&db->header, "NMERGE", "%d", 1, history->Nmerge);
+  return TRUE;
+}
+
+dmhObjectStats *dmhObjectStatsRead (char *filename) {
+
+  // instats.st_size & instats.st_mtime
+
+  // get the stats on this input file (for comparison with the output headers)
+  struct stat instats;
+  int stat_result = stat (filename, &instats);
+  if (stat_result) {
+    if (errno == ENOENT) return NULL;
+    fprintf (stderr, "cannot read stats on input file %s\n", filename);
+    perror ("stats error message:");
+    exit (2);
+  }
+  
+  dmhObjectStats *stats = NULL;  
+  ALLOCATE (stats, dmhObjectStats, 1);
+  stats->size = instats.st_size;
+  stats->time = instats.st_mtime;
+  stats->date = ohana_sec_to_date (instats.st_mtime);
+  return stats;
+}
+
+void dmhObjectStatsFree (dmhObjectStats *stats) {
+  if (!stats) return;
+  if (stats->date) free (stats->date);
+  free (stats);
+}
+
+// read the array of merged history information from this file's header
+dmhObject *dmhObjectRead (char *filename) {
+
+  // if the file does not exist, return NULL (means 'missed')
+  struct stat outstats;
+  int stat_result = stat (filename, &outstats);
+  if (stat_result) {
+    if (errno == ENOENT) return NULL;
+    fprintf (stderr, "cannot read stats on output file %s\n", filename);
+    perror ("stats error message:");
+    exit (2);
+  }
+
+  FILE *fout = fopen (filename, "r");
+  if (!fout) {
+    fprintf (stderr, "problem opening output file to read header %s\n", filename);
+    perror ("stats error message:");
+    exit (2);
+  }
+
+  Header outheader;
+  if (!gfits_fread_header (fout, &outheader)) {
+    fprintf (stderr, "problem reading header for output file %s\n", filename);
+    exit (2);
+  }
+  fclose (fout);
+
+  dmhObject *history = NULL;
+  ALLOCATE (history, dmhObject, 1);
+
+  int status = gfits_scan (&outheader, "NMERGE", "%d", 1, &history->Nmerge);      
+  if (!status) {
+    history->Nmerge = 0;
+  }
+
+  // ALLOCATE full list
+  ALLOCATE (history->size, off_t,  history->Nmerge);
+  ALLOCATE (history->time, time_t, history->Nmerge);
+  ALLOCATE (history->date, char *, history->Nmerge);
+
+  int i;
+  for (i = 0; i < history->Nmerge; i++) {
+    off_t  size;
+    char   date[80];
+
+    char name[16];
+    
+    snprintf (name, 16, "MS_%05d", i);
+    status = gfits_scan (&outheader, name, OFF_T_FMT, 1, &size);
+    if (!status) {
+      fprintf (stderr, "failed to read %s\n", name);
+      exit (6);
+    }
+    history->size[i] = size;
+
+    snprintf (name, 16, "MT_%05d", i);
+    status = gfits_scan (&outheader, name, "%s", 1, date);
+    if (!status) {
+      fprintf (stderr, "failed to read %s\n", name);
+      exit (7);
+    }
+    history->date[i] = strcreate (date);
+    history->time[i] = ohana_date_to_sec (date);
+  }
+  return history;
+}
+  
+// compare stats for the input to the full history for the output
+// have we merged this file?
+int dmhObjectCheck (dmhObject *history, dmhObjectStats *inStats) {
+
+  // if the input catalog does not exist, we did not miss it
+  // if the output catalog does not exist, we must have missed it
+
+  if (!inStats) return TRUE; // we do not need to merge something that does not exist...
+  if (!history) return FALSE; // we must not have merged since it does not exist
+
+  int i;
+  for (i = 0; i < history->Nmerge; i++) {
+    
+    // do we match this size?
+    if (history->size[i] != inStats->size) continue;
+
+    // do we match this date?
+    if (history->time[i] != inStats->time) continue;
+
+    return TRUE;  // we match (already merged)
+  }
+  return FALSE; // no match, not yet merged
+}
+
+// add the stats for the given input file to the output structure and header
+int dmhObjectAdd (dmhObject *history, Header *header, dmhObjectStats *inStats) {
+
+  // update the arrays
+  int last = history->Nmerge;
+
+  history->Nmerge ++;
+  REALLOCATE (history->size, off_t,  history->Nmerge);
+  REALLOCATE (history->time, time_t, history->Nmerge);
+  REALLOCATE (history->date, char *, history->Nmerge);
+
+  history->size[last] = inStats->size;
+  history->time[last] = inStats->time;
+  history->date[last] = inStats->date;
+
+  char name[16];
+  snprintf (name, 16, "MS_%05d", last);
+
+  int status = gfits_modify (header, name, OFF_T_FMT, 1, inStats->size); 
+  if (!status) { 
+    fprintf (stderr, "error: failed to add size to header (%d)\n", (int) inStats->size);
+    exit (1);
+  }
+
+  snprintf (name, 16, "MT_%05d", last);
+  status = gfits_modify (header, name, "%s", 1, inStats->date);
+  if (!status) {     
+    fprintf (stderr, "error: failed to add date to header (%s)\n", inStats->date);
+    exit (1);
+  }
+
+  gfits_modify (header, "NMERGE", "%d", 1, history->Nmerge);
+  return TRUE;
+}
+
+OutputStatus *OutputStatusInit (int N) {
+
+  int i;
+
+  OutputStatus *outstat = NULL;
+  ALLOCATE (outstat, OutputStatus, N);
+  for (i = 0; i < N; i++) {
+    outstat[i].valid = FALSE;
+    outstat[i].missed = FALSE;
+    outstat[i].history = NULL;
+    outstat[i].filename = NULL;
+  }
+  return outstat;
+}
+
+int OutputStatusFree (OutputStatus *outstat, int N) {
+
+  int i;
+  for (i = 0; i < N; i++) {
+    if (outstat[i].history)  { free (outstat[i].history); }
+    if (outstat[i].filename) { free (outstat[i].filename); }
+  }
+  free (outstat);
+  return TRUE;
+}
Index: trunk/Ohana/src/dvomerge/src/dvomergeImageIDs.c
===================================================================
--- trunk/Ohana/src/dvomerge/src/dvomergeImageIDs.c	(revision 34277)
+++ trunk/Ohana/src/dvomerge/src/dvomergeImageIDs.c	(revision 34405)
@@ -21,7 +21,15 @@
     return TRUE;
   }
+  // this operation reads the PHU header (inDB.header)
   if (!dvo_image_load (&inDB, VERBOSE, TRUE)) {
     Shutdown ("can't read input image catalog %s", inDB.filename);
   }
+  dvo_image_unlock (&inDB); // unlock input
+
+  // read the header for the database ID?
+  char *indbID = dmhImageReadID (&inDB);
+  if (!indbID) { 
+    Shutdown ("this database is missing a DVO database ID; please generate one before merging\n"); 
+  } 
 
   /*** load output/Images.dat ***/
@@ -41,8 +49,27 @@
   }
 
+  dmhImage *history = dmhImageRead (&outDB);
+  if (!history) { 
+    Shutdown ("error reading history for output database\n"); 
+  }
+
+  // have we already merged this database?
+  if (dmhImageCheck(history, indbID)) {
+    // if so, then just match the image IDs 
+    if (VERBOSE) fprintf (stderr, "already merged image table\n");
+    dvo_image_match_dbs(IDmap, &outDB, &inDB);
+    dvo_image_unlock (&outDB); // unlock output
+    return TRUE;
+  }
+
   // convert database table to internal structure & add to output image db
   dvo_image_merge_dbs(IDmap, &outDB, &inDB);
-  dvo_image_unlock (&inDB); // unlock input
 
+  // add the new image db to merge history
+  // (updates header as well as history structure
+  if (!dmhImageAdd (&outDB, history, indbID)) { 
+    Shutdown ("error reading history for output database\n"); 
+  }
+    
   SetProtect (TRUE);
   dvo_image_save (&outDB, VERBOSE);
Index: trunk/Ohana/src/dvomerge/src/dvomergeUpdate_catalogs.c
===================================================================
--- trunk/Ohana/src/dvomerge/src/dvomergeUpdate_catalogs.c	(revision 34277)
+++ trunk/Ohana/src/dvomerge/src/dvomergeUpdate_catalogs.c	(revision 34405)
@@ -31,33 +31,35 @@
     outlist = SkyListByBounds (outsky, -1, inlist[0].regions[i][0].Rmin + dPos, inlist[0].regions[i][0].Rmax - dPos, inlist[0].regions[i][0].Dmin + dPos, inlist[0].regions[i][0].Dmax - dPos);
 
-    // there may be more than one output region for a given input region.  are any of these output regions relevant to this machine?
+    OutputStatus *outstat = OutputStatusInit (outlist->Nregions);
+
+    // there may be more than one output region for a given input region.  
+    // are any of these output regions relevant to this machine?
     int found = FALSE;
-    for (j = 0; !found && (j < outlist[0].Nregions); j++) {
-      found = (found || HostTableTestHost(outlist[0].regions[j], HOST_ID));
+    for (j = 0; j < outlist[0].Nregions; j++) {
+      outstat[j].valid = HostTableTestHost(outlist[0].regions[j], HOST_ID);
+      found = (found || outstat[j].valid);
     }
 
     // skip this input table for if no output files are on this machine
     if (!found) {
+      OutputStatusFree (outstat, outlist->Nregions);
       SkyListFree (outlist); 
       continue; 
     }
 
-    // get the stats on this input file (for comparison with the output headers)
-    struct stat instats;
-    int stat_result = stat (inlist[0].filename[i], &instats);
-    if (stat_result) {
-      if (errno == ENOENT) continue;
-      fprintf (stderr, "cannot read stats on input file %s\n", inlist[0].filename[i]);
-      perror ("stats error message:");
-      exit (2);
-    }
-
-    // instats.st_size & instats.st_mtime
-
-    // check if any of the output files have NOT yet received data from this input file
-
+    // get stats for history check, skip input catalog if file not found (NULL inStats)
+    dmhObjectStats *inStats = dmhObjectStatsRead (inlist[0].filename[i]);
+    if (!inStats) {
+      if (VERBOSE) fprintf (stderr, "skipping %s, empty \n", inlist[0].filename[i]);
+      OutputStatusFree (outstat, outlist->Nregions);
+      SkyListFree (outlist); 
+      continue;
+    }
+
+    // Check if any of the output files have NOT yet received data from this input file
+    // If none have been missed, we can skip the input file completely
     int missed = FALSE;
-    for (j = 0; !missed && (j < outlist[0].Nregions); j++) {
-      if (!HostTableTestHost(outlist[0].regions[j], HOST_ID)) continue;
+    for (j = 0; j < outlist[0].Nregions; j++) {
+      if (!outstat[j].valid) continue;
 
       // set the parameters which guide catalog open/load/create
@@ -65,54 +67,17 @@
       snprintf (hostfile, DVO_MAX_PATH, "%s/%s.cpt", HOSTDIR, outlist[0].regions[j]->name);
       char *filename = HOST_ID ? hostfile : outlist[0].filename[j];
-
-      // get the stats on this input file (for comparison with the output headers)
-      struct stat outstats;
-      stat_result = stat (filename, &outstats);
-      if (stat_result) {
-	if (errno == ENOENT) {
-	  missed = TRUE;
-	  break;
-	}
-	fprintf (stderr, "cannot read stats on output file %s\n", filename);
-	perror ("stats error message:");
-	exit (2);
-      }
-
-      FILE *fout = fopen (filename, "r");
-      if (!fout) {
-	fprintf (stderr, "problem opening output file to read header %s\n", filename);
-	perror ("stats error message:");
-	exit (2);
-      }
-
-      Header outheader;
-      if (!gfits_fread_header (fout, &outheader)) {
-	fprintf (stderr, "problem reading header for output file %s\n", filename);
-	exit (2);
-      }
-      
-      fclose (fout);
-
-      // XXX note that we are hardwired to v 2
-      // check the header of output catalog for an existing merge
-      long long last_size;
-      char last_moddate[80];
-      gfits_scan (&outheader, "LMRG_SZ2", "%lld", 1, &last_size);      
-      gfits_scan (&outheader, "LMRG_DT2", "%s", 1, last_moddate);      
-
-      time_t last_mod = ohana_date_to_sec (last_moddate);
-
-      if (last_size != instats.st_size) {
-	missed = TRUE;
-	break;
-      }
-      
-      if (last_mod != instats.st_mtime) {
-	missed = TRUE;
-	break;
-      }
+      outstat[j].filename = strcreate (filename);
+
+      outstat[j].history = dmhObjectRead (outstat[j].filename);
+
+      // have we already merged this database?
+      outstat[j].missed = !dmhObjectCheck (outstat[j].history, inStats);
+      missed = (missed || outstat[j].missed);
     }
     if (!missed) {
-      fprintf (stderr, "skipping %s, already merged\n", inlist[0].filename[i]);
+      if (VERBOSE) fprintf (stderr, "skipping %s, empty or already merged\n", inlist[0].filename[i]);
+      OutputStatusFree (outstat, outlist->Nregions);
+      dmhObjectStatsFree (inStats);
+      SkyListFree (outlist); 
       continue;
     }
@@ -125,21 +90,22 @@
 	dvo_catalog_unlock (&incatalog);
 	dvo_catalog_free (&incatalog);
+	OutputStatusFree (outstat, outlist->Nregions);
+	dmhObjectStatsFree (inStats);
 	SkyListFree (outlist); 
 	continue;
     }
-
-    char *moddate = ohana_sec_to_date (instats.st_mtime);
 
     // merge input into the appropriate output tables
     for (j = 0; j < outlist[0].Nregions; j++) {
       // skip tables for which the output files are not on this machine
-      if (!HostTableTestHost(outlist[0].regions[j], HOST_ID)) continue; 
+      if (!outstat[j].valid) continue; 
+
+      // skip if we have already done the merge
+      if (!outstat[j].missed) continue; 
 
       if (VERBOSE) fprintf (stderr, "output : %s\n", outlist[0].regions[j][0].name);
 
-      // set the parameters which guide catalog open/load/create
-      char hostfile[DVO_MAX_PATH];
-      snprintf (hostfile, DVO_MAX_PATH, "%s/%s.cpt", HOSTDIR, outlist[0].regions[j]->name);
-      outcatalog.filename  = HOST_ID ? hostfile : outlist[0].filename[j];
+      // the real filename
+      outcatalog.filename = outstat[j].filename; 
 
       // load input catalog
@@ -151,26 +117,5 @@
       outcatalog.catflags = LOAD_AVES | LOAD_MEAS | LOAD_MISS | LOAD_SECF;
 
-# if (0)
-      // get the LMRG data from the previous pass
-      long long last_size;
-      char last_moddate[80];
-      int status_size = gfits_scan (&outcatalog.header, "LMRG_SZ", "%lld", 1, &last_size);      
-      int status_date = gfits_scan (&outcatalog.header, "LMRG_DT", "%s", 1, last_moddate);      
-
-      // save the LMRG data from the previous pass
-      if (status_size && status_date) {
-	gfits_modify (&outcatalog.header, "LMRG_SZ1", "%lld", 1, (long long) last_size);      
-	gfits_modify (&outcatalog.header, "LMRG_DT1", "%s", 1, last_moddate);      
-      }
-
-      // update header of output catalog
-      gfits_modify (&outcatalog.header, "LMRG_SZ", "%lld", 1, (long long) instats.st_size);      
-      gfits_modify (&outcatalog.header, "LMRG_DT", "%s", 1, moddate);      
-# endif
-
-      // update header of output catalog
-      // XXX note that we are hardwired to v 2
-      gfits_modify (&outcatalog.header, "LMRG_SZ2", "%lld", 1, (long long) instats.st_size);      
-      gfits_modify (&outcatalog.header, "LMRG_DT2", "%s", 1, moddate);      
+      dmhObjectAdd (outstat[j].history, &outcatalog.header, inStats);
 
       if (!dvo_catalog_backup (&outcatalog, TRUE)) {
@@ -196,6 +141,8 @@
       fprintf (stderr, "merged %s into %s\n", inlist[0].regions[i][0].name, outlist[0].regions[j][0].name);
     }
+
+    OutputStatusFree (outstat, outlist->Nregions);
     SkyListFree (outlist);
-    free (moddate);
+    dmhObjectStatsFree (inStats);
 
     dvo_catalog_unlock (&incatalog);
Index: trunk/Ohana/src/dvomerge/src/dvoverify.c
===================================================================
--- trunk/Ohana/src/dvomerge/src/dvoverify.c	(revision 34277)
+++ trunk/Ohana/src/dvomerge/src/dvoverify.c	(revision 34405)
@@ -42,4 +42,8 @@
   }
 
+  if (CHECK_IMAGE_ID) {
+    LoadImageIDs (CATDIR);
+  }
+
   // load the sky table for the existing database
   sky = SkyTableLoadOptimal (CATDIR, NULL, NULL, FALSE, SKY_DEPTH_HST, VERBOSE);
Index: trunk/Ohana/src/dvomerge/src/dvoverify_args.c
===================================================================
--- trunk/Ohana/src/dvomerge/src/dvoverify_args.c	(revision 34277)
+++ trunk/Ohana/src/dvomerge/src/dvoverify_args.c	(revision 34405)
@@ -53,4 +53,10 @@
   if ((N = get_argument (*argc, argv, "-skip-toplevel"))) {
     CHECK_TOPLEVEL = FALSE;
+    remove_argument (N, argc, argv);
+  }
+
+  CHECK_IMAGE_ID = TRUE;
+  if ((N = get_argument (*argc, argv, "-skip-image-ids"))) {
+    CHECK_IMAGE_ID = FALSE;
     remove_argument (N, argc, argv);
   }
Index: trunk/Ohana/src/dvomerge/src/dvoverify_catalogs.c
===================================================================
--- trunk/Ohana/src/dvomerge/src/dvoverify_catalogs.c	(revision 34277)
+++ trunk/Ohana/src/dvomerge/src/dvoverify_catalogs.c	(revision 34405)
@@ -100,7 +100,8 @@
 
     char tmpline[DVO_MAX_PATH];
-    if (VERBOSE)      { snprintf (tmpline, DVO_MAX_PATH, "%s -v", command); strcpy (command, tmpline); }
-    if (CHECKSORTED)  { snprintf (tmpline, DVO_MAX_PATH, "%s -s", command); strcpy (command, tmpline); }
-    if (LIST_MISSING) { snprintf (tmpline, DVO_MAX_PATH, "%s -list-missing", command); strcpy (command, tmpline); }
+    if (VERBOSE)         { snprintf (tmpline, DVO_MAX_PATH, "%s -v", command); strcpy (command, tmpline); }
+    if (CHECKSORTED)     { snprintf (tmpline, DVO_MAX_PATH, "%s -s", command); strcpy (command, tmpline); }
+    if (!CHECK_IMAGE_ID) { snprintf (tmpline, DVO_MAX_PATH, "%s -skip-image-ids", command); strcpy (command, tmpline); }
+    if (LIST_MISSING)    { snprintf (tmpline, DVO_MAX_PATH, "%s -list-missing", command); strcpy (command, tmpline); }
 
     fprintf (stderr, "command: %s\n", command);
Index: trunk/Ohana/src/dvomerge/src/dvoverify_client.c
===================================================================
--- trunk/Ohana/src/dvomerge/src/dvoverify_client.c	(revision 34277)
+++ trunk/Ohana/src/dvomerge/src/dvoverify_client.c	(revision 34405)
@@ -19,4 +19,10 @@
   skylist = SkyListByPatch (sky, -1, &UserPatch);
   
+  if (CHECK_IMAGE_ID) {
+    // XXX in client mode, we should be reading a reduced table generated by the calling
+    // serial program
+    LoadImageIDs (CATDIR);
+  }
+
   dvoverify_catalogs (skylist, &Nbad);
 
Index: trunk/Ohana/src/dvomerge/src/dvoverify_utils.c
===================================================================
--- trunk/Ohana/src/dvomerge/src/dvoverify_utils.c	(revision 34277)
+++ trunk/Ohana/src/dvomerge/src/dvoverify_utils.c	(revision 34405)
@@ -49,4 +49,6 @@
 
 // is this file a consistent FITS file?
+// note that VerifyTableFile only has to read the headers,
+// not the data blocks (it uses stat for sizes)
 int VerifyTableFile (char *filename) {
 
@@ -194,5 +196,5 @@
   // \sum average[].Nmeasure = Nmeasure
 
-  // if the table is NOT SORTED, we have a subset of checks we can make
+  // if the table is NOT SORTED, do we have a subset of checks we can make?
   if (!catalog.sorted) {
     fprintf (stderr, "!");
@@ -231,4 +233,6 @@
   }
 
+  // if we have a problem with Nmeasure and/or measureOffset values, we
+  // cannot do any further check -- we risk segfaults
   if (!status) {
     dvo_catalog_unlock (&catalog);
@@ -263,12 +267,12 @@
   }
 
-//  for (i = 0; i < catalog.Naverage; i++) {
-//    m = catalog.average[i].measureOffset;
-//    for (j = 0; i < catalog.Nmeasure; i++) {
-//      objIDsOK &= (catalog.average[i].objID == catalog.measure[m+j].objID);
-//      catIDsOK &= (catalog.average[i].catID == catalog.measure[m+j].catID);
-//      averefOK &= (catalog.measure[m+j].averef = i);
-//    }
-//  }
+  // check the image ID here?
+  if (CHECK_IMAGE_ID) {
+    int Nfail = CheckImageID (&catalog);
+    if (Nfail > 0) {
+      fprintf (stderr, "ERROR: catalog %s has invalid %d unmatched image IDs\n", catalog.filename, Nfail);
+      status = FALSE;
+    }
+  }
 
   dvo_catalog_unlock (&catalog);
@@ -278,6 +282,95 @@
 }
 
-// gfits_scan(&cpmHeaderTBL, "NAXIS1", "%d", 1, &NbytesPerRow);
-// gfits_scan(&cpmHeaderTBL, "NAXIS2", "%d", 1, &Nrows);
-    
+static int maxID = 0;
+static int *IDlist = NULL;
+
+// check that every measure->imageID (if set) matches an existing 
+// image->ID.  return the number of failures.
+int CheckImageID (Catalog *catalog) {
+
+  off_t i, j, m, id;
+  int Nfail = 0;
+
+  for (i = 0; i < catalog[0].Naverage; i++) {
+    m = catalog[0].average[i].measureOffset;
+    for (j = 0; j < catalog[0].average[i].Nmeasure; j++) {
+      id = catalog[0].measure[m+j].imageID;
+      if (id > maxID) {
+	Nfail ++;
+	continue;
+	// is this sufficient to catch IDs set without an image table?
+      }
+      if (IDlist) {
+	if (IDlist[id] < 0) {
+	  Nfail ++;
+	  continue;
+	}
+      } else {
+	if (id > 0) {
+	  Nfail ++;
+	  continue;
+	}
+      }
+    }
+  }
+  return Nfail;
+}
+
+int LoadImageIDs (char *catdir) {
+
+  int status;
+  off_t Nimages, i;
+  Image *images;
+  FITS_DB inDB;
+
+  char ImageCat[DVO_MAX_PATH];
+  snprintf (ImageCat, DVO_MAX_PATH, "%s/Images.dat", catdir);
+
+  // load the iage database table
+  status = dvo_image_lock (&inDB, ImageCat, 3600.0, LCK_SOFT);  // shorter timeout?
+  if (!status) {
+    fprintf (stderr, "ERROR: failure to lock image catalog %s", inDB.filename);
+    exit (3);
+  }
+
+  // load the image table 
+  if (inDB.dbstate == LCK_EMPTY) {
+    dvo_image_unlock (&inDB); // unlock input
+    // this is not an error: we can have no image table for, eg, 2MASS only db
+    return TRUE;
+  }
+  if (!dvo_image_load (&inDB, VERBOSE, TRUE)) {
+    fprintf (stderr, "can't read input image catalog %s", inDB.filename);
+    exit (4);
+  }
+
+  images = gfits_table_get_Image (&inDB.ftable, &Nimages, &inDB.swapped);
+  if (!images) {
+    fprintf (stderr, "ERROR: failed to read images from src\n");
+    exit (2);
+  }
+
+  // generate a lookup table for the images
   
+  // first, find the max imageID
+  for (i = 0; i < Nimages; i++) {
+    maxID = MAX(maxID, images[i].imageID);
+  }
+
+  ALLOCATE (IDlist, int, maxID + 1);
+  for (i = 0; i < maxID + 1; i++) {
+    IDlist[i] = -1;
+  }
+
+  for (i = 0; i < Nimages; i++) {
+    int id = images[i].imageID;
+    IDlist[id] = i;
+  }
+
+  // free image table here?
+  // (in the future, I'll have to do the image table read in segments
+  // it is just getting to be too large...)
+  dvo_image_unlock (&inDB); // unlock input
+
+  return TRUE;
+}
Index: trunk/Ohana/src/dvomerge/src/merge_catalogs_old.c
===================================================================
--- trunk/Ohana/src/dvomerge/src/merge_catalogs_old.c	(revision 34277)
+++ trunk/Ohana/src/dvomerge/src/merge_catalogs_old.c	(revision 34405)
@@ -320,5 +320,5 @@
     output[0].average[Nave].dP        	   = 0;
 
-    output[0].average[Nave].Xp        	   = 0;
+    output[0].average[Nave].stargal   	   = 0;
     output[0].average[Nave].ChiSqAve   	   = 0.0;
     output[0].average[Nave].ChiSqPM   	   = 0.0;
Index: trunk/Ohana/src/dvomerge/test/catdir.grizy/Images.dat
===================================================================
--- trunk/Ohana/src/dvomerge/test/catdir.grizy/Images.dat	(revision 34277)
+++ trunk/Ohana/src/dvomerge/test/catdir.grizy/Images.dat	(revision 34405)
@@ -1,1 +1,1 @@
-SIMPLE  =                    T /                                                BITPIX  =                    8 /                                                NAXIS   =                    0 /                                                PCOUNT  =                    0 /                                                GCOUNT  =                    1 /                                                BSCALE  =         1.0000000000 /                                                BZERO   =         0.0000000000 /                                                EXTEND  =                    T /                                                NIMAGES =                    0 /                                                ZERO_PT =        25.0000000000 /                                                FORMAT  = 'ELIXIR            ' /                                                END                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             XTENSION= 'BINTABLE          ' /                                                BITPIX  =                    8 /                                                NAXIS   =                    2 /                                                NAXIS1  =                  240 /                                                NAXIS2  =                    0 /                                                PCOUNT  =                    0 /                                                GCOUNT  =                    1 /                                                TFIELDS =                   50 /                                                EXTNAME = 'DVO_IMAGE_ELIXIR  ' /                                                TTYPE1  = 'CRVAL1            ' / coordinate at reference pixel                  TUNIT1  = '                  ' /                                                TFORM1  = 'D                 ' /                                                TSCAL1  =         1.0000000000 /                                                TZERO1  =         0.0000000000 /                                                TTYPE2  = 'CRVAL2            ' / coordinate at reference pixel                  TUNIT2  = '                  ' /                                                TFORM2  = 'D                 ' /                                                TSCAL2  =         1.0000000000 /                                                TZERO2  =         0.0000000000 /                                                TTYPE3  = 'CRPIX1            ' / coordinate of reference pixel                  TUNIT3  = '                  ' /                                                TFORM3  = 'E                 ' /                                                TSCAL3  =         1.0000000000 /                                                TZERO3  =         0.0000000000 /                                                TTYPE4  = 'CRPIX2            ' / coordinate of reference pixel                  TUNIT4  = '                  ' /                                                TFORM4  = 'E                 ' /                                                TSCAL4  =         1.0000000000 /                                                TZERO4  =         0.0000000000 /                                                TTYPE5  = 'CDELT1            ' / degrees per pixel                              TUNIT5  = '                  ' /                                                TFORM5  = 'E                 ' /                                                TSCAL5  =         1.0000000000 /                                                TZERO5  =         0.0000000000 /                                                TTYPE6  = 'CDELT2            ' / degrees per pixel                              TUNIT6  = '                  ' /                                                TFORM6  = 'E                 ' /                                                TSCAL6  =         1.0000000000 /                                                TZERO6  =         0.0000000000 /                                                TTYPE7  = 'PC1_1             ' / rotation matrix                                TUNIT7  = '                  ' /                                                TFORM7  = 'E                 ' /                                                TSCAL7  =         1.0000000000 /                                                TZERO7  =         0.0000000000 /                                                TTYPE8  = 'PC1_2             ' / rotation matrix                                TUNIT8  = '                  ' /                                                TFORM8  = 'E                 ' /                                                TSCAL8  =         1.0000000000 /                                                TZERO8  =         0.0000000000 /                                                TTYPE9  = 'PC2_1             ' / rotation matrix                                TUNIT9  = '                  ' /                                                TFORM9  = 'E                 ' /                                                TSCAL9  =         1.0000000000 /                                                TZERO9  =         0.0000000000 /                                                TTYPE10 = 'PC2_2             ' / rotation matrix                                TUNIT10 = '                  ' /                                                TFORM10 = 'E                 ' /                                                TSCAL10 =         1.0000000000 /                                                TZERO10 =         0.0000000000 /                                                TTYPE11 = 'POLYTERMS         ' / higher order warping terms                     TUNIT11 = '                  ' /                                                TFORM11 = '14E               ' /                                                TSCAL11 =         1.0000000000 /                                                TZERO11 =         0.0000000000 /                                                TTYPE12 = 'CTYPE             ' / coordinate type                                TUNIT12 = '                  ' /                                                TFORM12 = '15A               ' /                                                TSCAL12 =         1.0000000000 /                                                TZERO12 =         0.0000000000 /                                                TTYPE13 = 'NPOLYTERMS        ' / order of polynomial                            TUNIT13 = '                  ' /                                                TFORM13 = 'A                 ' /                                                TSCAL13 =         1.0000000000 /                                                TZERO13 =         0.0000000000 /                                                TTYPE14 = 'TZERO             ' / readout time (row 0)                           TUNIT14 = '                  ' /                                                TFORM14 = 'J                 ' /                                                TSCAL14 =         1.0000000000 /                                                TZERO14 =         0.0000000000 /                                                TTYPE15 = 'NSTAR             ' / number of stars on image                       TUNIT15 = '                  ' /                                                TFORM15 = 'J                 ' /                                                TSCAL15 =         1.0000000000 /                                                TZERO15 =         0.0000000000 /                                                TTYPE16 = 'SECZ              ' / airmass                                        TUNIT16 = 'milliairmass      ' /                                                TFORM16 = 'I                 ' /                                                TSCAL16 =         1.0000000000 /                                                TZERO16 =         0.0000000000 /                                                TTYPE17 = 'NX                ' / image width                                    TUNIT17 = '                  ' /                                                TFORM17 = 'I                 ' /                                                TSCAL17 =         1.0000000000 /                                                TZERO17 =         0.0000000000 /                                                TTYPE18 = 'NY                ' / image height                                   TUNIT18 = '                  ' /                                                TFORM18 = 'I                 ' /                                                TSCAL18 =         1.0000000000 /                                                TZERO18 =         0.0000000000 /                                                TTYPE19 = 'APMIFIT           ' / aperture correction                            TUNIT19 = 'millimag          ' /                                                TFORM19 = 'I                 ' /                                                TSCAL19 =         1.0000000000 /                                                TZERO19 =         0.0000000000 /                                                TTYPE20 = 'DAPMIFIT          ' / apmifit error                                  TUNIT20 = 'millimag          ' /                                                TFORM20 = 'I                 ' /                                                TSCAL20 =         1.0000000000 /                                                TZERO20 =         0.0000000000 /                                                TTYPE21 = 'SOURCE            ' / identifier for CCD,                            TUNIT21 = '                  ' /                                                TFORM21 = 'I                 ' /                                                TSCAL21 =         1.0000000000 /                                                TZERO21 =         0.0000000000 /                                                TTYPE22 = 'MCAL              ' / calibration mag                                TUNIT22 = 'millimag          ' /                                                TFORM22 = 'I                 ' /                                                TSCAL22 =         1.0000000000 /                                                TZERO22 =         0.0000000000 /                                                TTYPE23 = 'DMCAL             ' / error on Mcal                                  TUNIT23 = 'millimag          ' /                                                TFORM23 = 'I                 ' /                                                TSCAL23 =         1.0000000000 /                                                TZERO23 =         0.0000000000 /                                                TTYPE24 = 'XM                ' / image chisq                                    TUNIT24 = '10*log(value)     ' /                                                TFORM24 = 'I                 ' /                                                TSCAL24 =         1.0000000000 /                                                TZERO24 =         0.0000000000 /                                                TTYPE25 = 'NAME              ' / name of original image                         TUNIT25 = '                  ' /                                                TFORM25 = '32A               ' /                                                TSCAL25 =         1.0000000000 /                                                TZERO25 =         0.0000000000 /                                                TTYPE26 = 'DETECTION_LIMIT   ' / detection limit                                TUNIT26 = '10*mag            ' /                                                TFORM26 = 'B                 ' /                                                TSCAL26 =         1.0000000000 /                                                TZERO26 =         0.0000000000 /                                                TTYPE27 = 'SATURATION_LIMIT  ' / saturation limit                               TUNIT27 = '10*mag            ' /                                                TFORM27 = 'B                 ' /                                                TSCAL27 =         1.0000000000 /                                                TZERO27 =         0.0000000000 /                                                TTYPE28 = 'CERROR            ' / astrometric error                              TUNIT28 = '50*arcsec         ' /                                                TFORM28 = 'B                 ' /                                                TSCAL28 =         1.0000000000 /                                                TZERO28 =         0.0000000000 /                                                TTYPE29 = 'FWHM_X            ' / PSF x width                                    TUNIT29 = '25*arcsec         ' /                                                TFORM29 = 'B                 ' /                                                TSCAL29 =         1.0000000000 /                                                TZERO29 =         0.0000000000 /                                                TTYPE30 = 'FWHM_Y            ' / PSF y width                                    TUNIT30 = '25*arcsec         ' /                                                TFORM30 = 'B                 ' /                                                TSCAL30 =         1.0000000000 /                                                TZERO30 =         0.0000000000 /                                                TTYPE31 = 'TRATE             ' / scan rate                                      TUNIT31 = '100 usec/pixel    ' /                                                TFORM31 = 'B                 ' /                                                TSCAL31 =         1.0000000000 /                                                TZERO31 =         0.0000000000 /                                                TTYPE32 = 'EXPTIME           ' / exposure time                                  TUNIT32 = 'seconds           ' /                                                TFORM32 = 'E                 ' /                                                TSCAL32 =         1.0000000000 /                                                TZERO32 =         0.0000000000 /                                                TTYPE33 = 'CODE              ' / image quality flag                             TUNIT33 = '                  ' /                                                TFORM33 = 'A                 ' /                                                TSCAL33 =         1.0000000000 /                                                TZERO33 =         0.0000000000 /                                                TTYPE34 = 'CCDNUM            ' / CCD ID number                                  TUNIT34 = '                  ' /                                                TFORM34 = 'B                 ' /                                                TSCAL34 =         1.0000000000 /                                                TZERO34 =         0.0000000000 /                                                TTYPE35 = 'DUMMY             ' / unused                                         TUNIT35 = '                  ' /                                                TFORM35 = '20A               ' /                                                TSCAL35 =         1.0000000000 /                                                TZERO35 =         0.0000000000 /                                                TTYPE36 = 'ORDER             ' / Mrel 2D polynomical order                      TUNIT36 = '                  ' /                                                TFORM36 = 'I                 ' /                                                TSCAL36 =         1.0000000000 /                                                TZERO36 =         0.0000000000 /                                                TTYPE37 = 'MX                ' / Mrel polyterm                                  TUNIT37 = '                  ' /                                                TFORM37 = 'I                 ' /                                                TSCAL37 =         1.0000000000 /                                                TZERO37 =         0.0000000000 /                                                TTYPE38 = 'MY                ' / Mrel polyterm                                  TUNIT38 = '                  ' /                                                TFORM38 = 'I                 ' /                                                TSCAL38 =         1.0000000000 /                                                TZERO38 =         0.0000000000 /                                                TTYPE39 = 'MXX               ' / Mrel polyterm                                  TUNIT39 = '                  ' /                                                TFORM39 = 'I                 ' /                                                TSCAL39 =         1.0000000000 /                                                TZERO39 =         0.0000000000 /                                                TTYPE40 = 'MXY               ' / Mrel polyterm                                  TUNIT40 = '                  ' /                                                TFORM40 = 'I                 ' /                                                TSCAL40 =         1.0000000000 /                                                TZERO40 =         0.0000000000 /                                                TTYPE41 = 'MYY               ' / Mrel polyterm                                  TUNIT41 = '                  ' /                                                TFORM41 = 'I                 ' /                                                TSCAL41 =         1.0000000000 /                                                TZERO41 =         0.0000000000 /                                                TTYPE42 = 'MXXX              ' / Mrel polyterm                                  TUNIT42 = '                  ' /                                                TFORM42 = 'I                 ' /                                                TSCAL42 =         1.0000000000 /                                                TZERO42 =         0.0000000000 /                                                TTYPE43 = 'MXXY              ' / Mrel polyterm                                  TUNIT43 = '                  ' /                                                TFORM43 = 'I                 ' /                                                TSCAL43 =         1.0000000000 /                                                TZERO43 =         0.0000000000 /                                                TTYPE44 = 'MXYY              ' / Mrel polyterm                                  TUNIT44 = '                  ' /                                                TFORM44 = 'I                 ' /                                                TSCAL44 =         1.0000000000 /                                                TZERO44 =         0.0000000000 /                                                TTYPE45 = 'MYYY              ' / Mrel polyterm                                  TUNIT45 = '                  ' /                                                TFORM45 = 'I                 ' /                                                TSCAL45 =         1.0000000000 /                                                TZERO45 =         0.0000000000 /                                                TTYPE46 = 'MXXXX             ' / Mrel polyterm                                  TUNIT46 = '                  ' /                                                TFORM46 = 'I                 ' /                                                TSCAL46 =         1.0000000000 /                                                TZERO46 =         0.0000000000 /                                                TTYPE47 = 'MXXXY             ' / Mrel polyterm                                  TUNIT47 = '                  ' /                                                TFORM47 = 'I                 ' /                                                TSCAL47 =         1.0000000000 /                                                TZERO47 =         0.0000000000 /                                                TTYPE48 = 'MXXYY             ' / Mrel polyterm                                  TUNIT48 = '                  ' /                                                TFORM48 = 'I                 ' /                                                TSCAL48 =         1.0000000000 /                                                TZERO48 =         0.0000000000 /                                                TTYPE49 = 'MXYYY             ' / Mrel polyterm                                  TUNIT49 = '                  ' /                                                TFORM49 = 'I                 ' /                                                TSCAL49 =         1.0000000000 /                                                TZERO49 =         0.0000000000 /                                                TTYPE50 = 'MYYYY             ' / Mrel polyterm                                  TUNIT50 = '                  ' /                                                TFORM50 = 'I                 ' /                                                TSCAL50 =         1.0000000000 /                                                TZERO50 =         0.0000000000 /                                                END                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
+SIMPLE  =                    T /                                                BITPIX  =                    8 /                                                NAXIS   =                    0 /                                                PCOUNT  =                    0 /                                                GCOUNT  =                    1 /                                                BSCALE  =         1.0000000000 /                                                BZERO   =         0.0000000000 /                                                EXTEND  =                    T /                                                NIMAGES =                    0 /                                                ZERO_PT =        25.0000000000 /                                                FORMAT  = 'ELIXIR            ' /                                                DVO_DBID= 'c2fa2cdbac0df952ae954ed04381e219' /                                  END                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             XTENSION= 'BINTABLE          ' /                                                BITPIX  =                    8 /                                                NAXIS   =                    2 /                                                NAXIS1  =                  240 /                                                NAXIS2  =                    0 /                                                PCOUNT  =                    0 /                                                GCOUNT  =                    1 /                                                TFIELDS =                   50 /                                                EXTNAME = 'DVO_IMAGE_ELIXIR  ' /                                                TTYPE1  = 'CRVAL1            ' / coordinate at reference pixel                  TUNIT1  = '                  ' /                                                TFORM1  = 'D                 ' /                                                TSCAL1  =         1.0000000000 /                                                TZERO1  =         0.0000000000 /                                                TTYPE2  = 'CRVAL2            ' / coordinate at reference pixel                  TUNIT2  = '                  ' /                                                TFORM2  = 'D                 ' /                                                TSCAL2  =         1.0000000000 /                                                TZERO2  =         0.0000000000 /                                                TTYPE3  = 'CRPIX1            ' / coordinate of reference pixel                  TUNIT3  = '                  ' /                                                TFORM3  = 'E                 ' /                                                TSCAL3  =         1.0000000000 /                                                TZERO3  =         0.0000000000 /                                                TTYPE4  = 'CRPIX2            ' / coordinate of reference pixel                  TUNIT4  = '                  ' /                                                TFORM4  = 'E                 ' /                                                TSCAL4  =         1.0000000000 /                                                TZERO4  =         0.0000000000 /                                                TTYPE5  = 'CDELT1            ' / degrees per pixel                              TUNIT5  = '                  ' /                                                TFORM5  = 'E                 ' /                                                TSCAL5  =         1.0000000000 /                                                TZERO5  =         0.0000000000 /                                                TTYPE6  = 'CDELT2            ' / degrees per pixel                              TUNIT6  = '                  ' /                                                TFORM6  = 'E                 ' /                                                TSCAL6  =         1.0000000000 /                                                TZERO6  =         0.0000000000 /                                                TTYPE7  = 'PC1_1             ' / rotation matrix                                TUNIT7  = '                  ' /                                                TFORM7  = 'E                 ' /                                                TSCAL7  =         1.0000000000 /                                                TZERO7  =         0.0000000000 /                                                TTYPE8  = 'PC1_2             ' / rotation matrix                                TUNIT8  = '                  ' /                                                TFORM8  = 'E                 ' /                                                TSCAL8  =         1.0000000000 /                                                TZERO8  =         0.0000000000 /                                                TTYPE9  = 'PC2_1             ' / rotation matrix                                TUNIT9  = '                  ' /                                                TFORM9  = 'E                 ' /                                                TSCAL9  =         1.0000000000 /                                                TZERO9  =         0.0000000000 /                                                TTYPE10 = 'PC2_2             ' / rotation matrix                                TUNIT10 = '                  ' /                                                TFORM10 = 'E                 ' /                                                TSCAL10 =         1.0000000000 /                                                TZERO10 =         0.0000000000 /                                                TTYPE11 = 'POLYTERMS         ' / higher order warping terms                     TUNIT11 = '                  ' /                                                TFORM11 = '14E               ' /                                                TSCAL11 =         1.0000000000 /                                                TZERO11 =         0.0000000000 /                                                TTYPE12 = 'CTYPE             ' / coordinate type                                TUNIT12 = '                  ' /                                                TFORM12 = '15A               ' /                                                TSCAL12 =         1.0000000000 /                                                TZERO12 =         0.0000000000 /                                                TTYPE13 = 'NPOLYTERMS        ' / order of polynomial                            TUNIT13 = '                  ' /                                                TFORM13 = 'A                 ' /                                                TSCAL13 =         1.0000000000 /                                                TZERO13 =         0.0000000000 /                                                TTYPE14 = 'TZERO             ' / readout time (row 0)                           TUNIT14 = '                  ' /                                                TFORM14 = 'J                 ' /                                                TSCAL14 =         1.0000000000 /                                                TZERO14 =         0.0000000000 /                                                TTYPE15 = 'NSTAR             ' / number of stars on image                       TUNIT15 = '                  ' /                                                TFORM15 = 'J                 ' /                                                TSCAL15 =         1.0000000000 /                                                TZERO15 =         0.0000000000 /                                                TTYPE16 = 'SECZ              ' / airmass                                        TUNIT16 = 'milliairmass      ' /                                                TFORM16 = 'I                 ' /                                                TSCAL16 =         1.0000000000 /                                                TZERO16 =         0.0000000000 /                                                TTYPE17 = 'NX                ' / image width                                    TUNIT17 = '                  ' /                                                TFORM17 = 'I                 ' /                                                TSCAL17 =         1.0000000000 /                                                TZERO17 =         0.0000000000 /                                                TTYPE18 = 'NY                ' / image height                                   TUNIT18 = '                  ' /                                                TFORM18 = 'I                 ' /                                                TSCAL18 =         1.0000000000 /                                                TZERO18 =         0.0000000000 /                                                TTYPE19 = 'APMIFIT           ' / aperture correction                            TUNIT19 = 'millimag          ' /                                                TFORM19 = 'I                 ' /                                                TSCAL19 =         1.0000000000 /                                                TZERO19 =         0.0000000000 /                                                TTYPE20 = 'DAPMIFIT          ' / apmifit error                                  TUNIT20 = 'millimag          ' /                                                TFORM20 = 'I                 ' /                                                TSCAL20 =         1.0000000000 /                                                TZERO20 =         0.0000000000 /                                                TTYPE21 = 'SOURCE            ' / identifier for CCD,                            TUNIT21 = '                  ' /                                                TFORM21 = 'I                 ' /                                                TSCAL21 =         1.0000000000 /                                                TZERO21 =         0.0000000000 /                                                TTYPE22 = 'MCAL              ' / calibration mag                                TUNIT22 = 'millimag          ' /                                                TFORM22 = 'I                 ' /                                                TSCAL22 =         1.0000000000 /                                                TZERO22 =         0.0000000000 /                                                TTYPE23 = 'DMCAL             ' / error on Mcal                                  TUNIT23 = 'millimag          ' /                                                TFORM23 = 'I                 ' /                                                TSCAL23 =         1.0000000000 /                                                TZERO23 =         0.0000000000 /                                                TTYPE24 = 'XM                ' / image chisq                                    TUNIT24 = '10*log(value)     ' /                                                TFORM24 = 'I                 ' /                                                TSCAL24 =         1.0000000000 /                                                TZERO24 =         0.0000000000 /                                                TTYPE25 = 'NAME              ' / name of original image                         TUNIT25 = '                  ' /                                                TFORM25 = '32A               ' /                                                TSCAL25 =         1.0000000000 /                                                TZERO25 =         0.0000000000 /                                                TTYPE26 = 'DETECTION_LIMIT   ' / detection limit                                TUNIT26 = '10*mag            ' /                                                TFORM26 = 'B                 ' /                                                TSCAL26 =         1.0000000000 /                                                TZERO26 =         0.0000000000 /                                                TTYPE27 = 'SATURATION_LIMIT  ' / saturation limit                               TUNIT27 = '10*mag            ' /                                                TFORM27 = 'B                 ' /                                                TSCAL27 =         1.0000000000 /                                                TZERO27 =         0.0000000000 /                                                TTYPE28 = 'CERROR            ' / astrometric error                              TUNIT28 = '50*arcsec         ' /                                                TFORM28 = 'B                 ' /                                                TSCAL28 =         1.0000000000 /                                                TZERO28 =         0.0000000000 /                                                TTYPE29 = 'FWHM_X            ' / PSF x width                                    TUNIT29 = '25*arcsec         ' /                                                TFORM29 = 'B                 ' /                                                TSCAL29 =         1.0000000000 /                                                TZERO29 =         0.0000000000 /                                                TTYPE30 = 'FWHM_Y            ' / PSF y width                                    TUNIT30 = '25*arcsec         ' /                                                TFORM30 = 'B                 ' /                                                TSCAL30 =         1.0000000000 /                                                TZERO30 =         0.0000000000 /                                                TTYPE31 = 'TRATE             ' / scan rate                                      TUNIT31 = '100 usec/pixel    ' /                                                TFORM31 = 'B                 ' /                                                TSCAL31 =         1.0000000000 /                                                TZERO31 =         0.0000000000 /                                                TTYPE32 = 'EXPTIME           ' / exposure time                                  TUNIT32 = 'seconds           ' /                                                TFORM32 = 'E                 ' /                                                TSCAL32 =         1.0000000000 /                                                TZERO32 =         0.0000000000 /                                                TTYPE33 = 'CODE              ' / image quality flag                             TUNIT33 = '                  ' /                                                TFORM33 = 'A                 ' /                                                TSCAL33 =         1.0000000000 /                                                TZERO33 =         0.0000000000 /                                                TTYPE34 = 'CCDNUM            ' / CCD ID number                                  TUNIT34 = '                  ' /                                                TFORM34 = 'B                 ' /                                                TSCAL34 =         1.0000000000 /                                                TZERO34 =         0.0000000000 /                                                TTYPE35 = 'DUMMY             ' / unused                                         TUNIT35 = '                  ' /                                                TFORM35 = '20A               ' /                                                TSCAL35 =         1.0000000000 /                                                TZERO35 =         0.0000000000 /                                                TTYPE36 = 'ORDER             ' / Mrel 2D polynomical order                      TUNIT36 = '                  ' /                                                TFORM36 = 'I                 ' /                                                TSCAL36 =         1.0000000000 /                                                TZERO36 =         0.0000000000 /                                                TTYPE37 = 'MX                ' / Mrel polyterm                                  TUNIT37 = '                  ' /                                                TFORM37 = 'I                 ' /                                                TSCAL37 =         1.0000000000 /                                                TZERO37 =         0.0000000000 /                                                TTYPE38 = 'MY                ' / Mrel polyterm                                  TUNIT38 = '                  ' /                                                TFORM38 = 'I                 ' /                                                TSCAL38 =         1.0000000000 /                                                TZERO38 =         0.0000000000 /                                                TTYPE39 = 'MXX               ' / Mrel polyterm                                  TUNIT39 = '                  ' /                                                TFORM39 = 'I                 ' /                                                TSCAL39 =         1.0000000000 /                                                TZERO39 =         0.0000000000 /                                                TTYPE40 = 'MXY               ' / Mrel polyterm                                  TUNIT40 = '                  ' /                                                TFORM40 = 'I                 ' /                                                TSCAL40 =         1.0000000000 /                                                TZERO40 =         0.0000000000 /                                                TTYPE41 = 'MYY               ' / Mrel polyterm                                  TUNIT41 = '                  ' /                                                TFORM41 = 'I                 ' /                                                TSCAL41 =         1.0000000000 /                                                TZERO41 =         0.0000000000 /                                                TTYPE42 = 'MXXX              ' / Mrel polyterm                                  TUNIT42 = '                  ' /                                                TFORM42 = 'I                 ' /                                                TSCAL42 =         1.0000000000 /                                                TZERO42 =         0.0000000000 /                                                TTYPE43 = 'MXXY              ' / Mrel polyterm                                  TUNIT43 = '                  ' /                                                TFORM43 = 'I                 ' /                                                TSCAL43 =         1.0000000000 /                                                TZERO43 =         0.0000000000 /                                                TTYPE44 = 'MXYY              ' / Mrel polyterm                                  TUNIT44 = '                  ' /                                                TFORM44 = 'I                 ' /                                                TSCAL44 =         1.0000000000 /                                                TZERO44 =         0.0000000000 /                                                TTYPE45 = 'MYYY              ' / Mrel polyterm                                  TUNIT45 = '                  ' /                                                TFORM45 = 'I                 ' /                                                TSCAL45 =         1.0000000000 /                                                TZERO45 =         0.0000000000 /                                                TTYPE46 = 'MXXXX             ' / Mrel polyterm                                  TUNIT46 = '                  ' /                                                TFORM46 = 'I                 ' /                                                TSCAL46 =         1.0000000000 /                                                TZERO46 =         0.0000000000 /                                                TTYPE47 = 'MXXXY             ' / Mrel polyterm                                  TUNIT47 = '                  ' /                                                TFORM47 = 'I                 ' /                                                TSCAL47 =         1.0000000000 /                                                TZERO47 =         0.0000000000 /                                                TTYPE48 = 'MXXYY             ' / Mrel polyterm                                  TUNIT48 = '                  ' /                                                TFORM48 = 'I                 ' /                                                TSCAL48 =         1.0000000000 /                                                TZERO48 =         0.0000000000 /                                                TTYPE49 = 'MXYYY             ' / Mrel polyterm                                  TUNIT49 = '                  ' /                                                TFORM49 = 'I                 ' /                                                TSCAL49 =         1.0000000000 /                                                TZERO49 =         0.0000000000 /                                                TTYPE50 = 'MYYYY             ' / Mrel polyterm                                  TUNIT50 = '                  ' /                                                TFORM50 = 'I                 ' /                                                TSCAL50 =         1.0000000000 /                                                TZERO50 =         0.0000000000 /                                                END                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
