Index: trunk/ppStack/src/Makefile.am
===================================================================
--- trunk/ppStack/src/Makefile.am	(revision 23575)
+++ trunk/ppStack/src/Makefile.am	(revision 23576)
@@ -29,4 +29,5 @@
 	ppStackPrepare.c	\
 	ppStackConvolve.c	\
+	ppStackCombinePrepare.c	\
 	ppStackCombineInitial.c	\
 	ppStackReject.c		\
Index: trunk/ppStack/src/ppStackCamera.c
===================================================================
--- trunk/ppStack/src/ppStackCamera.c	(revision 23575)
+++ trunk/ppStack/src/ppStackCamera.c	(revision 23576)
@@ -51,4 +51,11 @@
     bool status = false;                // Status of file definition
 
+    psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSTACK_RECIPE); // Recipe for ppSim
+    if (!recipe) {
+        psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find recipe %s", PPSTACK_RECIPE);
+        return false;
+    }
+    bool convolve = psMetadataLookupBool(NULL, recipe, "CONVOLVE"); // Convolve images before stack?
+
     psArray *runImages = pmFPAfileDefineMultipleFromRun(&status, NULL, config,
                                                         "PPSTACK.INPUT"); // Input images from previous run
@@ -98,5 +105,5 @@
         }
         if (!runSrc) {
-            psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to define input sources from RUN metadta.");
+            psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to define input sources from RUN metadata.");
             psFree(runImages);
             return false;
@@ -104,17 +111,20 @@
         psFree(runSrc);
 
-        psArray *runKernel = pmFPAfileDefineMultipleFromRun(&status, runImages, config,
-                                                            "PPSTACK.CONV.KERNEL"); // Convolution kernels
-        if (!status) {
-            psError(PS_ERR_UNKNOWN, false, "Unable to define convolution kernels from RUN metadata.");
-            psFree(runImages);
-            return false;
-        }
-        if (!runSrc) {
-            psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to define convolution kernels from RUN metadta.");
-            psFree(runImages);
-            return false;
-        }
-        psFree(runKernel);
+        if (convolve) {
+            psArray *runKernel = pmFPAfileDefineMultipleFromRun(&status, runImages, config,
+                                                                "PPSTACK.CONV.KERNEL"); // Convolution kernels
+            if (!status) {
+                psError(PS_ERR_UNKNOWN, false, "Unable to define convolution kernels from RUN metadata.");
+                psFree(runImages);
+                return false;
+            }
+            if (!runKernel) {
+                psError(PS_ERR_UNEXPECTED_NULL, true,
+                        "Unable to define convolution kernels from RUN metadata.");
+                psFree(runImages);
+                return false;
+            }
+            psFree(runKernel);
+        }
 
         psFree(runImages);
@@ -200,10 +210,12 @@
             }
 
-            pmFPAfile *kernel = pmFPAfileDefineOutput(config, imageFile->fpa, "PPSTACK.CONV.KERNEL");
-            if (!kernel) {
-                psError(PS_ERR_IO, false, _("Unable to generate output file from PPSTACK.CONV.KERNEL"));
-                return false;
-            }
-            kernel->save = true;
+            if (convolve) {
+                pmFPAfile *kernel = pmFPAfileDefineOutput(config, imageFile->fpa, "PPSTACK.CONV.KERNEL");
+                if (!kernel) {
+                    psError(PS_ERR_IO, false, _("Unable to generate output file from PPSTACK.CONV.KERNEL"));
+                    return false;
+                }
+                kernel->save = true;
+            }
 
             i++;
@@ -300,11 +312,4 @@
     }
     jpeg2->save = true;
-
-
-    psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSTACK_RECIPE); // Recipe for ppSim
-    if (!recipe) {
-        psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find recipe %s", PPSTACK_RECIPE);
-        return false;
-    }
 
     // For photometry, we operate on the chip-mosaicked image
Index: trunk/ppStack/src/ppStackCombineInitial.c
===================================================================
--- trunk/ppStack/src/ppStackCombineInitial.c	(revision 23575)
+++ trunk/ppStack/src/ppStackCombineInitial.c	(revision 23576)
@@ -23,40 +23,8 @@
     psTimerStart("PPSTACK_INITIAL");
 
-    psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSTACK_RECIPE); // ppStack recipe
-    psAssert(recipe, "We've thrown an error on this before.");
-
     psMetadata *ppsub = psMetadataLookupMetadata(NULL, config->recipes, "PPSUB"); // PPSUB recipe
     int overlap = 2 * psMetadataLookupS32(NULL, ppsub,
                                           "KERNEL.SIZE"); // Overlap by kernel size between consecutive scans
 
