Index: trunk/ppStack/src/ppStackLoop.c
===================================================================
--- trunk/ppStack/src/ppStackLoop.c	(revision 18559)
+++ trunk/ppStack/src/ppStackLoop.c	(revision 18591)
@@ -204,5 +204,4 @@
 
     bool mdok;                          // Status of MD lookup
-    psMaskType maskBlank = psMetadataLookupU8(NULL, config->arguments, "MASK.BLANK"); // Mask for blank reg.
     bool tempDelete = psMetadataLookupBool(&mdok, config->arguments, "TEMP.DELETE"); // Delete temporary files?
     const char *tempImage = psMetadataLookupStr(NULL, config->arguments, "TEMP.IMAGE"); // Suffix for temporary images
@@ -242,4 +241,9 @@
     psMetadata *ppsub = psMetadataLookupMetadata(NULL, config->recipes, "PPSUB"); // PPSUB recipe
     int overlap = 2 * psMetadataLookupS32(NULL, ppsub, "KERNEL.SIZE"); // Overlap by kernel size between consecutive scans
+
+    if (!pmConfigMaskSetBits(NULL, NULL, config)) {
+        psError(PS_ERR_UNKNOWN, false, "Unable to determine mask value.");
+        return false;
+    }
 
     memDump("start");
@@ -790,5 +794,5 @@
         if (stats) {
             psTrace("ppStack", 1, "Gathering statistics on stacked image....\n");
-            ppStatsFPA(stats, outCell->parent->parent, view, maskBlank, config);
+            ppStatsFPA(stats, outCell->parent->parent, view, pmConfigMaskGet("BLANK", config), config);
         }
 
Index: trunk/ppStack/src/ppStackMatch.c
===================================================================
--- trunk/ppStack/src/ppStackMatch.c	(revision 18559)
+++ trunk/ppStack/src/ppStackMatch.c	(revision 18591)
@@ -30,5 +30,8 @@
     psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, "PPSUB"); // PPSUB recipe
     int size = psMetadataLookupS32(NULL, recipe, "KERNEL.SIZE"); // Kernel half-size
-    psMaskType maskBad = pmConfigMaskGet(psMetadataLookupStr(NULL, recipe, "MASK.BAD"), config); // Value to mask
+
+    psMaskType maskIn = pmConfigMaskGet("MASK.VALUE", config); // Bits to mask going in to pmSubtractionMatch
+    psMaskType maskOut = pmConfigMaskGet("BLANK", config); // Bits to mask after pmSubtractionMatch
+
     bool mdok;                          // Status of MD lookup
     bool renorm = psMetadataLookupBool(&mdok, config->arguments, "RENORM"); // Renormalise variances?
@@ -41,5 +44,5 @@
     float penalty = psMetadataLookupF32(NULL, config->arguments, "PENALTY"); // Penalty for wideness
 
