Index: trunk/ppStack/src/ppStackLoop.c
===================================================================
--- trunk/ppStack/src/ppStackLoop.c	(revision 21258)
+++ trunk/ppStack/src/ppStackLoop.c	(revision 21366)
@@ -24,8 +24,8 @@
 
 // Files required for the convolution
-static char *convolveFiles[] = { "PPSTACK.INPUT", "PPSTACK.INPUT.MASK", "PPSTACK.INPUT.WEIGHT", NULL };
+static char *convolveFiles[] = { "PPSTACK.INPUT", "PPSTACK.INPUT.MASK", "PPSTACK.INPUT.VARIANCE", NULL };
 
 // Output files for the combination
-static char *combineFiles[] = { "PPSTACK.OUTPUT", "PPSTACK.OUTPUT.MASK", "PPSTACK.OUTPUT.WEIGHT",
+static char *combineFiles[] = { "PPSTACK.OUTPUT", "PPSTACK.OUTPUT.MASK", "PPSTACK.OUTPUT.VARIANCE",
                                 "PPSTACK.OUTPUT.JPEG1", "PPSTACK.OUTPUT.JPEG2", NULL };
 
@@ -204,8 +204,8 @@
     const char *tempImage = psMetadataLookupStr(NULL, recipe, "TEMP.IMAGE"); // Suffix for temporary images
     const char *tempMask = psMetadataLookupStr(NULL, recipe, "TEMP.MASK"); // Suffix for temporary masks
-    const char *tempWeight = psMetadataLookupStr(NULL, recipe, "TEMP.WEIGHT"); // Suffix for temp weight maps
-    if (!tempImage || !tempMask || !tempWeight) {
+    const char *tempVariance = psMetadataLookupStr(NULL, recipe, "TEMP.VARIANCE"); // Suffix for temp variance maps
+    if (!tempImage || !tempMask || !tempVariance) {
         psError(PS_ERR_BAD_PARAMETER_VALUE, false,
-                "Unable to find TEMP.IMAGE, TEMP.MASK and TEMP.WEIGHT in recipe");
+                "Unable to find TEMP.IMAGE, TEMP.MASK and TEMP.VARIANCE in recipe");
         return false;
     }
@@ -387,14 +387,14 @@
     psArray *imageNames = psArrayAlloc(num);
     psArray *maskNames = psArrayAlloc(num);
-    psArray *weightNames = psArrayAlloc(num);
+    psArray *varianceNames = psArrayAlloc(num);
     for (int i = 0; i < num; i++) {
-        psString imageName = NULL, maskName = NULL, weightName = NULL; // Names for convolved images
+        psString imageName = NULL, maskName = NULL, varianceName = NULL; // Names for convolved images
         psStringAppend(&imageName, "%s/%s.%d.%s", tempDir, tempName, i, tempImage);
         psStringAppend(&maskName, "%s/%s.%d.%s", tempDir, tempName, i, tempMask);
-        psStringAppend(&weightName, "%s/%s.%d.%s", tempDir, tempName, i, tempWeight);
-        psTrace("ppStack", 5, "Temporary files: %s %s %s\n", imageName, maskName, weightName);
+        psStringAppend(&varianceName, "%s/%s.%d.%s", tempDir, tempName, i, tempVariance);
+        psTrace("ppStack", 5, "Temporary files: %s %s %s\n", imageName, maskName, varianceName);
         imageNames->data[i] = imageName;
         maskNames->data[i] = maskName;
-        weightNames->data[i] = weightName;
+        varianceNames->data[i] = varianceName;
     }
     // Free the outputName that we grabbed above to set up tempName.
@@ -417,4 +417,5 @@
     psList *fpaList = psListAlloc(NULL); // List of input FPAs, for concept averaging
     psList *cellList = psListAlloc(NULL); // List of input cells, for concept averaging
+    psArray *covariances = psArrayAlloc(num); // Covariance matrices
     for (int i = 0; i < num; i++) {
         psTrace("ppStack", 2, "Convolving input %d of %d to target PSF....\n", i, num);
@@ -431,4 +432,5 @@
             psFree(fpaList);
             psFree(cellList);
+            psFree(covariances);
             return false;
         }
@@ -450,4 +452,5 @@
             psFree(fpaList);
             psFree(cellList);
+            psFree(covariances);
             return false;
         }
@@ -464,4 +467,5 @@
             continue;
         }
+        covariances->data[i] = psMemIncrRefCounter(readout->covariance);
 
         if (stats) {
@@ -486,10 +490,9 @@
         pmHDU *hdu = readout->parent->parent->parent->hdu; // HDU for convolved image
         assert(hdu);
-        writeImage(imageNames->data[i],  hdu->header, readout->image, config);
         psMetadata *maskHeader = psMetadataCopy(NULL, hdu->header); // Copy of header, for mask
         pmConfigMaskWriteHeader(config, maskHeader);
-        writeImage(maskNames->data[i],   maskHeader, readout->mask, config);
+        writeImage(maskNames->data[i], maskHeader, readout->mask, config);
         psFree(maskHeader);
-        writeImage(weightNames->data[i], hdu->header, readout->weight, config);
+        writeImage(varianceNames->data[i], hdu->header, readout->variance, config);
 
         pmCell *inCell = readout->parent; // Input cell
@@ -502,4 +505,5 @@
             psFree(fpaList);
             psFree(cellList);
+            psFree(covariances);
             return false;
         }