-    pmFPAview *view = NULL;             // View to readout
-
-    int row0, col0;                 // Offset for readout
-    int numCols, numRows;           // Size of readout
-    ppStackThread *thread = stack->threads->data[0]; // Representative thread
-    if (!pmReadoutStackSetOutputSize(&col0, &row0, &numCols, &numRows, thread->readouts)) {
-        psError(PS_ERR_UNKNOWN, false, "problem setting output readout size.");
-        return false;
-    }
-
-    pmFPAfileActivate(config->files, false, NULL);
-    ppStackFileActivation(config, PPSTACK_FILES_COMBINE, true);
-    view = ppStackFilesIterateDown(config);
-    if (!view) {
-        return false;
-    }
-
-    pmCell *outCell = pmFPAfileThisCell(config->files, view, "PPSTACK.OUTPUT"); // Output cell
-    options->outRO = pmReadoutAlloc(outCell); // Output readout
-    psFree(view);
-
-    psString maskBadStr = psMetadataLookupStr(NULL, recipe, "MASK.BAD"); // Name of bits to mask for bad
-    psImageMaskType maskBad = pmConfigMaskGet(maskBadStr, config); // Bits to mask for bad pixels
-    if (!pmReadoutStackDefineOutput(options->outRO, col0, row0, numCols, numRows, true, true, maskBad)) {
-        psError(PS_ERR_UNKNOWN, false, "Unable to prepare output.");
-        return false;
-    }
-
-    psFree(options->cells); options->cells = NULL;
 
     bool status;                    // Status of read
