Index: branches/eam_branches/ppStack.20211015/src/ppStackReadout.c
===================================================================
--- branches/eam_branches/ppStack.20211015/src/ppStackReadout.c	(revision 41841)
+++ branches/eam_branches/ppStack.20211015/src/ppStackReadout.c	(revision 41842)
@@ -68,6 +68,5 @@
     psVector *addVariance = options->matchChi2; // Additional variance when rejecting
 
-    job->results = ppStackReadoutInitial(config, outRO, thread->readouts, mask,
-                                         weightings, exposures, addVariance);
+    job->results = ppStackReadoutInitial(config, outRO, thread->readouts, mask, weightings, exposures, addVariance);
     thread->busy = false;
 
@@ -340,5 +339,7 @@
 }
 
-psArray *ppStackReadoutPercent(const pmConfig *config, pmReadout *outRO, const psArray *readouts,
+bool pmStackCombineByPercentile(pmReadout *outRO, psArray *stack, float minRange, float maxRange, psImageMaskType maskBad, psImageMaskType maskSuspect, psImageMaskType maskBlank);
+
+bool ppStackReadoutPercent(const pmConfig *config, pmReadout *outRO, const psArray *readouts,
 			       const psVector *mask, const psVector *weightings, const psVector *exposures,
 			       const psVector *addVariance)
@@ -357,30 +358,22 @@
 
     bool mdok;                          // Status of MD lookup
-    float iter = psMetadataLookupF32(NULL, recipe, "COMBINE.ITER"); // Rejection iterations
-    float minRange = psMetadataLookupF32(NULL, recipe, "COMBINE.MIN.RANGE"); // Combination threshold
-    float maxRange = psMetadataLookupF32(NULL, recipe, "COMBINE.MAX.RANGE"); // Combination threshold
-
-    psMetadata *ppsub = psMetadataLookupMetadata(NULL, config->recipes, "PPSUB"); // PPSUB recipe
-    int kernelSize = psMetadataLookupS32(NULL, ppsub, "KERNEL.SIZE"); // Kernel half-size
-
-    psString maskBadStr = psMetadataLookupStr(NULL, recipe, "MASK.VAL"); // Name of bits to mask for bad
-    psImageMaskType maskBad = pmConfigMaskGet(maskBadStr, config); // Bits to mask for bad pixels
-
-    psString maskSuspectStr = psMetadataLookupStr(NULL, recipe, "MASK.SUSPECT"); // Name of suspect mask bits
+    float minRange = psMetadataLookupF32(&mdok, recipe, "COMBINE.MIN.RANGE"); // Combination threshold
+    float maxRange = psMetadataLookupF32(&mdok, recipe, "COMBINE.MAX.RANGE"); // Combination threshold
+
+    char defaultBlankStr[16] = "BLANK";
+
+    psString maskBadStr     = psMetadataLookupStr(&mdok, recipe, "MASK.VAL"); // Name of bits to mask for bad
+    psString maskSuspectStr = psMetadataLookupStr(&mdok, recipe, "MASK.SUSPECT"); // Name of suspect mask bits
+    psString maskBlankStr   = psMetadataLookupStr(&mdok, recipe, "MASK.BLANK"); // Name of bits to set for empty pixels
+    if (!maskBlankStr) {
+      maskBlankStr = psMetadataLookupStr(&mdok, recipe, "MASK.BAD"); // Old name for MASK.BLANK
+    }
+    if (!maskBlankStr) {
+      maskBlankStr = defaultBlankStr; // this is statically allocated above
+    }
+
+    psImageMaskType maskBad     = pmConfigMaskGet(maskBadStr, config); // Bits to mask for bad pixels
     psImageMaskType maskSuspect = pmConfigMaskGet(maskSuspectStr, config); // Suspect bits
-
-    bool status = false;
-    psImageMaskType maskBlank;
-    psString maskBlankStr = psMetadataLookupStr(&status, recipe, "MASK.BLANK"); // Name of bits to set for empty pixels
-    if (maskBlankStr) {
-      maskBlank = pmConfigMaskGet(maskBlankStr, config); // Bits to mask for bad pixels
-    } else {
-      maskBlankStr = psMetadataLookupStr(&status, recipe, "MASK.BAD"); // Old name for MASK.BLANK
-      if (maskBlankStr) {
-	maskBlank = pmConfigMaskGet(maskBlankStr, config); // Bits to mask for bad pixels
-      } else {
-	maskBlank = pmConfigMaskGet("BLANK", config); // Bits to mask for bad pixels
-      }
-    }
+    psImageMaskType maskBlank   = pmConfigMaskGet(maskBlankStr, config); // Bits to mask for bad pixels
 
     int num = readouts->n;              // Number of inputs
@@ -412,10 +405,6 @@
     sectionNum++;
 
-    psArray *results = psArrayAlloc(2); // Array of results
-    results->data[0] = inspect;
-    results->data[1] = reject;
-
-    return results;
-}
-
-
+    return true;
+}
+
+
