Index: /trunk/ppStack/src/ppStackArguments.c
===================================================================
--- /trunk/ppStack/src/ppStackArguments.c	(revision 19171)
+++ /trunk/ppStack/src/ppStackArguments.c	(revision 19172)
@@ -145,6 +145,7 @@
     psMetadataAddF32(arguments, PS_LIST_TAIL, "-combine-rej", 0,
                      "Combination rejection thresold (sigma)", NAN);
-    psMetadataAddU8(arguments,  PS_LIST_TAIL, "-mask-bad", 0, "Mask value for bad pixels", 0);
-    psMetadataAddU8(arguments,  PS_LIST_TAIL, "-mask-blank", 0, "Mask value for blank region", 0);
+    psMetadataAddStr(arguments,  PS_LIST_TAIL, "-mask-val", 0, "Mask value of input bad pixels", NULL);
+    psMetadataAddStr(arguments,  PS_LIST_TAIL, "-mask-bad", 0, "Mask value to give bad pixels", NULL);
+    psMetadataAddStr(arguments,  PS_LIST_TAIL, "-mask-poor", 0, "Mask value to give poor pixels", NULL);
     psMetadataAddF32(arguments, PS_LIST_TAIL, "-threshold-mask", 0, "Threshold for mask deconvolution", NAN);
     psMetadataAddF32(arguments, PS_LIST_TAIL, "-image-rej", 0,
@@ -219,9 +220,11 @@
     VALUE_ARG_RECIPE_INT("-iter",             "ITER",           S32, 0);
     VALUE_ARG_RECIPE_FLOAT("-combine-rej",    "COMBINE.REJ",    F32);
-    VALUE_ARG_RECIPE_MASK("-mask-bad",        "MASK.BAD");
-    VALUE_ARG_RECIPE_MASK("-mask-blank",      "MASK.BLANK");
     VALUE_ARG_RECIPE_FLOAT("-threshold-mask", "THRESHOLD.MASK", F32);
     VALUE_ARG_RECIPE_FLOAT("-image-rej",      "IMAGE.REJ",      F32);
     VALUE_ARG_RECIPE_INT("-rows",             "ROWS",           S32, 0);
+
+    valueArgRecipeStr(arguments, recipe, "-mask-val",  "MASK.VAL",  recipe);
+    valueArgRecipeStr(arguments, recipe, "-mask-bad",  "MASK.BAD",  recipe);
+    valueArgRecipeStr(arguments, recipe, "-mask-poor", "MASK.POOR", recipe);
 
     VALUE_ARG_RECIPE_FLOAT("-source-radius", "SOURCE.RADIUS", F32);
Index: /trunk/ppStack/src/ppStackLoop.c
===================================================================
--- /trunk/ppStack/src/ppStackLoop.c	(revision 19171)
+++ /trunk/ppStack/src/ppStackLoop.c	(revision 19172)
@@ -803,5 +803,8 @@
         if (stats) {
             psTrace("ppStack", 1, "Gathering statistics on stacked image....\n");
-            ppStatsFPA(stats, outCell->parent->parent, view, pmConfigMaskGet("BLANK", config), config);
+            psString maskBadStr = psMetadataLookupStr(NULL, recipe, "MASK.BAD"); // Name of bits for bad
+            psMaskType maskBad = pmConfigMaskGet(maskBadStr, config); // Bits to mask for bad pixels
+
+            ppStatsFPA(stats, outCell->parent->parent, view, maskBad, config);
         }
 
Index: /trunk/ppStack/src/ppStackMatch.c
===================================================================
--- /trunk/ppStack/src/ppStackMatch.c	(revision 19171)
+++ /trunk/ppStack/src/ppStackMatch.c	(revision 19172)
@@ -34,6 +34,10 @@
     int size = psMetadataLookupS32(NULL, ppsub, "KERNEL.SIZE"); // Kernel half-size
 
-    psMaskType maskIn = pmConfigMaskGet("MASK.VALUE", config); // Bits to mask going in to pmSubtractionMatch
-    psMaskType maskOut = pmConfigMaskGet("BLANK", config); // Bits to mask after pmSubtractionMatch
+    psString maskValStr = psMetadataLookupStr(NULL, recipe, "MASK.VAL"); // Name of bits to mask going in
+    psMaskType maskVal = pmConfigMaskGet(maskValStr, config); // Bits to mask going in to pmSubtractionMatch
+    psString maskPoorStr = psMetadataLookupStr(NULL, recipe, "MASK.POOR"); // Name of bits to mask for poor
+    psMaskType maskPoor = pmConfigMaskGet(maskPoorStr, config); // Bits to mask for poor pixels
+    psString maskBadStr = psMetadataLookupStr(NULL, recipe, "MASK.BAD"); // Name of bits to mask for bad
+    psMaskType maskBad = pmConfigMaskGet(maskBadStr, config); // Bits to mask for bad pixels
 
     bool mdok;                          // Status of MD lookup
@@ -45,5 +49,5 @@
     int threads = psMetadataLookupS32(NULL, config->arguments, "-threads"); // Number of threads
 
-    if (!pmReadoutMaskNonfinite(readout, maskIn)) {
+    if (!pmReadoutMaskNonfinite(readout, maskVal)) {
         psError(PS_ERR_UNKNOWN, false, "Unable to mask non-finite pixels in readout.");
         return false;
@@ -75,4 +79,5 @@
         float optThresh = psMetadataLookupF32(&mdok, ppsub, "OPTIMUM.TOL"); // Tolerance for search
         int optOrder = psMetadataLookupS32(&mdok, ppsub, "OPTIMUM.ORDER"); // Order for search
+        float poorFrac = psMetadataLookupF32(&mdok, ppsub, "POOR.FRACTION"); // Fraction for "poor"
 
         // These values are specified specifically for stacking
@@ -87,5 +92,5 @@
         {
             psStats *bg = psStatsAlloc(PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV); // Statistics for bg
-            if (!psImageBackground(bg, NULL, readout->image, readout->mask, maskIn, rng)) {
+            if (!psImageBackground(bg, NULL, readout->image, readout->mask, maskVal, rng)) {
                 psWarning("Can't measure background for image.");
                 psErrorClear();
@@ -136,5 +141,5 @@
                                 sources, stampsName, type, size, order, widths, orders, inner, ringsOrder,
                                 binning, penalty, optimum, optWidths, optOrder, optThresh, iter, rej,
-                                maskIn, maskOut, badFrac, PM_SUBTRACTION_MODE_1)) {
+                                maskVal, maskBad, maskPoor, poorFrac, badFrac, PM_SUBTRACTION_MODE_1)) {
             psError(PS_ERR_UNKNOWN, false, "Unable to match images.");
             psFree(fake);
@@ -226,5 +231,5 @@
     if (renorm) {
         psLogMsg("ppStack", PS_LOG_INFO, "Renormalising variance map.");
-        if (!pmReadoutWeightRenorm(readout, maskOut, renormMean, renormStdev, renormWidth, rng)) {
+        if (!pmReadoutWeightRenorm(readout, maskBad, renormMean, renormStdev, renormWidth, rng)) {
             psError(PS_ERR_UNKNOWN, false, "Unable to renormalise variances.");
             psFree(output);
@@ -235,5 +240,5 @@
     // Ensure the background value is zero
     psStats *bg = psStatsAlloc(PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV); // Statistics for background
-    if (!psImageBackground(bg, NULL, readout->image, readout->mask, maskOut, rng)) {
+    if (!psImageBackground(bg, NULL, readout->image, readout->mask, maskVal | maskBad, rng)) {
         psWarning("Can't measure background for image.");
         psErrorClear();
Index: /trunk/ppStack/src/ppStackReadout.c
===================================================================
--- /trunk/ppStack/src/ppStackReadout.c	(revision 19171)
+++ /trunk/ppStack/src/ppStackReadout.c	(revision 19172)
@@ -10,7 +10,7 @@
 #include "ppStack.h"
 
-//#define REJECTION_FILES                 // Write rejection mask?
-//#define INSPECTION_FILES                // Write inspection mask?
-//#define COMBINED_FILES                  // Write combined images?
+#define REJECTION_FILES                 // Write rejection mask?
+#define INSPECTION_FILES                // Write inspection mask?
+#define COMBINED_FILES                  // Write combined images?
 
 
@@ -34,5 +34,4 @@
     int iter = psMetadataLookupS32(NULL, recipe, "ITER"); // Rejection iterations
     float combineRej = psMetadataLookupF32(NULL, recipe, "COMBINE.REJ"); // Combination threshold
-    psMaskType maskVal = pmConfigMaskGet("BLANK", config); // Value to mask
     bool useVariance = psMetadataLookupBool(&mdok, recipe, "VARIANCE"); // Use variance for rejection?
     bool safe = psMetadataLookupBool(&mdok, recipe, "SAFE"); // Be safe when combining small numbers of pixels
@@ -40,4 +39,9 @@
     psMetadata *ppsub = psMetadataLookupMetadata(NULL, config->recipes, "PPSUB"); // PPSUB recipe
     int kernelSize = psMetadataLookupS32(NULL, ppsub, "KERNEL.SIZE"); // Kernel half-size
+
+    psString maskValStr = psMetadataLookupStr(NULL, recipe, "MASK.VAL"); // Name of bits to mask going in
+    psMaskType maskVal = pmConfigMaskGet(maskValStr, config); // Bits to mask going in to pmSubtractionMatch
+    psString maskBadStr = psMetadataLookupStr(NULL, recipe, "MASK.BAD"); // Name of bits to mask for bad
+    psMaskType maskBad = pmConfigMaskGet(maskBadStr, config); // Bits to mask for bad pixels
 
     int num = readouts->n;              // Number of inputs
@@ -67,5 +71,5 @@
     }
 
-    if (!pmStackCombine(outRO, stack, maskVal, maskVal, kernelSize, iter, combineRej, true,
+    if (!pmStackCombine(outRO, stack, maskVal | maskBad, maskBad, kernelSize, iter, combineRej, true,
                         useVariance, safe)) {
         psError(PS_ERR_UNKNOWN, false, "Unable to combine input readouts with rejection.");
@@ -93,5 +97,5 @@
                                             psRegionSet(0, outRO->image->numCols - 1,
                                                         0, outRO->image->numRows - 1),
-                                            maskVal);
+                                            maskBad);
         psString name = NULL;           // Name of image
         psStringAppend(&name, "inspect_%03d_%03d.fits", sectionNum, i);
@@ -143,6 +147,10 @@
 
     bool mdok;                          // Status of MD lookup
-    psMaskType maskVal = pmConfigMaskGet("BLANK", config); // Value to mask
     bool useVariance = psMetadataLookupBool(&mdok, recipe, "VARIANCE"); // Use variance for rejection?
+
+    psString maskValStr = psMetadataLookupStr(NULL, recipe, "MASK.VAL"); // Name of bits to mask going in
+    psMaskType maskVal = pmConfigMaskGet(maskValStr, config); // Bits to mask going in to pmSubtractionMatch
+    psString maskBadStr = psMetadataLookupStr(NULL, recipe, "MASK.BAD"); // Name of bits to mask for bad
+    psMaskType maskBad = pmConfigMaskGet(maskBadStr, config); // Bits to mask for bad pixels
 
     int num = readouts->n;              // Number of inputs
@@ -210,5 +218,5 @@
                                              psRegionSet(0, outRO->image->numCols - 1,
                                                          0, outRO->image->numRows - 1),
-                                             maskVal);
+                                             maskBad);
             psString name = NULL;           // Name of image
             psStringAppend(&name, "reject_%03d.fits", i);
@@ -222,5 +230,6 @@
 #endif
 
-    if (!pmStackCombine(outRO, stack, maskVal, maskVal, 0, 0, NAN, numGood != num, useVariance, false)) {
+    if (!pmStackCombine(outRO, stack, maskVal | maskBad, maskBad, 0, 0, NAN,
+                        numGood != num, useVariance, false)) {
         psError(PS_ERR_UNKNOWN, false, "Unable to combine input readouts.");
         psFree(fpaList);