Index: trunk/ppStack/src/ppStackCombinePrepare.c
===================================================================
--- trunk/ppStack/src/ppStackCombinePrepare.c	(revision 23576)
+++ trunk/ppStack/src/ppStackCombinePrepare.c	(revision 23576)
@@ -0,0 +1,47 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <pslib.h>
+#include <psmodules.h>
+
+#include "ppStack.h"
+#include "ppStackLoop.h"
+
+bool ppStackCombinePrepare(ppStackThreadData *stack, ppStackOptions *options, pmConfig *config)
+{
+    psAssert(stack, "Require stack");
+    psAssert(options, "Require options");
+    psAssert(config, "Require configuration");
+
+    int row0, col0;                 // Offset for readout
+    int numCols, numRows;           // Size of readout
+    ppStackThread *thread = stack->threads->data[0]; // Representative thread
+    if (!pmReadoutStackSetOutputSize(&col0, &row0, &numCols, &numRows, thread->readouts)) {
+        psError(PS_ERR_UNKNOWN, false, "problem setting output readout size.");
+        return false;
+    }
+
+    pmFPAfileActivate(config->files, false, NULL);
+    ppStackFileActivation(config, PPSTACK_FILES_COMBINE, true);
+    pmFPAview *view = ppStackFilesIterateDown(config); // View to readout
+    if (!view) {
+        return false;
+    }
+
+    pmCell *outCell = pmFPAfileThisCell(config->files, view, "PPSTACK.OUTPUT"); // Output cell
+    options->outRO = pmReadoutAlloc(outCell); // Output readout
+    psFree(view);
+
+    psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSTACK_RECIPE); // ppStack recipe
+    psAssert(recipe, "We've thrown an error on this before.");
+    psString maskBadStr = psMetadataLookupStr(NULL, recipe, "MASK.BAD"); // Name of bits to mask for bad
+    psImageMaskType maskBad = pmConfigMaskGet(maskBadStr, config); // Bits to mask for bad pixels
+    if (!pmReadoutStackDefineOutput(options->outRO, col0, row0, numCols, numRows, true, true, maskBad)) {
+        psError(PS_ERR_UNKNOWN, false, "Unable to prepare output.");
+        return false;
+    }
+
+    return true;
+}
Index: trunk/ppStack/src/ppStackLoop.c
===================================================================
--- trunk/ppStack/src/ppStackLoop.c	(revision 23575)
+++ trunk/ppStack/src/ppStackLoop.c	(revision 23576)
@@ -59,4 +59,13 @@
     if (!stack) {
         psError(PS_ERR_IO, false, "Unable to initialise stack threads.");
+        psFree(options);
+        return false;
+    }
+    psFree(options->cells); options->cells = NULL;
+
+    // Prepare for combination
+    if (!ppStackCombinePrepare(stack, options, config)) {
+        psError(PS_ERR_UNKNOWN, false, "Unable to prepare for combination.");
+        psFree(stack);
         psFree(options);
         return false;
Index: trunk/ppStack/src/ppStackLoop.h
===================================================================
--- trunk/ppStack/src/ppStackLoop.h	(revision 23575)
+++ trunk/ppStack/src/ppStackLoop.h	(revision 23576)
@@ -30,4 +30,11 @@
 // Convolve inputs to match target PSF
 bool ppStackConvolve(
+    ppStackOptions *options,            // Options
+    pmConfig *config                    // Configuration
+    );
+
+// Prepare for combination
+bool ppStackCombinePrepare(
+    ppStackThreadData *stack,           // Stack
     ppStackOptions *options,            // Options
     pmConfig *config                    // Configuration
Index: trunk/ppStack/src/ppStackReadout.c
===================================================================
--- trunk/ppStack/src/ppStackReadout.c	(revision 23575)
+++ trunk/ppStack/src/ppStackReadout.c	(revision 23576)
@@ -185,6 +185,5 @@
     assert(outRO);
     assert(readouts);
-    assert(rejected);
-    assert(readouts->n == rejected->n);
+    assert(!rejected || readouts->n == rejected->n);
     assert(mask && mask->n == readouts->n && mask->type.type == PS_TYPE_VECTOR_MASK);
     assert(weightings && weightings->n == readouts->n && weightings->type.type == PS_TYPE_F32);
@@ -207,10 +206,13 @@
     psArray *stack = psArrayAlloc(num); // Array for stacking
 
-    int numGood = num;                  // Number of good inputs: images that haven't been completely rejected
+    bool entire = (rejected ? false : true); // Combine entire image?
     for (int i = 0; i < num; i++) {
         pmReadout *ro = readouts->data[i];
-        if (!ro || !rejected->data[i] || mask->data.PS_TYPE_VECTOR_MASK_DATA[i]) {
-            // Image completely rejected
-            numGood--;
+        if (mask->data.U8[i] & (PPSTACK_MASK_REJECT | PPSTACK_MASK_BAD)) {
+            // Image completely rejected since previous combination
+            entire = true;
+            continue;
+        } else if (mask->data.U8[i]) {
+            // Image completely rejected before original combination
             continue;
         }
@@ -234,10 +236,10 @@
         pmStackData *data = pmStackDataAlloc(ro, weightings->data.F32[i],
                                              addVariance ? addVariance->data.F32[i] : NAN);
-        data->reject = psMemIncrRefCounter(rejected->data[i]);
+        data->reject = rejected ? psMemIncrRefCounter(rejected->data[i]) : NULL;
         stack->data[i] = data;
     }
 
     if (!pmStackCombine(outRO, stack, maskVal | maskBad, maskBad, 0, 0, NAN, NAN, NAN,
-                        numGood != num, useVariance, false)) {
+                        entire, useVariance, false)) {
         psError(PS_ERR_UNKNOWN, false, "Unable to combine input readouts.");
         psFree(stack);
Index: trunk/ppStack/src/ppStackSetup.c
===================================================================
--- trunk/ppStack/src/ppStackSetup.c	(revision 23575)
+++ trunk/ppStack/src/ppStackSetup.c	(revision 23576)
@@ -14,5 +14,6 @@
 
 // Generate an array of input filenames
-static psArray *stackNameArray(pmConfig *config, // Configuration
+static psArray *stackNameArray(const ppStackOptions *options, // Stack options
+                               pmConfig *config, // Configuration
                                const char *name // Name of file
     )
@@ -21,19 +22,16 @@
     psAssert(config, "Require file name");
 
-    psString regex = NULL;             // Regular expression for selecting file
-    psStringAppend(&regex, "^%s$", name);
-    psMetadataIterator *iter = psMetadataIteratorAlloc(config->files, PS_LIST_HEAD, regex); // Iterator
-    psFree(regex);
-    psMetadataItem *item;               // Item from iteration
-    psArray *array = psArrayAlloc(BUFFER); // Array of file names
-    while ((item = psMetadataGetAndIncrement(iter))) {
-        psAssert(item->type == PS_DATA_UNKNOWN, "Should be this type");
-        pmFPAfile *file = item->data.V; // An input file
+    psArray *array = psArrayAllocEmpty(options->num); // Array with filenames
+    pmFPAview *view = pmFPAviewAlloc(0);// View to readout
+    view->chip = view->cell = view->readout = -1;
 
-        psString filename = psStringCopy(file->filename); // Filename of interest
+    for (int i = 0; i < options->num; i++) {
+        pmFPAfile *file = pmFPAfileSelectSingle(config->files, name, i); // File of interest
+
+        psString filename = pmFPAfileName(file, view, config); // Filename of interest
+        psAssert(filename, "Can't determine filename");
         psArrayAdd(array, array->n, filename);
         psFree(filename);               // Drop reference
     }
-    psFree(iter);
 
     return array;
@@ -114,7 +112,7 @@
         psFree(outputName);
     } else {
-        options->imageNames = stackNameArray(config, "PPSTACK.INPUT");
-        options->maskNames = stackNameArray(config, "PPSTACK.INPUT.MASK");
-        options->varianceNames = stackNameArray(config, "PPSTACK.INPUT.VARIANCE");
+        options->imageNames = stackNameArray(options, config, "PPSTACK.INPUT");
+        options->maskNames = stackNameArray(options, config, "PPSTACK.INPUT.MASK");
+        options->varianceNames = stackNameArray(options, config, "PPSTACK.INPUT.VARIANCE");
     }
 
