Index: trunk/ppStack/src/ppStack.h
===================================================================
--- trunk/ppStack/src/ppStack.h	(revision 17031)
+++ trunk/ppStack/src/ppStack.h	(revision 17255)
@@ -63,4 +63,5 @@
                   const pmReadout *sourcesRO, ///< Readout with sources
                   const pmPSF *psf,     ///< Target PSF
+                  psRandom *rng,        ///< Random number generator
                   const pmConfig *config ///< Configuration
     );
Index: trunk/ppStack/src/ppStackArguments.c
===================================================================
--- trunk/ppStack/src/ppStackArguments.c	(revision 17031)
+++ trunk/ppStack/src/ppStackArguments.c	(revision 17255)
@@ -83,4 +83,18 @@
 }
 
+// Get a statistic name from the command-line or recipe, and add the enum to the arguments
+#define VALUE_ARG_RECIPE_STAT(ARGNAME, RECIPENAME) { \
+    const char *stat = psMetadataLookupStr(NULL, arguments, ARGNAME); \
+    if (!stat) { \
+        stat = psMetadataLookupStr(NULL, recipe, RECIPENAME); \
+        if (!stat) { \
+            psError(PS_ERR_BAD_PARAMETER_VALUE, false, "Unable to find %s in recipe %s", \
+                    RECIPENAME, PPSTACK_RECIPE); \
+            goto ERROR; \
+        } \
+    } \
+    psMetadataAddS32(config->arguments, PS_LIST_TAIL, RECIPENAME, 0, NULL, psStatsOptionFromString(stat)); \
+}
+
 // Get a string value from the command-line and add it to the target
 static bool valueArgStr(psMetadata *arguments, // Command-line arguments
@@ -141,4 +155,8 @@
     psMetadataAddBool(arguments, PS_LIST_TAIL, "-variance", 0, "Use variance for rejection?", false);
     psMetadataAddBool(arguments, PS_LIST_TAIL, "-safe", 0, "Play safe with small numbers of pixels to combine?", false);
+    psMetadataAddBool(arguments, PS_LIST_TAIL, "-renorm", 0, "Renormalise variance maps?", false);
+    psMetadataAddStr(arguments, PS_LIST_TAIL, "-renorm-mean", 0, "Statistic for mean in renormalisation", NULL);
+    psMetadataAddStr(arguments, PS_LIST_TAIL, "-renorm-stdev", 0, "Statistic for stdev in renormalisation", NULL);
+    psMetadataAddS32(arguments, PS_LIST_TAIL, "-renorm-width", 0, "Width of renormalisation boxes", 0);
     psMetadataAddStr(arguments, PS_LIST_TAIL, "-temp-image", 0, "Suffix for temporary images", NULL);
     psMetadataAddStr(arguments, PS_LIST_TAIL, "-temp-mask", 0, "Suffix for temporary masks", NULL);
@@ -208,4 +226,12 @@
     }
 
+    if (psMetadataLookupBool(NULL, arguments, "-renorm") ||
+        psMetadataLookupBool(NULL, recipe, "RENORM")) {
+        psMetadataAddBool(config->arguments, PS_LIST_TAIL, "RENORM", 0, "Renormalise variance maps?", true);
+    }
+    VALUE_ARG_RECIPE_INT("-renorm-width", "RENORM.WIDTH", S32, 0);
+    VALUE_ARG_RECIPE_STAT("-renorm-mean", "RENORM.MEAN");
+    VALUE_ARG_RECIPE_STAT("-renorm-stdev", "RENORM.STDEV");
+
     valueArgRecipeStr(arguments, recipe, "-temp-image",  "TEMP.IMAGE",  config->arguments);
     valueArgRecipeStr(arguments, recipe, "-temp-mask",   "TEMP.MASK",   config->arguments);
@@ -218,5 +244,4 @@
     }
 
-
     psTrace("ppStack", 1, "Done reading command-line arguments\n");
     psFree(arguments);
@@ -227,4 +252,2 @@
     return false;
 }
