Index: trunk/ppStack/src/ppStackLoop.c
===================================================================
--- trunk/ppStack/src/ppStackLoop.c	(revision 19453)
+++ trunk/ppStack/src/ppStackLoop.c	(revision 19475)
@@ -771,4 +771,6 @@
     }
 
+    psThreadPoolFinalize();
+
     memDump("final");
 
@@ -786,13 +788,29 @@
     // Close up
     bool wcsDone = false;           // Have we done the WCS?
+    psList *fpaList = psListAlloc(NULL); // List of input FPAs, for concept averaging
+    psList *cellList = psListAlloc(NULL); // List of input cells, for concept averaging
+    float totExposure = 0.0;            // Total exposure time
     for (int i = 0; i < num; i++) {
         if (!inputMask->data.U8[i]) {
             continue;
         }
+        ppStackThread *thread = stack->threads->data[0]; // Representative stack
+        pmReadout *inRO = thread->readouts->data[i]; // Template readout
+        if (!inRO) {
+            continue;
+        }
+        float exposure = psMetadataLookupF32(NULL, inRO->parent->concepts, "CELL.EXPOSURE"); // Exposure time
+        if (!isfinite(exposure)) {
+            psWarning("CELL.EXPOSURE not set for readout %d", i);
+        } else {
+            totExposure += exposure;
+        }
+
+        psListAdd(cellList, PS_LIST_TAIL, inRO->parent);
+        psListAdd(fpaList, PS_LIST_TAIL, inRO->parent->parent->parent);
+
         if (!wcsDone) {
             // Copy astrometry over
             wcsDone = true;
-            ppStackThread *thread = stack->threads->data[0]; // Representative stack
-            pmReadout *inRO = thread->readouts->data[i]; // Template readout
             if (inRO) {
                 pmHDU *inHDU = pmHDUFromCell(inRO->parent); // Template HDU
@@ -838,4 +856,18 @@
     psFree(weightNames);
 
+    // Copy concepts
+    pmCell *outCell = outRO->parent;    // Output cell
+    pmChip *outChip = outCell->parent;  // Output chip
+    pmFPA *outFPA = outChip->parent;    // Output FPA
+    psMetadataAddF32(outCell->concepts, PS_LIST_TAIL, "CELL.EXPOSURE", PS_META_REPLACE,
+                     "Summed exposure time (sec)", totExposure);
+    psMetadataAddF32(outFPA->concepts, PS_LIST_TAIL, "FPA.EXPOSURE", PS_META_REPLACE,
+                     "Summed exposure time (sec)", totExposure);
+
+    pmConceptsAverageFPAs(outFPA, fpaList);
+    pmConceptsAverageCells(outCell, cellList, NULL, NULL, true);
+    psFree(fpaList);
+    psFree(cellList);
+
     psFree(inputMask);
     psFree(stack);
Index: trunk/ppStack/src/ppStackMatch.c
===================================================================
--- trunk/ppStack/src/ppStackMatch.c	(revision 19453)
+++ trunk/ppStack/src/ppStackMatch.c	(revision 19475)
@@ -15,5 +15,5 @@
                      PM_SOURCE_MODE_CR_LIMIT) // Mask to apply to input sources
 
-//#define TESTING                         // Enable debugging output
+#define TESTING                         // Enable debugging output
 
 
Index: trunk/ppStack/src/ppStackReadout.c
===================================================================
--- trunk/ppStack/src/ppStackReadout.c	(revision 19453)
+++ trunk/ppStack/src/ppStackReadout.c	(revision 19475)
@@ -196,11 +196,4 @@
     psArray *stack = psArrayAlloc(num); // Array for stacking
 
-    pmCell *outCell = outRO->parent;    // Output cell
-    pmChip *outChip = outCell->parent;  // Output chip
-    pmFPA *outFPA = outChip->parent;    // Output FPA
-
-    float totExposure = 0.0;            // Total exposure time
-    psList *fpaList = psListAlloc(NULL); // List of input FPAs, for concept averaging
-    psList *cellList = psListAlloc(NULL); // List of input cells, for concept averaging
     int numGood = num;                  // Number of good inputs: images that haven't been completely rejected
     for (int i = 0; i < num; i++) {
@@ -222,15 +215,4 @@
         }
 
-        float exposure = psMetadataLookupF32(NULL, ro->parent->concepts, "CELL.EXPOSURE"); // Exposure time
-        if (!isfinite(exposure)) {
-            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
-                    "CELL.EXPOSURE is not set for input file %ld", stack->n);
-            psFree(fpaList);
-            psFree(cellList);
-            psFree(stack);
-            return false;
-        }
-        totExposure += exposure;        // Total exposure time
-
         // Ensure there is a mask, or pmStackCombine will complain
         if (!ro->mask) {
@@ -239,7 +221,4 @@
         }
 
-        psListAdd(fpaList, PS_LIST_TAIL, fpa);
-        psListAdd(cellList, PS_LIST_TAIL, ro->parent);
-
         pmStackData *data = pmStackDataAlloc(ro, weighting);
         data->reject = psMemIncrRefCounter(rejected->data[i]);
@@ -250,6 +229,4 @@
                         numGood != num, useVariance, false)) {
         psError(PS_ERR_UNKNOWN, false, "Unable to combine input readouts.");
-        psFree(fpaList);
-        psFree(cellList);
         psFree(stack);
         return false;
@@ -267,18 +244,10 @@
 #endif
 
-    psMetadataAddF32(outCell->concepts, PS_LIST_TAIL, "CELL.EXPOSURE", PS_META_REPLACE,
-                     "Summed exposure time (sec)", totExposure);
-    psMetadataAddF32(outCell->parent->parent->concepts, PS_LIST_TAIL, "FPA.EXPOSURE", PS_META_REPLACE,
-                     "Summed exposure time (sec)", totExposure);
+    pmCell *outCell = outRO->parent;    // Output cell
+    pmChip *outChip = outCell->parent;  // Output chip
 
     outRO->data_exists = true;
     outCell->data_exists = true;
-    outCell->parent->data_exists = true;
-
-    // Copy other concepts
-    pmConceptsAverageFPAs(outFPA, fpaList);
-    pmConceptsAverageCells(outCell, cellList, NULL, NULL, true);
-    psFree(fpaList);
-    psFree(cellList);
+    outChip->data_exists = true;
 
     psFree(stack);