@@ -523,4 +527,5 @@
         psFree(fpaList);
         psFree(cellList);
+        psFree(covariances);
         return false;
     }
@@ -570,4 +575,5 @@
             psFree(matchChi2);
             psFree(values);
+            psFree(covariances);
             return false;
         }
@@ -611,4 +617,5 @@
         psFree(inputMask);
         psFree(matchChi2);
+        psFree(covariances);
         return false;
     }
@@ -622,5 +629,5 @@
     // Start threading
     ppStackThreadInit();
-    ppStackThreadData *stack = ppStackThreadDataSetup(cells, imageNames, maskNames, weightNames, config);
+    ppStackThreadData *stack = ppStackThreadDataSetup(cells, imageNames, maskNames, varianceNames, config);
 
     psTimerStart("PPSTACK_INITIAL");
@@ -645,4 +652,5 @@
             psFree(matchChi2);
             psFree(cells);
+            psFree(covariances);
             return false;
         }
@@ -658,4 +666,5 @@
             psFree(matchChi2);
             psFree(cells);
+            psFree(covariances);
             return false;
         }
@@ -676,4 +685,5 @@
             psFree(outRO);
             psFree(cells);
+            psFree(covariances);
             return false;
         }
@@ -695,4 +705,5 @@
                 psFree(view);
                 psFree(outRO);
+                psFree(covariances);
                 return false;
             }
@@ -721,4 +732,5 @@
                 psFree(view);
                 psFree(outRO);
+                psFree(covariances);
                 return false;
             }
@@ -735,4 +747,5 @@
             psFree(view);
             psFree(outRO);
+            psFree(covariances);
             return false;
         }
@@ -803,4 +816,5 @@
                 psFree(inspect);
                 psFree(rejected);
+                psFree(covariances);
                 return false;
             }
@@ -818,4 +832,5 @@
             psFree(inspect);
             psFree(rejected);
+            psFree(covariances);
             return false;
         }
@@ -912,4 +927,5 @@
             psFree(view);
             psFree(outRO);
+            psFree(covariances);
             return false;
         }
@@ -941,4 +957,5 @@
                 psFree(view);
                 psFree(outRO);
+                psFree(covariances);
                 return false;
             }
@@ -962,4 +979,5 @@
                 psFree(view);
                 psFree(outRO);
+                psFree(covariances);
                 return false;
             }
@@ -974,4 +992,5 @@
             psFree(view);
             psFree(outRO);
+            psFree(covariances);
             return false;
         }
@@ -979,4 +998,14 @@
 
     memDump("final");
+
+    // Sum covariance matrices
+    for (int i = 0; i < num; i++) {
+        if (inputMask->data.U8[i]) {
+            psFree(covariances->data[i]);
+            covariances->data[i] = NULL;
+        }
+    }
+    outRO->covariance = psImageCovarianceSum(covariances);
+    psFree(covariances);
 
     if (stats) {
@@ -1040,17 +1069,17 @@
             psString imageResolved = pmConfigConvertFilename(imageNames->data[i], config, false, false);
             psString maskResolved = pmConfigConvertFilename(maskNames->data[i], config, false, false);
-            psString weightResolved = pmConfigConvertFilename(weightNames->data[i], config, false, false);
+            psString varianceResolved = pmConfigConvertFilename(varianceNames->data[i], config, false, false);
             if (unlink(imageResolved) == -1 || unlink(maskResolved) == -1 ||
-                unlink(weightResolved) == -1) {
+                unlink(varianceResolved) == -1) {
                 psWarning("Unable to delete temporary files for image %d", i);
             }
             psFree(imageResolved);
             psFree(maskResolved);
-            psFree(weightResolved);
+            psFree(varianceResolved);
         }
     }
     psFree(imageNames);
     psFree(maskNames);
-    psFree(weightNames);
+    psFree(varianceNames);
 
     psFree(inputMask);
@@ -1092,6 +1121,6 @@
         float renormWidth = psMetadataLookupS32(&mdok, recipe, "RENORM.WIDTH"); // Width of Gaussian phot
         psImageMaskType maskValue = pmConfigMaskGet("BLANK", config); // Bits to mask
-        if (!pmReadoutWeightRenormPhot(outRO, maskValue, renormNum, renormWidth,
-                                       renormMean, renormStdev, NULL)) {
+        if (!pmReadoutVarianceRenormPhot(outRO, maskValue, renormNum, renormWidth,
+                                         renormMean, renormStdev, NULL)) {
             psError(PS_ERR_UNKNOWN, false, "Unable to renormalise variances.");
             psFree(outRO);
