Index: /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/include/dvo.h
===================================================================
--- /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/include/dvo.h	(revision 37376)
+++ /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/include/dvo.h	(revision 37377)
@@ -948,4 +948,8 @@
 void dvo_image_create (FITS_DB *db, double ZeroPoint);
 
+int gfits_table_set_Image (FTable *ftable);
+int gfits_table_mkheader_Image (Header *header);
+Image *gfits_table_get_Image (FTable *ftable, off_t *Ndata, char *swapped);
+
 /* flatcorr APIs */
 FlatCorrectionTable *FlatCorrectionLoad (char *filename, int VERBOSE);
Index: /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/ImageMetadata.c
===================================================================
--- /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/ImageMetadata.c	(revision 37376)
+++ /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/ImageMetadata.c	(revision 37377)
@@ -156,13 +156,13 @@
   // assign the storage arrays
   for (i = 0; i < Nimage; i++) {
-    int Nmosaic = FindMosaicForImage (image, Nimage, i);
-    if (!Nmosaic) continue;
-    Nmosaic --;
+    if (!image[i].coords.mosaic) continue;
     imageID[i]  = image[i].imageID;
     externID[i] = image[i].externID;
-    crval1[i]   = image[Nmosaic].coords.crval1;
-    crval2[i]   = image[Nmosaic].coords.crval2;
-
-    theta[i]    = DEG_RAD*atan2(image[Nmosaic].coords.pc1_2, image[Nmosaic].coords.pc1_1);
+    Coords *mosaic = image[i].coords.mosaic;
+
+    crval1[i]   = mosaic->crval1;
+    crval2[i]   = mosaic->crval2;
+
+    theta[i]    = DEG_RAD*atan2(mosaic->pc1_2, mosaic->pc1_1);
 
     Mcal[i]     = image[i].Mcal;
Index: /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/ImageOps.c
===================================================================
--- /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/ImageOps.c	(revision 37376)
+++ /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/ImageOps.c	(revision 37377)
@@ -55,5 +55,4 @@
     if (TimeSelect && ((image[i].tzero < tzero) || (image[i].tzero+image[i].trate*image[i].NY > tzero + trange))) continue;
     if (selection->useDisplay) {
-      if (!FindMosaicForImage (image, Nimage, i)) continue;
       // first check if region center is in image
       status = RD_to_XY (&X, &Y, Rmid, graph.coords.crval2, &image[i].coords);
@@ -89,5 +88,4 @@
     }
     if (selection->useSkyregion) {
-      if (!FindMosaicForImage (image, Nimage, i)) continue;
       /* project this image to screen display coords */
       x[0] = 0;           y[0] = 0;
Index: /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/ImageSelection.c
===================================================================
--- /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/ImageSelection.c	(revision 37376)
+++ /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/ImageSelection.c	(revision 37377)
@@ -64,5 +64,4 @@
   }
   if (m == -1) return (NULL);
-  if (!FindMosaicForImage (image, Nimage, m)) return (NULL);
   return (&image[m]);
 }
@@ -85,5 +84,4 @@
   }
   if (m == -1) return (NULL);
-  if (!FindMosaicForImage (image, Nimage, m)) return (NULL);
   return (&image[m]);
 }
Index: /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/coordops.c
===================================================================
--- /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/coordops.c	(revision 37376)
+++ /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/coordops.c	(revision 37377)
@@ -3,4 +3,6 @@
 /* note that Coords.ctype carries the DEC (ctype2) value */
 
+// this was previously coded not-thread-safe: I've added the mosaic link directly to the Coords structure
+# if (0)
 static Coords mosaic;
 static int gotMosaic = FALSE;
@@ -19,4 +21,5 @@
   return (TRUE);
 }
