Index: trunk/ppImage/src/ppImage.h
===================================================================
--- trunk/ppImage/src/ppImage.h	(revision 23535)
+++ trunk/ppImage/src/ppImage.h	(revision 23688)
@@ -40,5 +40,5 @@
     bool doAstromMosaic;                // full-mosaic Astrometry
     bool doStats;                       // call ppStats on the image
-    bool checkCTE;			// measure pixel-based variance
+    bool checkCTE;                      // measure pixel-based variance
 
     // output files requested
@@ -88,5 +88,5 @@
     float remnanceThresh;               // Threshold for remnance detection
 
-    char *normClass;			// class to use for per-class normalization 
+    char *normClass;                    // class to use for per-class normalization
 } ppImageOptions;
 
@@ -146,7 +146,7 @@
 bool ppImageRebinChip (pmConfig *config, pmFPAview *view, ppImageOptions *options, char *outName);
 
-bool ppImagePhotom (pmConfig *config, pmFPAview *view);
-bool ppImageAstrom (pmConfig *config);
-bool ppImageAddstar (pmConfig *config);
+bool ppImagePhotom(psMetadata *stats, pmConfig *config, pmFPAview *view);
+bool ppImageAstrom(pmConfig *config, psMetadata *stats);
+bool ppImageAddstar(pmConfig *config);
 
 // Subtract background from the chip-mosaicked image
Index: trunk/ppImage/src/ppImageAstrom.c
===================================================================
--- trunk/ppImage/src/ppImageAstrom.c	(revision 23535)
+++ trunk/ppImage/src/ppImageAstrom.c	(revision 23688)
@@ -7,5 +7,5 @@
 // this function is mostly equivalent to the top-level of psastro, with some
 // modifications since the data has already been loaded.
-bool ppImageAstrom (pmConfig *config) {
+bool ppImageAstrom (pmConfig *config, psMetadata *stats) {
 
     bool status;
@@ -27,5 +27,5 @@
     }
 
-    if (!psastroAnalysis (config)) {
+    if (!psastroAnalysis(config, stats)) {
         psError (PSASTRO_ERR_UNKNOWN, false, "failure in psastro analysis\n");
         return false;
Index: trunk/ppImage/src/ppImageLoop.c
===================================================================
--- trunk/ppImage/src/ppImageLoop.c	(revision 23535)
+++ trunk/ppImage/src/ppImageLoop.c	(revision 23688)
@@ -13,7 +13,12 @@
 bool ppImageLoop(pmConfig *config, ppImageOptions *options)
 {
-    psMetadata *stats = options->doStats ? psMetadataAlloc() : NULL; // Statistics to output
+    psMetadata *stats = NULL;           // Statistics to output
     float timeDetrend = 0;              // Amount of time spent in detrend
     float timePhot = 0;                 // Amount of time spent in photometry
+
+    if (options->doStats) {
+        stats = psMetadataAlloc();
+        psMetadataAddS32(stats, PS_LIST_TAIL, "QUALITY", 0, "No problems", 0);
+    }
 
     bool status;                        // Status of MD lookup
@@ -139,5 +144,5 @@
         psTimerStart(TIMER_PHOT);
         if (options->doPhotom) {
-            if (!ppImagePhotom(config, view)) {
+            if (!ppImagePhotom(stats, config, view)) {
                 ESCAPE("error running photometry.");
             }
@@ -200,5 +205,5 @@
     // this also performs the psastro file IO
     if (options->doAstromChip || options->doAstromMosaic) {
-        if (!ppImageAstrom(config)) {
+        if (!ppImageAstrom(config, stats)) {
             ESCAPE("error running astrometry.");
         }
Index: trunk/ppImage/src/ppImagePhotom.c
===================================================================
--- trunk/ppImage/src/ppImagePhotom.c	(revision 23535)
+++ trunk/ppImage/src/ppImagePhotom.c	(revision 23688)
@@ -6,5 +6,5 @@
 
 // In this function, we perform the psphot analysis routine for the chip-mosaicked images
-bool ppImagePhotom (pmConfig *config, pmFPAview *view) {
+bool ppImagePhotom(psMetadata *stats, pmConfig *config, pmFPAview *view) {
 
     bool status;
@@ -12,5 +12,5 @@
     pmReadout *readout;
 
-    psphotInit ();
+    psphotInit();
 
     // find or define a pmFPAfile PSPHOT.INPUT
@@ -37,14 +37,22 @@
             // run the actual photometry analysis
             if (!psphotReadout (config, view)) {
-                psError(psErrorCodeLast(), false, "failure in psphotReadout for chip %d, cell %d, readout %d\n", view->chip, view->cell, view->readout);
-                return false;
+                // This is likely a data quality issue
+                // XXX Split into multiple cases using error codes?
+                psErrorStackPrint(stderr, "Unable to perform photometry on image");
+                psWarning("Unable to perform photometry on image --- suspect bad data quality.");
+                if (stats && psMetadataLookupS32(NULL, stats, "QUALITY") == 0) {
+                    psMetadataAddS32(stats, PS_LIST_TAIL, "QUALITY", PS_META_REPLACE,
+                                     "Unable to perform photometry on image", psErrorCodeLast());
+                }
+                psErrorClear();
+                psphotFilesActivate(config, false);
             }
 
-	    // we want to save the MASK as modified by psphot, but not the data or weight
-	    // free the old mask and replace with a memory copy of the new mask
-	    pmReadout *oldReadout = pmFPAviewThisReadout (view, input->src);
-	    pmReadout *newReadout = pmFPAviewThisReadout (view, input->fpa);
-	    psFree (oldReadout->mask);
-	    oldReadout->mask = psMemIncrRefCounter (newReadout->mask);
+            // we want to save the MASK as modified by psphot, but not the data or weight
+            // free the old mask and replace with a memory copy of the new mask
+            pmReadout *oldReadout = pmFPAviewThisReadout(view, input->src);
+            pmReadout *newReadout = pmFPAviewThisReadout(view, input->fpa);
+            psFree (oldReadout->mask);
+            oldReadout->mask = psMemIncrRefCounter(newReadout->mask);
         }
     }
