Index: trunk/psastro/src/psastroMosaicAstrom.c
===================================================================
--- trunk/psastro/src/psastroMosaicAstrom.c	(revision 10922)
+++ trunk/psastro/src/psastroMosaicAstrom.c	(revision 12492)
@@ -5,15 +5,24 @@
 bool psastroMosaicAstrom (pmConfig *config, psArray *refs) {
 
+    bool status;
+
     // select the current recipe
     psMetadata *recipe  = psMetadataLookupPtr (NULL, config->recipes, PSASTRO_RECIPE);
     if (!recipe) {
-	psError(PSASTRO_ERR_CONFIG, true, "Can't find PSASTRO recipe!\n");
+	psError(PSASTRO_ERR_CONFIG, false, "Can't find PSASTRO recipe!\n");
 	return false;
     }
+
+    // physical pixel scale in microns per pixel
+    double pixelScale = psMetadataLookupF32 (&status, recipe, "PSASTRO.PIXEL.SCALE");
+    if (!status) {
+	psError(PS_ERR_IO, false, "Failed to lookup pixel scale"); 
+	return false; 
+    } 
 
     // select the input data sources
     pmFPAfile *input = psMetadataLookupPtr (NULL, config->files, "PSASTRO.INPUT");
     if (!input) {
-	psError(PSASTRO_ERR_CONFIG, true, "Can't find input data!\n");
+	psError(PSASTRO_ERR_CONFIG, false, "Can't find input data!\n");
 	return false;
     }
@@ -27,5 +36,8 @@
     // given the existing per-chip astrometry, determine matches between raw and ref stars
     // is this needed? yes, if we didn't do SingleChip astrometry first
-    psastroMosaicSetMatch (fpa, recipe, 0);
+    if (!psastroMosaicSetMatch (fpa, recipe, 0)) {
+	psError(PSASTRO_ERR_UNKNOWN, false, "failed to match raw and ref stars for mosaic");
+	return false;
+    }
     if (psTraceGetLevel("psastro.dump") > 0) { psastroDumpMatches (fpa, "match.0.dat"); }
 
@@ -33,5 +45,8 @@
     // modify the chip->toFPA scaling to match knowledge about pixel scale,
     // then recalculate raw and ref positions
-    psastroMosaicCommonScale (fpa, recipe);
+    if (!psastroMosaicCommonScale (fpa, recipe)) {
+	psError(PSASTRO_ERR_UNKNOWN, false, "failed to set a common scale for the chips");
+	return false;
+    }
     if (psTraceGetLevel("psastro.dump") > 0) { psastroDumpMatches (fpa, "match.1.dat"); }
 
@@ -39,32 +54,73 @@
     // apply the new distortion terms up and down
     // refit the per-chip terms with linear fits only
-    psastroMosaicGradients (fpa, recipe);
+    if (!psastroMosaicGradients (fpa, recipe)) {
+	psError(PSASTRO_ERR_UNKNOWN, false, "failed to measure mosaic gradients");
+	return false;
+    }
     if (psTraceGetLevel("psastro.dump") > 0) { psastroDumpMatches (fpa, "match.2.dat"); }
 
-    psastroMosaicChipAstrom (fpa, recipe, false);
+    // measure the astrometry for the chips under the distortion term
+    if (!psastroMosaicChipAstrom (fpa, recipe, false)) {
+	psError(PSASTRO_ERR_UNKNOWN, false, "failed to measure chip astrometry in mosaic mode");
+	return false;
+    }
     if (psTraceGetLevel("psastro.dump") > 0) { psastroDumpMatches (fpa, "match.3.dat"); }
 
-    // re-perform the match with a slightly tighter circle
-    psastroMosaicSetMatch (fpa, recipe, 1);
+    // do a second pass on the distortion with improved chip positions and rotations
+    // first, re-perform the match with a slightly tighter circle
+    if (!psastroMosaicSetMatch (fpa, recipe, 1)) {
+	psError(PSASTRO_ERR_UNKNOWN, false, "failed to match raw and ref stars for mosaic (2nd pass)");
+	return false;
+    }
+    if (!psastroMosaicCommonScale (fpa, recipe)) {
+	psError(PSASTRO_ERR_UNKNOWN, false, "failed to set a common scale for the chips (2nd pass)");
+	return false;
+    }
+    if (!psastroMosaicGradients (fpa, recipe)) {
+	psError(PSASTRO_ERR_UNKNOWN, false, "failed to measure mosaic gradients (2nd pass)");
+	return false;
+    }
+    if (psTraceGetLevel("psastro.dump") > 0) { psastroDumpMatches (fpa, "match.4.dat"); }
 
-    // do a second pass on the distortion with improved chip positions and rotations
-    psastroMosaicCommonScale (fpa, recipe);
-    psastroMosaicGradients (fpa, recipe);
-    psastroMosaicChipAstrom (fpa, recipe, false);
-    psastroMosaicSetMatch (fpa, recipe, 1);
-    
+    if (!psastroMosaicChipAstrom (fpa, recipe, false)) {
+	psError(PSASTRO_ERR_UNKNOWN, false, "failed to measure chip astrometry in mosaic mode (2nd pass)");
+	return false;
+    }
+    if (psTraceGetLevel("psastro.dump") > 0) { psastroDumpMatches (fpa, "match.5.dat"); }
+
     // now fit the chips under the common distortion with higher-order terms
     // first, re-perform the match with a slightly tighter circle
-    psastroMosaicChipAstrom (fpa, recipe, true);
+    if (!psastroMosaicSetMatch (fpa, recipe, 1)) {
+	psError(PSASTRO_ERR_UNKNOWN, false, "failed to match raw and ref stars for mosaic (3rd pass)");
+	return false;
+    }
+    if (!psastroMosaicChipAstrom (fpa, recipe, true)) {
+	psError(PSASTRO_ERR_UNKNOWN, false, "failed to measure chip astrometry in mosaic mode (3rd pass)");
+	return false;
+    }
+    if (psTraceGetLevel("psastro.dump") > 0) { psastroDumpMatches (fpa, "match.6.dat"); }
 
-    // save WCS and analysis metadata in update header
+    // save WCS and analysis metadata in update header XXX this is still wrong: the pmFPAExtent
+    // function returns the FP dimensions in pixel units relative to the 0,0 corner of chip
+    // 0,0.  I need to have a function which loops over all cells, determines the pixel
+    // dimensions for each cell, converts them to chip pixels, then uses the fpa astrometry
+    // structures to get the total dimensions of the fpa in fpa units.  equivalent to
+    // pmFPAExtent
+    psRegion *region = pmFPAExtent (fpa);
+    region->x0 *= pixelScale;
+    region->x1 *= pixelScale;
+    region->y0 *= pixelScale;
+    region->y1 *= pixelScale;
+
     // XXX also need to add DATE/TIME info and NAXIS1, NAXIS2
     psMetadata *updates = psMetadataAlloc();
-    psMetadataAddS32 (updates, PS_LIST_TAIL, "NAXIS1",   PS_META_REPLACE, "fpa dimensions (um)", 30000);
-    psMetadataAddS32 (updates, PS_LIST_TAIL, "NAXIS2",   PS_META_REPLACE, "fpa dimensions (um)", 30000);
-    psMetadataAddStr (updates, PS_LIST_TAIL, "DATE-OBS", PS_META_REPLACE, "date", "2003-08-28");
-    psMetadataAddStr (updates, PS_LIST_TAIL, "UTC-OBS",  PS_META_REPLACE, "date", "7:15:46.47");
+    psMetadataAddS32 (updates, PS_LIST_TAIL, "NAXIS1",   PS_META_REPLACE, "fpa dimensions (mm)", region->x1 - region->x0);
+    psMetadataAddS32 (updates, PS_LIST_TAIL, "NAXIS2",   PS_META_REPLACE, "fpa dimensions (mm)", region->y1 - region->y0);
+    psFree (region);
     
-    pmAstromWriteBilevelMosaic (updates, fpa, NONLIN_TOL);
+    if (!pmAstromWriteBilevelMosaic (updates, fpa, NONLIN_TOL)) {
+	psAbort ("failed to save header terms");
+    }
+
     psMetadataAddMetadata (fpa->analysis, PS_LIST_TAIL, "PSASTRO.HEADER",  PS_META_REPLACE, "psastro header stats", updates);
     psFree (updates);