+# endif
 
 int XY_to_LM (double *L, double *M, double x, double y, Coords *coords) {
@@ -78,6 +81,9 @@
     /* mosaic astrometry : WRP is chip astrometry; apply mosaic (DIS) term */
     if (proj == PROJ_WRP) {
-      if (!gotMosaic) return (FALSE);
-      XY_to_RD (ra, dec, L, M, &mosaic);
+      if (!coords->mosaic) {
+	myAbort ("missing mosaic element");
+	return (FALSE);
+      }
+      XY_to_RD (ra, dec, L, M, coords->mosaic);
     }
     return (TRUE);
@@ -208,6 +214,9 @@
   if (mode == PROJ_MODE_CARTESIAN) {
     if (proj == PROJ_WRP) {
-      if (!gotMosaic) return (FALSE);
-      RD_to_XY (L, M, ra, dec, &mosaic);
+      if (!coords->mosaic) {
+	myAbort ("missing mosaic element");
+	return (FALSE);
+      }
+      RD_to_XY (L, M, ra, dec, coords->mosaic);
       return (TRUE);
     }
Index: /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dbExtractImages.c
===================================================================
--- /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dbExtractImages.c	(revision 37376)
+++ /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dbExtractImages.c	(revision 37377)
@@ -59,5 +59,4 @@
   time_t t;
   dbValue value;
-  off_t Nmosaic;
 
   value.Flt = NAN;
@@ -68,5 +67,4 @@
     case IMAGE_RA:
       if (!haveCelestial) {
-	if (!FindMosaicForImage (image, Nimage, N)) return value;
 	if (!strcmp(&image[N].coords.ctype[4], "-DIS")) {
 	  x = 0.0;
@@ -83,5 +81,4 @@
     case IMAGE_DEC:
       if (!haveCelestial) {
-	if (!FindMosaicForImage (image, Nimage, N)) return value;
 	if (!strcmp(&image[N].coords.ctype[4], "-DIS")) {
 	  x = 0.0;
@@ -99,5 +96,4 @@
       if (!haveGalactic) {
 	if (!haveCelestial) {
-	  if (!FindMosaicForImage (image, Nimage, N)) return value;
 	  if (!strcmp(&image[N].coords.ctype[4], "-DIS")) {
 	    x = 0.0;
@@ -118,5 +114,4 @@
       if (!haveGalactic) {
 	if (!haveCelestial) {
-	  if (!FindMosaicForImage (image, Nimage, N)) return value;
 	  if (!strcmp(&image[N].coords.ctype[4], "-DIS")) {
 	    x = 0.0;
@@ -137,5 +132,4 @@
       if (!haveEcliptic) {
 	if (!haveCelestial) {
-	  if (!FindMosaicForImage (image, Nimage, N)) return value;
 	  if (!strcmp(&image[N].coords.ctype[4], "-DIS")) {
 	    x = 0.0;
@@ -156,5 +150,4 @@
       if (!haveEcliptic) {
 	if (!haveCelestial) {
-	  if (!FindMosaicForImage (image, Nimage, N)) return value;
 	  if (!strcmp(&image[N].coords.ctype[4], "-DIS")) {
 	    x = 0.0;
@@ -269,17 +262,14 @@
 
     case IMAGE_FWHM_MEDIAN:
-      if (!(Nmosaic = FindMosaicForImage (image, Nimage, N))) return value;
-      Nmosaic --; // XXX kind of a hack: FindMosaicForImage returns 0 or the mosaic seq number + 1
-      value.Flt = (image[Nmosaic].fwhm_x + image[Nmosaic].fwhm_y) / 50.0;
+      if (!image[N].parent) return value;
+      value.Flt = (image[N].parent->fwhm_x + image[N].parent->fwhm_y) / 50.0;
       break;
     case IMAGE_FWHM_MAJ_MEDIAN:
-      if (!(Nmosaic = FindMosaicForImage (image, Nimage, N))) return value;
-      Nmosaic --; // XXX kind of a hack: FindMosaicForImage returns 0 or the mosaic seq number + 1
-      value.Flt = image[Nmosaic].fwhm_x / 25.0;
+      if (!image[N].parent) return value;
+      value.Flt = image[N].parent->fwhm_x / 25.0;
       break;
     case IMAGE_FWHM_MIN_MEDIAN:
-      if (!(Nmosaic = FindMosaicForImage (image, Nimage, N))) return value;
-      Nmosaic --; // XXX kind of a hack: FindMosaicForImage returns 0 or the mosaic seq number + 1
-      value.Flt = image[Nmosaic].fwhm_y / 25.0;
+      if (!image[N].parent) return value;
+      value.Flt = image[N].parent->fwhm_y / 25.0;
       break;
 
Index: /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dbExtractMeasures.c
===================================================================
--- /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dbExtractMeasures.c	(revision 37376)
+++ /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dbExtractMeasures.c	(revision 37377)
@@ -581,12 +581,5 @@
     case MEAS_XMOSAIC: /* offset relative to exposure center in camera coords */
       if (!haveMosaicMeas) {
-	if (REMOTE_CLIENT) {
-	  mosaic = MatchMosaicMetadata (measure[0].imageID);
-	} else {
-	  // fprintf (stderr, "non-parallel Xmos broken\n");
-	  // abort();
-	  // mosaic = MatchMosaic (measure[0].t, measure[0].photcode);
-	  mosaic = MatchMosaicMetadata (measure[0].imageID);
-	}
+	mosaic = MatchMosaicMetadata (measure[0].imageID);
 	if (mosaic == NULL) break;
 	double Rm = measure[0].R;
@@ -598,12 +591,5 @@
     case MEAS_YMOSAIC: /* OK */
       if (!haveMosaicMeas) {
-	if (REMOTE_CLIENT) {
-	  mosaic = MatchMosaicMetadata (measure[0].imageID);
-	} else {
-	  // fprintf (stderr, "non-parallel Xmos broken\n");
-	  // abort();
-	  // mosaic = MatchMosaic (measure[0].t, measure[0].photcode);
-	  mosaic = MatchMosaicMetadata (measure[0].imageID);
-	}
+	mosaic = MatchMosaicMetadata (measure[0].imageID);
 	if (mosaic == NULL) break;
 	double Rm = measure[0].R;
Index: /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert.c
===================================================================
--- /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert.c	(revision 37376)
+++ /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert.c	(revision 37377)
@@ -643,15 +643,4 @@
     return (TRUE); }
 
-  if (!strcmp (extname, "DVO_IMAGE")) {
-    Image *image;
-    image = gfits_table_get_Image (ftable, &Nimage, NULL);
-    if (!image) {
-      fprintf (stderr, "ERROR: failed to read images\n");
-      exit (2);
-    }
-    *format = DVO_FORMAT_INTERNAL;
-    return (TRUE);
-  }
-
   CONVERT_FORMAT ("DVO_IMAGE_ELIXIR", 	       ELIXIR,          Elixir);
   CONVERT_FORMAT ("DVO_IMAGE_LONEOS", 	       LONEOS,          Loneos);
@@ -690,8 +679,4 @@
   /* convert from the internal format */
   switch (format) {
-    case DVO_FORMAT_INTERNAL: {
-      gfits_convert_Image ((Image *) ftable[0].buffer, sizeof(Image), Nimage);
-      break; }
-
       FORMAT_CASE (ELIXIR, 	    Elixir);
       FORMAT_CASE (LONEOS, 	    Loneos);
@@ -744,10 +729,4 @@
   /* convert from the internal format */
   switch (format) {
-    case DVO_FORMAT_INTERNAL: {
-      for (i = 0; i < Nrow; i++) {
-	gfits_convert_Image ((Image *) vtable[0].buffer[i], sizeof(Image), 1);
-      }
-      return (TRUE); }
-
       FORMAT_CASE (ELIXIR, 	    Elixir);
       FORMAT_CASE (LONEOS, 	    Loneos);
Index: /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert_PS1_DEV_1.c
===================================================================
--- /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert_PS1_DEV_1.c	(revision 37376)
+++ /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert_PS1_DEV_1.c	(revision 37377)
@@ -219,5 +219,8 @@
 
   for (i = 0; i < Nvalues; i++) {
-    memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
+    // this is only safe because the initial 120 bytes in Coords match CoordsDisk
+    memcpy (&out[i].coords, &in[i].coords, sizeof(CoordsDisk));
+    out[i].coords.mosaic   = NULL;
+    out[i].coords.imageMap = NULL;
 
     // RAW_IMAGE_NAME_LEN < DVO_IMAGE_NAME_LEN
@@ -287,5 +290,6 @@
 
   for (i = 0; i < Nvalues; i++) {
-    memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
+    // this is only safe because the initial 120 bytes in Coords match CoordsDisk
+    memcpy (&out[i].coords, &in[i].coords, sizeof(CoordsDisk));
 
     // RAW_IMAGE_NAME_LEN < DVO_IMAGE_NAME_LEN
Index: /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert_PS1_DEV_2.c
===================================================================
--- /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert_PS1_DEV_2.c	(revision 37376)
+++ /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert_PS1_DEV_2.c	(revision 37377)
@@ -214,5 +214,8 @@
 
   for (i = 0; i < Nvalues; i++) {
-    memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
+    // this is only safe because the initial 120 bytes in Coords match CoordsDisk
+    memcpy (&out[i].coords, &in[i].coords, sizeof(CoordsDisk));
+    out[i].coords.mosaic   = NULL;
+    out[i].coords.imageMap = NULL;
 
     // RAW_IMAGE_NAME_LEN < DVO_IMAGE_NAME_LEN
@@ -279,5 +282,6 @@
 
   for (i = 0; i < Nvalues; i++) {
-    memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
+    // this is only safe because the initial 120 bytes in Coords match CoordsDisk
+    memcpy (&out[i].coords, &in[i].coords, sizeof(CoordsDisk));
 
     // RAW_IMAGE_NAME_LEN < DVO_IMAGE_NAME_LEN
Index: /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert_PS1_DEV_3.c
===================================================================
--- /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert_PS1_DEV_3.c	(revision 37376)
+++ /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert_PS1_DEV_3.c	(revision 37377)
@@ -18,5 +18,8 @@
 
   for (i = 0; i < Nvalues; i++) {
-    memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
+    // this is only safe because the initial 120 bytes in Coords match CoordsDisk
+    memcpy (&out[i].coords, &in[i].coords, sizeof(CoordsDisk));
+    out[i].coords.mosaic   = NULL;
+    out[i].coords.imageMap = NULL;
 
     // RAW_IMAGE_NAME_LEN > DVO_IMAGE_NAME_LEN
@@ -78,5 +81,6 @@
 
   for (i = 0; i < Nvalues; i++) {
-    memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
+    // this is only safe because the initial 120 bytes in Coords match CoordsDisk
+    memcpy (&out[i].coords, &in[i].coords, sizeof(CoordsDisk));
 
     // RAW_IMAGE_NAME_LEN > DVO_IMAGE_NAME_LEN
Index: /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert_PS1_REF.c
===================================================================
--- /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert_PS1_REF.c	(revision 37376)
+++ /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert_PS1_REF.c	(revision 37377)
@@ -145,5 +145,8 @@
 
   for (i = 0; i < Nvalues; i++) {
-    memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
+    // this is only safe because the initial 120 bytes in Coords match CoordsDisk
+    memcpy (&out[i].coords, &in[i].coords, sizeof(CoordsDisk));
+    out[i].coords.mosaic   = NULL;
+    out[i].coords.imageMap = NULL;
 
     // RAW_IMAGE_NAME_LEN > DVO_IMAGE_NAME_LEN
@@ -208,5 +211,6 @@
 
   for (i = 0; i < Nvalues; i++) {
-    memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
+    // this is only safe because the initial 120 bytes in Coords match CoordsDisk
+    memcpy (&out[i].coords, &in[i].coords, sizeof(CoordsDisk));
 
     // RAW_IMAGE_NAME_LEN > DVO_IMAGE_NAME_LEN
Index: /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert_PS1_V1.c
===================================================================
--- /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert_PS1_V1.c	(revision 37376)
+++ /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert_PS1_V1.c	(revision 37377)
@@ -238,5 +238,8 @@
 
   for (i = 0; i < Nvalues; i++) {
-    memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
+    // this is only safe because the initial 120 bytes in Coords match CoordsDisk
+    memcpy (&out[i].coords, &in[i].coords, sizeof(CoordsDisk));
+    out[i].coords.mosaic   = NULL;
+    out[i].coords.imageMap = NULL;
 
     // RAW_IMAGE_NAME_LEN > DVO_IMAGE_NAME_LEN
@@ -302,5 +305,6 @@
 
   for (i = 0; i < Nvalues; i++) {
-    memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
+    // this is only safe because the initial 120 bytes in Coords match CoordsDisk
+    memcpy (&out[i].coords, &in[i].coords, sizeof(CoordsDisk));
 
     // RAW_IMAGE_NAME_LEN > DVO_IMAGE_NAME_LEN
Index: /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert_PS1_V2.c
===================================================================
--- /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert_PS1_V2.c	(revision 37376)
+++ /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert_PS1_V2.c	(revision 37377)
@@ -249,5 +249,8 @@
 
   for (i = 0; i < Nvalues; i++) {
-    memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
+    // this is only safe because the initial 120 bytes in Coords match CoordsDisk
+    memcpy (&out[i].coords, &in[i].coords, sizeof(CoordsDisk));
+    out[i].coords.mosaic   = NULL;
+    out[i].coords.imageMap = NULL;
 
     // RAW_IMAGE_NAME_LEN > DVO_IMAGE_NAME_LEN
@@ -313,5 +316,6 @@
 
   for (i = 0; i < Nvalues; i++) {
-    memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
+    // this is only safe because the initial 120 bytes in Coords match CoordsDisk
+    memcpy (&out[i].coords, &in[i].coords, sizeof(CoordsDisk));
 
     // RAW_IMAGE_NAME_LEN > DVO_IMAGE_NAME_LEN
Index: /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert_PS1_V3.c
===================================================================
--- /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert_PS1_V3.c	(revision 37376)
+++ /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert_PS1_V3.c	(revision 37377)
@@ -259,5 +259,8 @@
 
   for (i = 0; i < Nvalues; i++) {
-    memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
+    // this is only safe because the initial 120 bytes in Coords match CoordsDisk
+    memcpy (&out[i].coords, &in[i].coords, sizeof(CoordsDisk));
+    out[i].coords.mosaic   = NULL;
+    out[i].coords.imageMap = NULL;
 
     // RAW_IMAGE_NAME_LEN > DVO_IMAGE_NAME_LEN
@@ -323,5 +326,6 @@
 
   for (i = 0; i < Nvalues; i++) {
-    memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
+    // this is only safe because the initial 120 bytes in Coords match CoordsDisk
+    memcpy (&out[i].coords, &in[i].coords, sizeof(CoordsDisk));
 
     // RAW_IMAGE_NAME_LEN > DVO_IMAGE_NAME_LEN
Index: /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert_PS1_V4.c
===================================================================
--- /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert_PS1_V4.c	(revision 37376)
+++ /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert_PS1_V4.c	(revision 37377)
@@ -299,5 +299,8 @@
 
   for (i = 0; i < Nvalues; i++) {
-    memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
+    // this is only save because the initial 120 bytes in Coords match CoordsDisk
+    memcpy (&out[i].coords, &in[i].coords, sizeof(CoordsDisk));
+    out[i].coords.mosaic   = NULL;
+    out[i].coords.imageMap = NULL;
 
     // RAW_IMAGE_NAME_LEN > DVO_IMAGE_NAME_LEN
@@ -363,5 +366,6 @@
 
   for (i = 0; i < Nvalues; i++) {
-    memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
+    // this is only save because the initial 120 bytes in Coords match CoordsDisk
+    memcpy (&out[i].coords, &in[i].coords, sizeof(CoordsDisk));
 
     // RAW_IMAGE_NAME_LEN > DVO_IMAGE_NAME_LEN
Index: /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert_PS1_V5.c
===================================================================
--- /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert_PS1_V5.c	(revision 37376)
+++ /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert_PS1_V5.c	(revision 37377)
@@ -676,5 +676,8 @@
 
   for (i = 0; i < Nvalues; i++) {
-    memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
+    // this is only safe because the initial 120 bytes in Coords match CoordsDisk
+    memcpy (&out[i].coords, &in[i].coords, sizeof(CoordsDisk));
+    out[i].coords.mosaic   = NULL;
+    out[i].coords.imageMap = NULL;
 
     // RAW_IMAGE_NAME_LEN == DVO_IMAGE_NAME_LEN
@@ -741,5 +744,6 @@
 
   for (i = 0; i < Nvalues; i++) {
-    memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
+    // this is only save because the initial 120 bytes in Coords match CoordsDisk
+    memcpy (&out[i].coords, &in[i].coords, sizeof(CoordsDisk));
 
     // RAW_IMAGE_NAME_LEN == DVO_IMAGE_NAME_LEN
Index: /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert_elixir.c
===================================================================
--- /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert_elixir.c	(revision 37376)
+++ /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert_elixir.c	(revision 37377)
@@ -210,5 +210,8 @@
 
   for (i = 0; i < Nvalues; i++) {
-    memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
+    // this is only safe because the initial 120 bytes in Coords match CoordsDisk
+    memcpy (&out[i].coords, &in[i].coords, sizeof(CoordsDisk));
+    out[i].coords.mosaic   = NULL;
+    out[i].coords.imageMap = NULL;
 
     // RAW_IMAGE_NAME_LEN < DVO_IMAGE_NAME_LEN
@@ -280,5 +283,6 @@
 
   for (i = 0; i < Nvalues; i++) {
-    memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
+    // this is only safe because the initial 120 bytes in Coords match CoordsDisk
+    memcpy (&out[i].coords, &in[i].coords, sizeof(CoordsDisk));
 
     // RAW_IMAGE_NAME_LEN < DVO_IMAGE_NAME_LEN
Index: /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert_loneos.c
===================================================================
--- /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert_loneos.c	(revision 37376)
+++ /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert_loneos.c	(revision 37377)
@@ -188,5 +188,8 @@
 
   for (i = 0; i < Nvalues; i++) {
-    memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
+    // this is only safe because the initial 120 bytes in Coords match CoordsDisk
+    memcpy (&out[i].coords, &in[i].coords, sizeof(CoordsDisk));
+    out[i].coords.mosaic   = NULL;
+    out[i].coords.imageMap = NULL;
 
     // RAW_IMAGE_NAME_LEN < DVO_IMAGE_NAME_LEN
@@ -259,5 +262,6 @@
 
   for (i = 0; i < Nvalues; i++) {
-    memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
+    // this is only safe because the initial 120 bytes in Coords match CoordsDisk
+    memcpy (&out[i].coords, &in[i].coords, sizeof(CoordsDisk));
 
     // RAW_IMAGE_NAME_LEN < DVO_IMAGE_NAME_LEN
Index: /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert_panstarrs_DEV_0.c
===================================================================
--- /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert_panstarrs_DEV_0.c	(revision 37376)
+++ /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert_panstarrs_DEV_0.c	(revision 37377)
@@ -227,5 +227,8 @@
 
   for (i = 0; i < Nvalues; i++) {
-    memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
+    // this is only safe because the initial 120 bytes in Coords match CoordsDisk
+    memcpy (&out[i].coords, &in[i].coords, sizeof(CoordsDisk));
+    out[i].coords.mosaic   = NULL;
+    out[i].coords.imageMap = NULL;
 
     // RAW_IMAGE_NAME_LEN < DVO_IMAGE_NAME_LEN
@@ -297,5 +300,6 @@
 
   for (i = 0; i < Nvalues; i++) {
-    memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
+    // this is only safe because the initial 120 bytes in Coords match CoordsDisk
+    memcpy (&out[i].coords, &in[i].coords, sizeof(CoordsDisk));
 
     // RAW_IMAGE_NAME_LEN < DVO_IMAGE_NAME_LEN
Index: /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert_panstarrs_DEV_1.c
===================================================================
--- /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert_panstarrs_DEV_1.c	(revision 37376)
+++ /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_convert_panstarrs_DEV_1.c	(revision 37377)
@@ -227,5 +227,8 @@
 
   for (i = 0; i < Nvalues; i++) {
-    memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
+    // this is only safe because the initial 120 bytes in Coords match CoordsDisk
+    memcpy (&out[i].coords, &in[i].coords, sizeof(CoordsDisk));
+    out[i].coords.mosaic   = NULL;
+    out[i].coords.imageMap = NULL;
 
     // RAW_IMAGE_NAME_LEN < DVO_IMAGE_NAME_LEN
@@ -297,5 +300,6 @@
 
   for (i = 0; i < Nvalues; i++) {
-    memcpy (&out[i].coords, &in[i].coords, sizeof(Coords));
+    // this is only safe because the initial 120 bytes in Coords match CoordsDisk
+    memcpy (&out[i].coords, &in[i].coords, sizeof(CoordsDisk));
 
     // RAW_IMAGE_NAME_LEN < DVO_IMAGE_NAME_LEN
Index: /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_image.c
===================================================================
--- /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_image.c	(revision 37376)
+++ /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_image.c	(revision 37377)
@@ -200,5 +200,5 @@
 
   gfits_create_matrix (&db[0].header, &db[0].matrix);
-  gfits_table_set_Image (&db[0].ftable, NULL, 0);
+  gfits_table_set_Image (&db[0].ftable);
 
   gfits_modify (&db[0].header, "NIMAGES", "%d", 1, 0);
@@ -207,5 +207,5 @@
   dvo_image_createID (&db[0].header);
 
-  if (db[0].format == DVO_FORMAT_INTERNAL)  	  gfits_modify (&db[0].header, "FORMAT", "%s", 1, "INTERNAL");
+  // if (db[0].format == DVO_FORMAT_INTERNAL)  	  gfits_modify (&db[0].header, "FORMAT", "%s", 1, "INTERNAL");
   if (db[0].format == DVO_FORMAT_LONEOS)    	  gfits_modify (&db[0].header, "FORMAT", "%s", 1, "LONEOS");
   if (db[0].format == DVO_FORMAT_ELIXIR)    	  gfits_modify (&db[0].header, "FORMAT", "%s", 1, "ELIXIR");
@@ -267,2 +267,112 @@
 }
 
+int gfits_table_set_Image (FTable *ftable) {
+
+  Header *header;
+
+  header = ftable[0].header;
+
+  gfits_table_mkheader_Image (header);
+  
+  /* create table */
+  if (!gfits_create_table (header, ftable)) return (FALSE);
+
+  return (TRUE);
+}
+
+int gfits_table_mkheader_Image (Header *header) {
+
+  /* create table header */
+  if (!gfits_create_table_header (header, "BINTABLE", "DVO_IMAGE")) return (FALSE);
+
+  /* define table layout */
+  /** TABLE DEFINITION **/
+  gfits_define_bintable_column (header, "D",    "CRVAL1",           "coordinate at reference pixel",   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "D",    "CRVAL2",           "coordinate at reference pixel",   "",                  1.0, 0.0);
+# if (0)
+  gfits_define_bintable_column (header, "E",    "CRPIX1",           "coordinate of reference pixel",   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "CRPIX2",           "coordinate of reference pixel",   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "CDELT1",           "degrees per pixel",               "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "CDELT2",           "degrees per pixel",               "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PC1_1",            "rotation matrix",                 "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PC1_2",            "rotation matrix",                 "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PC2_1",            "rotation matrix",                 "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "PC2_2",            "rotation matrix",                 "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "14E",  "POLYTERMS",        "higher order warping terms",      "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "15A",  "CTYPE",            "coordinate type",                 "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "A",    "NPOLYTERMS",       "order of polynomial",             "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "8B",   "MOSAIC",           "pointer to parent mosaic",        "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "8B",   "IMAGE_MAP",        "pointer to image map",            "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "J",    "TZERO",            "readout time (row 0)",            "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "J",    "NSTAR",            "number of stars on image",        "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "SECZ",             "airmass",                         "mag",               1.0, 0.0);
+  gfits_define_bintable_column (header, "I",    "NX",               "image width",                     "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "I",    "NY",               "image height",                    "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "APMIFIT",          "aperture correction",             "mag",               1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "DAPMIFIT",         "apmifit error",                   "mag",               1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MCAL",             "calibration mag",                 "mag",               1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "DMCAL",            "error on Mcal",                   "mag",               1.0, 0.0);
+  gfits_define_bintable_column (header, "I",    "XM",               "image chisq",                     "10*log(value)",     1.0, 0.0);
+  gfits_define_bintable_column (header, "I",    "PHOTCODE",         "identifier for CCD,",             "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "EXPTIME",          "exposure time",                   "seconds",           1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "ST",               "sidereal time of exposure",       "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "LAT",              "observatory latitude",            "degrees",           1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "RA_CENTER",        "image center",                    "degrees",           1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "DEC_CENTER",       "image center",                    "degrees",           1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "RADIUS",           "image radius",                    "degrees",           1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "REF_COLOR_BLUE",   "median astrometry ref color",     "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "REF_COLOR_RED",    "median astrometry ref color",     "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "117A", "NAME",             "name of original image ",         "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "B",    "DETECTION_LIMIT",  "detection limit",                 "10*mag",            1.0, 0.0);
+  gfits_define_bintable_column (header, "B",    "SATURATION_LIMIT", "saturation limit",                "10*mag",            1.0, 0.0);
+  gfits_define_bintable_column (header, "B",    "CERROR",           "astrometric error",               "50*arcsec",         1.0, 0.0);
+  gfits_define_bintable_column (header, "B",    "FWHM_X",           "PSF x width",                     "25*arcsec",         1.0, 0.0);
+  gfits_define_bintable_column (header, "B",    "FWHM_Y",           "PSF y width",                     "25*arcsec",         1.0, 0.0);
+  gfits_define_bintable_column (header, "B",    "TRATE",            "scan rate",                       "100 usec/pixel",    1.0, 0.0);
+  gfits_define_bintable_column (header, "B",    "CCDNUM",           "CCD ID number",                   "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "J",    "FLAGS",            "image quality flags",             "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "J",    "IMAGE_ID",         "internal image ID",               "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "J",    "PARENT_ID",        "associated ref image",            "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "J",    "EXTERN_ID",        "external image ID",               "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "I",    "SOURCE_ID",        "analysis source ID",              "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "I",    "NLINK_ASTROM",     "mean number of matched measurements for astrometry", "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "I",    "NLINK_PHOTOM",     "mean number of matched measurements for astrometry", "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "I",    "UBERCAL_DIST",     "distance to nearest ubercal image", "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "XPIX_SYS_ERR",     "systematic astrometry error in X", "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "YPIX_SYS_ERR",     "systematic astrometry error in Y", "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "E",    "MAG_SYS_ERR",      "systematic photometry error",     "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "I",    "N_FIT_ASTROM",     "number of stars used for astrometry cal", "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "I",    "N_FIT_PHOTOM",     "number of stars used for photometry cal", "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "J",    "PHOTOM_MAP_ID",    "reference to 2D zero point map",  "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "J",    "ASTROM_MAP_ID",    "reference to 2D astrometry map",  "",                  1.0, 0.0);
+  gfits_define_bintable_column (header, "8B",   "PARENT",           "pointer to parent mosaic (not save to disk)", "",                  1.0, 0.0);
+# endif
+
+  return (TRUE);
+}
+
+/* return internal structure representation */
+Image *gfits_table_get_Image (FTable *ftable, off_t *Ndata, char *swapped) {
+
+  int Ncols;
+  Image *data;
+
+  Ncols = ftable[0].header[0].Naxis[0];
+  if (Ncols != 384) {
+    fprintf (stderr, "ERROR: mis-match in table size: width is %d but should be %d bytes\n", Ncols, 384);
+    return NULL;
+  }
+
+  *Ndata = ftable[0].header[0].Naxis[1];
+  data = (Image *) ftable[0].buffer;
+
+  if (!swapped) {
+    myAbort ("invalid to call this without suppying 'swapped'");
+  }
+  if (*swapped == FALSE) {
+    myAbort ("invalid for table to be swapped");
+  }
+    
+  return (data);
+}
+
Index: /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_util.c
===================================================================
--- /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_util.c	(revision 37376)
+++ /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/dvo_util.c	(revision 37377)
@@ -145,10 +145,5 @@
         if ((image->externID == externID) && (image->sourceID == sourceID)) {
             BuildChipMatch(dvoConfig->images, dvoConfig->nImages);
-            if (FindMosaicForImage(dvoConfig->images, dvoConfig->nImages, i)) {
-                return image;
-            } else {
-                fprintf(stderr, "FindMosaicForImage failed\n");
-                return NULL;
-            }
+	    return image;
         }
     }
Index: /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/mosaic_astrom.c
===================================================================
--- /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/mosaic_astrom.c	(revision 37376)
+++ /branches/eam_branches/ipp-20140904/Ohana/src/libdvo/src/mosaic_astrom.c	(revision 37377)
@@ -1,6 +1,11 @@
 # include <dvo.h>
+
+//  the block of code below was used to define the chip->mosaic relationship before this
+//  was assigned to the coords value
 
 off_t getDISentry (e_time start, e_time stop, e_time *startMos, off_t *indexMos, off_t Nmosaic);
 void SortDISindex (e_time *S, off_t *I, off_t N);
+
+# if (0)
 
 /* chip-match table: j = ChipMatch[i], images[j] is DIS for images[i] WRP */
@@ -93,5 +98,6 @@
 }
 
-int BuildChipMatch_old (Image *images, off_t Nimages) {
+// this is a very old version of BuildChipMatch which does not use bisection
+int BuildChipMatch_nosort (Image *images, off_t Nimages) {
 
   off_t i, j, NDIS;
@@ -140,5 +146,6 @@
 }
 
-int BuildChipMatch (Image *images, off_t Nimages) {
+// this is an old version of BuildChipMatch which stores the results here in a local static variable
+int BuildChipMatch_static (Image *images, off_t Nimages) {
 
   off_t i, j, NDIS;
@@ -198,8 +205,59 @@
   return (TRUE);
 }
-
+# endif
+
+int BuildChipMatch (Image *images, off_t Nimages) {
+
+  off_t i, j, NDIS;
+
+  off_t  Ndis = 0;
+  off_t  *DISentry = NULL;
+  e_time *DIStzero = NULL;
+
+  if (DISentry != NULL) free (DISentry);
+  if (DIStzero != NULL) free (DIStzero);
+
+  // allocate containers for DIS indexing
+  Ndis = 0;
+  NDIS = 100;
+  ALLOCATE (DISentry, off_t, NDIS);
+  ALLOCATE (DIStzero, e_time, NDIS);
+
+  // find all DIS images, save tzero (& photcode?) 
+  for (i = 0; i < Nimages; i++) {
+    if (strcmp(&images[i].coords.ctype[4], "-DIS")) continue;
+    DISentry[Ndis] = i;
+    DIStzero[Ndis] = images[i].tzero;
+    Ndis ++;
+    if (Ndis >= NDIS) {
+      NDIS += 100;
+      REALLOCATE (DISentry, off_t, NDIS);
+      REALLOCATE (DIStzero, e_time, NDIS);
+    }
+  }
+
+  // sort the index, start, and stop by the start times:
+  SortDISindex (DIStzero, DISentry, Ndis);
+
+  /* find all matched WRP images */
+  for (i = 0; i < Nimages; i++) {
+    images[i].parent        = NULL; // reset to NULL
+    images[i].coords.mosaic = NULL; // reset to NULL
+    if (strcmp(&images[i].coords.ctype[4], "-WRP")) continue; // only define link for WRP coords
+
+    j = getDISentry (images[i].tzero, images[i].tzero + (int) images[i].exptime, DIStzero, DISentry, Ndis);
+    if (j == -1) {
+      fprintf (stderr, "WARNING: can't find matching mosaic \n");
+      continue;
+    }
+    if (j >= Nimages) myAbort("invalid DIS entry");
+    images[i].parent = &images[j];
+    images[i].coords.mosaic = &images[j].coords;
+  }
+  return (TRUE);
+}
+
+// use bisection to find the overlapping mosaic
 off_t getDISentry (e_time start, e_time stop, e_time *startMos, off_t *indexMos, off_t Nmosaic) {
-
-  // use bisection to find the overlapping mosaic
 
   off_t Nlo, Nhi, N;