-    if (!pmReadoutMaskNonfinite(readout, maskBad)) {
+    if (!pmReadoutMaskNonfinite(readout, maskIn)) {
         psError(PS_ERR_UNKNOWN, false, "Unable to mask non-finite pixels in readout.");
         return false;
@@ -64,6 +67,4 @@
         int ringsOrder = psMetadataLookupS32(NULL, recipe, "RINGS.ORDER"); // RINGS polynomial order
         int binning = psMetadataLookupS32(NULL, recipe, "SPAM.BINNING"); // Binning for SPAM kernel
-        psMaskType maskBlank = pmConfigMaskGet(psMetadataLookupStr(NULL, recipe, "MASK.BLANK"),
-                                            config); // Mask for blank reg.
         float badFrac = psMetadataLookupF32(NULL, recipe, "BADFRAC"); // Maximum bad fraction
         bool optimum = psMetadataLookupBool(&mdok, recipe, "OPTIMUM"); // Derive optimum parameters?
@@ -114,5 +115,5 @@
                                 sources, stampsName, type, size, order, widths, orders, inner, ringsOrder,
                                 binning, penalty, optimum, optWidths, optOrder, optThresh, iter, rej,
-                                maskBad, maskBlank, badFrac, PM_SUBTRACTION_MODE_1)) {
+                                maskIn, maskOut, badFrac, PM_SUBTRACTION_MODE_1)) {
             psError(PS_ERR_UNKNOWN, false, "Unable to match images.");
             psFree(fake);
@@ -200,5 +201,5 @@
     if (renorm) {
         psLogMsg("ppStack", PS_LOG_INFO, "Renormalising variance map.");
-        if (!pmReadoutWeightRenorm(readout, maskBad, renormMean, renormStdev, renormWidth, rng)) {
+        if (!pmReadoutWeightRenorm(readout, maskOut, renormMean, renormStdev, renormWidth, rng)) {
             psError(PS_ERR_UNKNOWN, false, "Unable to renormalise variances.");
             psFree(output);
@@ -209,5 +210,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, maskBad, rng)) {
+    if (!psImageBackground(bg, NULL, readout->image, readout->mask, maskOut, rng)) {
         psWarning("Can't measure background for image.");
         psErrorClear();
Index: trunk/ppStack/src/ppStackReadout.c
===================================================================
--- trunk/ppStack/src/ppStackReadout.c	(revision 18559)
+++ trunk/ppStack/src/ppStackReadout.c	(revision 18591)
@@ -32,7 +32,5 @@
     int iter = psMetadataLookupS32(NULL, config->arguments, "ITER"); // Rejection iterations
     float combineRej = psMetadataLookupF32(NULL, config->arguments, "COMBINE.REJ"); // Combination threshold
-    psMaskType maskBad = psMetadataLookupU8(NULL, config->arguments, "MASK.BAD"); // Value to mask
-    psMaskType maskBlank = psMetadataLookupU8(NULL, config->arguments, "MASK.BLANK"); // Mask for blank reg.
-//    float threshold = psMetadataLookupF32(NULL, config->arguments, "THRESHOLD.MASK"); // Threshold for mask deconvolution
+    psMaskType maskVal = pmConfigMaskGet("BLANK", config); // Value to mask
     bool useVariance = psMetadataLookupBool(&mdok, config->arguments, "VARIANCE"); // Use variance for rejection?
     bool safe = psMetadataLookupBool(&mdok, config->arguments, "SAFE"); // Play safe when combining small numbers of pixels?
@@ -67,5 +65,5 @@
     }
 
-    if (!pmStackCombine(outRO, stack, maskBad, maskBlank, kernelSize, iter, combineRej, true,
+    if (!pmStackCombine(outRO, stack, maskVal, maskVal, kernelSize, iter, combineRej, true,
                         useVariance, safe)) {
         psError(PS_ERR_UNKNOWN, false, "Unable to combine input readouts with rejection.");
@@ -93,5 +91,5 @@
                                             psRegionSet(0, outRO->image->numCols - 1,
                                                         0, outRO->image->numRows - 1),
-                                            maskBlank);
+                                            maskVal);
         psString name = NULL;           // Name of image
         psStringAppend(&name, "inspect_%03d_%03d.fits", sectionNum, i);
@@ -140,6 +138,5 @@
     // Get the recipe values
     bool mdok;                          // Status of MD lookup
-    psMaskType maskBad = psMetadataLookupU8(NULL, config->arguments, "MASK.BAD"); // Value to mask
-    psMaskType maskBlank = psMetadataLookupU8(NULL, config->arguments, "MASK.BLANK"); // Mask for blank reg.
+    psMaskType maskVal = pmConfigMaskGet("BLANK", config); // Value to mask
     bool useVariance = psMetadataLookupBool(&mdok, config->arguments, "VARIANCE"); // Use variance for rejection?
 
@@ -208,5 +205,5 @@
                                              psRegionSet(0, outRO->image->numCols - 1,
                                                          0, outRO->image->numRows - 1),
-                                             maskBlank);
+                                             maskVal);
             psString name = NULL;           // Name of image
             psStringAppend(&name, "reject_%03d.fits", i);
@@ -220,5 +217,5 @@
 #endif
 
-    if (!pmStackCombine(outRO, stack, maskBad, maskBlank, 0, 0, NAN, numGood != num, useVariance, false)) {
+    if (!pmStackCombine(outRO, stack, maskVal, maskVal, 0, 0, NAN, numGood != num, useVariance, false)) {
         psError(PS_ERR_UNKNOWN, false, "Unable to combine input readouts.");
         psFree(fpaList);