-
-
Index: trunk/ppStack/src/ppStackLoop.c
===================================================================
--- trunk/ppStack/src/ppStackLoop.c	(revision 17031)
+++ trunk/ppStack/src/ppStackLoop.c	(revision 17255)
@@ -306,4 +306,5 @@
     psArray *subKernels = psArrayAlloc(num); // Subtraction kernels --- required in the stacking
     psArray *subRegions = psArrayAlloc(num); // Subtraction regions --- required in the stacking
+    psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS, 0); // Random number generator
     for (int i = 0; i < num; i++) {
         psTrace("ppStack", 2, "Convolving input %d of %d to target PSF....\n", i, num);
@@ -315,4 +316,5 @@
             psFree(sources);
             psFree(targetPSF);
+            psFree(rng);
             return false;
         }
@@ -323,8 +325,9 @@
         // Background subtraction, scaling and normalisation is performed automatically by the image matching
         psArray *regions = NULL, *kernels = NULL; // Regions and kernels used in subtraction
-        if (!ppStackMatch(readout, &regions, &kernels, sources, targetPSF, config)) {
+        if (!ppStackMatch(readout, &regions, &kernels, sources, targetPSF, rng, config)) {
             psError(PS_ERR_UNKNOWN, false, "Unable to match image %d --- ignoring.", i);
             psFree(sources);
             psFree(targetPSF);
+            psFree(rng);
             return false;
         }
@@ -345,4 +348,5 @@
     psFree(sources);
     psFree(targetPSF);
+    psFree(rng);
 
 
Index: trunk/ppStack/src/ppStackMatch.c
===================================================================
--- trunk/ppStack/src/ppStackMatch.c	(revision 17031)
+++ trunk/ppStack/src/ppStackMatch.c	(revision 17255)
@@ -16,5 +16,5 @@
 
 bool ppStackMatch(pmReadout *readout, psArray **regions, psArray **kernels,
-                  const pmReadout *sourcesRO, const pmPSF *psf, const pmConfig *config)
+                  const pmReadout *sourcesRO, const pmPSF *psf, psRandom *rng, const pmConfig *config)
 {
     assert(readout);
@@ -30,7 +30,19 @@
     psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, "PPSUB"); // PPSUB recipe
     int size = psMetadataLookupS32(NULL, recipe, "KERNEL.SIZE"); // Kernel half-size
+    psMaskType maskBad = pmConfigMask(psMetadataLookupStr(NULL, recipe, "MASK.BAD"), config); // Value to mask
+    bool mdok;                          // Status of MD lookup
+    bool renorm = psMetadataLookupBool(&mdok, recipe, "RENORM"); // Renormalise variances?
+    psStatsOptions renormMean = psMetadataLookupS32(&mdok, recipe, "RENORM.MEAN"); // Statistic for mean
+    psStatsOptions renormStdev = psMetadataLookupS32(&mdok, recipe, "RENORM.STDEV"); // Statistic for stdev
+    int renormWidth = psMetadataLookupS32(&mdok, recipe, "RENORM.WIDTH"); // Width for renormalisation box
+
+    // Renormalise the variances if desired
+    if (renorm && !pmReadoutWeightRenorm(readout, maskBad, renormMean, renormStdev, renormWidth, rng)) {
+        psError(PS_ERR_UNKNOWN, false, "Unable to renormalise variances.");
+        psFree(output);
+        return false;
+    }
 
 #ifndef NO_CONVOLUTION
-    bool mdok;                          // Status of MD lookup
     int order = psMetadataLookupS32(NULL, recipe, "SPATIAL.ORDER"); // Spatial polynomial order
     float regionSize = psMetadataLookupF32(NULL, recipe, "REGION.SIZE"); // Size of iso-kernel regs
@@ -47,6 +59,4 @@
     int ringsOrder = psMetadataLookupS32(NULL, recipe, "RINGS.ORDER"); // RINGS polynomial order
     int binning = psMetadataLookupS32(NULL, recipe, "SPAM.BINNING"); // Binning for SPAM kernel
-    psMaskType maskBad = pmConfigMask(psMetadataLookupStr(NULL, recipe, "MASK.BAD"),
-                                      config); // Value to mask
     psMaskType maskBlank = pmConfigMask(psMetadataLookupStr(NULL, recipe, "MASK.BLANK"),
                                         config); // Mask for blank reg.
