Index: trunk/pswarp/src/Makefile.am
===================================================================
--- trunk/pswarp/src/Makefile.am	(revision 15607)
+++ trunk/pswarp/src/Makefile.am	(revision 15608)
@@ -14,7 +14,7 @@
 	pswarpMatchRange.c		\
 	pswarpParseCamera.c		\
+	pswarpPixelFraction.c		\
 	pswarpTransformReadout_Opt.c	\
 	pswarpVersion.c            
-#	pswarpTransformReadout.c
 
 noinst_HEADERS = \
Index: trunk/pswarp/src/pswarp.h
===================================================================
--- trunk/pswarp/src/pswarp.h	(revision 15607)
+++ trunk/pswarp/src/pswarp.h	(revision 15608)
@@ -55,3 +55,11 @@
 bool pswarpMapSetLocalModel (pswarpMap *map, pmReadout *dest, pmReadout *src, int ix, int iy);
 
-bool pswarpDefineSkycell (pmFPAfile **outFile, pmConfig **outConfig, pmConfig *config, const char *filename, const char *argname);
+bool pswarpDefineSkycell (pmFPAfile **outFile, pmConfig **outConfig, pmConfig *config,
+                          const char *filename, const char *argname);
+
+/// Check to see if the readout has a minimum fraction of "lit" pixels
+bool pswarpPixelFraction(const pmReadout *readout, ///< Readout to inspect
+                         psMetadata *stats, ///< Statistics to update with the result
+                         const pmConfig *config ///< Configuration
+    );
+
Index: trunk/pswarp/src/pswarpLoop.c
===================================================================
--- trunk/pswarp/src/pswarpLoop.c	(revision 15607)
+++ trunk/pswarp/src/pswarpLoop.c	(revision 15608)
@@ -215,9 +215,18 @@
     pmCell *outCell = output->parent;   // Output cell
     pmChip *outChip = outCell->parent;  // Output chip
-    pmFPA *outFPA = outChip->parent;    // Output FPA
+    pmFPA *outFPA = outChip->parent;    // Output FP
+
+    if (!pswarpPixelFraction(output, stats, config)) {
+        // Don't write output images, and don't bother about anything else
+        output->data_exists = outCell->data_exists = outChip->data_exists = false;
+        psFree(cells);
+        psFree(view);
+        goto COMPLETED;
+    }
 
     if (!pmConceptsAverageCells(outCell, cells, NULL, NULL, false)) {
         psError(PS_ERR_UNKNOWN, false, "Unable to average cell concepts.");
         psFree(stats);
+        psFree(cells);
         psFree(view);
         return false;
@@ -266,7 +275,7 @@
         view->chip = view->cell = view->readout = 0;
         if (!psphotReadout(config, view)) {
-            psError(psErrorCodeLast(), false, "Unable to determine PSF for warped image.\n");
-            psFree(view);
-            return false;
+            // Can't do anything about it; let it continue
+            psErrorStackPrint(stderr, "Unable to determine PSF for warped image.\n");
+            psErrorClear();
         }
         psFree(view);
@@ -319,4 +328,5 @@
     // Now done with the skycell side of things
 
+    COMPLETED:
     // Write out summary statistics
     if (stats) {
Index: trunk/pswarp/src/pswarpPixelFraction.c
===================================================================
--- trunk/pswarp/src/pswarpPixelFraction.c	(revision 15608)
+++ trunk/pswarp/src/pswarpPixelFraction.c	(revision 15608)
@@ -0,0 +1,59 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <pslib.h>
+#include <psmodules.h>
+
+#include "pswarp.h"
+
+bool pswarpPixelFraction(const pmReadout *readout, psMetadata *stats, const pmConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(readout, false);
+    PS_ASSERT_IMAGE_NON_NULL(readout->image, false);
+    PS_ASSERT_IMAGE_TYPE(readout->image, PS_TYPE_F32, false);
+    if (!readout->mask) {
+        // Can't do anything
+        return true;
+    }
+    PS_ASSERT_IMAGE_NON_NULL(readout->mask, false);
+    PS_ASSERT_IMAGES_SIZE_EQUAL(readout->mask, readout->image, false);
+    PS_ASSERT_IMAGE_TYPE(readout->mask, PS_TYPE_MASK, false);
+
+    if (stats) {
+        PS_ASSERT_METADATA_NON_NULL(stats, false);
+    }
+    PS_ASSERT_PTR_NON_NULL(config, false);
+    PS_ASSERT_METADATA_NON_NULL(config->arguments, false);
+
+    float minFrac = psMetadataLookupF32(NULL, config->arguments, "ACCEPT.FRAC"); // Minimum fraction
+    psMaskType maskPoor = psMetadataLookupU8(NULL, config->arguments, "MASK.POOR"); // Mask for "poor" data
+    psMaskType maskBad = psMetadataLookupU8(NULL, config->arguments, "MASK.BAD"); // Mask for bad data
+    psMaskType maskVal = maskPoor | maskBad; // Mask to apply
+
+    psImage *image = readout->image;    // Image of interest
+    psImage *mask = readout->mask;      // Mask image
+
+    int numCols = image->numCols, numRows = image->numRows; // Size of image
+    long numPix = numCols * numRows;
+
+    int numBad = 0;                     // Number of bad pixels
+    for (int y = 0; y < numRows; y++) {
+        for (int x = 0; x < numCols; x++) {
+            if (mask->data.PS_TYPE_MASK_DATA[y][x] & maskVal) {
+                numBad++;
+            }
+        }
+    }
+
+    float goodFrac = (numPix - numBad) / numPix; // Fraction of good pixels
+    bool accept = (goodFrac >= minFrac ? true : false); // Accept this readout?
+
+    if (stats) {
+        psMetadataAddBool(stats, PS_LIST_HEAD, "ACCEPT", 0, "Accept this readout?", accept);
+    }
+
+    return accept;
+}
+
