Index: trunk/psModules/src/imcombine/pmStackReject.c
===================================================================
--- trunk/psModules/src/imcombine/pmStackReject.c	(revision 16604)
+++ trunk/psModules/src/imcombine/pmStackReject.c	(revision 16607)
@@ -11,43 +11,55 @@
 #define PIXEL_LIST_BUFFER 100           // Number of pixels to add to list at a time
 
-psPixels *pmStackReject(const psPixels *in, float threshold, const psArray *regions,
-                        const psArray *solutions, const pmSubtractionKernels *kernels)
+psPixels *pmStackReject(const psPixels *in, const psRegion *valid, float threshold,
+                        const psArray *subRegions, const psArray *kernels)
 {
     PS_ASSERT_PIXELS_NON_NULL(in, NULL);
     PS_ASSERT_FLOAT_LARGER_THAN_OR_EQUAL(threshold, 0.0, NULL);
     PS_ASSERT_FLOAT_LESS_THAN_OR_EQUAL(threshold, 1.0, NULL);
-    PS_ASSERT_ARRAY_NON_NULL(regions, NULL);
-    PS_ASSERT_ARRAY_NON_NULL(solutions, NULL);
-    PS_ASSERT_ARRAYS_SIZE_EQUAL(regions, solutions, NULL);
-    PS_ASSERT_PTR_NON_NULL(kernels, NULL);
+    PS_ASSERT_ARRAY_NON_NULL(subRegions, NULL);
+    PS_ASSERT_ARRAY_NON_NULL(kernels, NULL);
+    PS_ASSERT_ARRAYS_SIZE_EQUAL(subRegions, kernels, NULL);
 
     // Get the original image size
-    int numRegions = regions->n;        // Number of regions
+    int numRegions = subRegions->n;        // Number of regions
     int numCols = 0, numRows = 0;       // Size of original image
     int minCols = INT_MAX, minRows = INT_MAX; // Minimum coordinate for image
     int size = 0;                       // Size of kernel
     for (int i = 0; i < numRegions; i++) {
-        psRegion *region = regions->data[i]; // Region of interest
-        if (region->x0 < minCols) {
-            minCols = region->x0;
+        psRegion *subRegion = subRegions->data[i]; // Region of interest
+        if (subRegion->x0 < minCols) {
+            minCols = subRegion->x0;
         }
-        if (region->y0 < minRows) {
-            minRows = region->y0;
+        if (subRegion->y0 < minRows) {
+            minRows = subRegion->y0;
         }
-        if (region->x1 > numCols) {
-            numCols = region->x1;
+        if (subRegion->x1 > numCols) {
+            numCols = subRegion->x1;
         }
-        if (region->y1 > numRows) {
-            numRows = region->y1;
+        if (subRegion->y1 > numRows) {
+            numRows = subRegion->y1;
+        }
+
+        pmSubtractionKernels *kernel = kernels->data[i]; // Kernel of interest
+        if (size == 0) {
+            size = kernel->size;
+        } else if (kernel->size != size) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Kernel sizes are not identical: %d vs %d",
+                    size, kernel->size);
+            return NULL;
         }
     }
-    if (minCols != 0 || minRows != 0) {
-        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
-                "Some error with image regions --- minimum coordinate is not 0,0");
-        return NULL;
+
+    // Adjust the size for the size of the subimage
+    if (valid) {
+        minCols = PS_MAX(valid->x0, minCols);
+        minRows = PS_MAX(valid->y0, minRows);
+        numCols = PS_MIN(valid->x1, numCols);
+        numRows = PS_MIN(valid->y1, numRows);
     }
     psTrace("psModules.imcombine", 1, "Rejecting [%d:%d,%d:%d]\n", minCols, numCols, minRows, numRows);
 
-    psImage *mask = psPixelsToMask(NULL, in, psRegionSet(0, numCols, 0, numRows), 0x01); // Mask image
+    psImage *mask = psPixelsToMask(NULL, in, psRegionSet(minCols, numCols - 1, minRows, numRows - 1),
+                                   0x01); // Mask
     psImage *image = psImageCopy(NULL, mask, PS_TYPE_F32); // Floating-point version, so we can convolve
     psFree(mask);
@@ -57,4 +69,6 @@
     pmReadout *inRO = pmReadoutAlloc(NULL); // Readout with input image
     inRO->image = image;
+    inRO->col0 = minCols;
+    inRO->row0 = minRows;
     for (int i = 0; i < numRegions; i++) {
         psRegion *region = subRegions->data[i]; // Region of interest
@@ -76,8 +90,10 @@
 
         // Image of the kernel at the centre of the region
-        float xNorm = (region->x0 + 0.5 * (region->x1 - region->x0) - numCols/2.0) / (float)numCols;
-        float yNorm = (region->y0 + 0.5 * (region->y1 - region->y0) - numRows/2.0) / (float)numRows;
-        psImage *kernel = pmSubtractionKernelImage(kernels, xNorm, yNorm, false);
-        if (!kernel) {
+        float xNorm = (region->x0 + 0.5 * (region->x1 - region->x0) - kernel->numCols/2.0) /
+            (float)kernel->numCols;
+        float yNorm = (region->y0 + 0.5 * (region->y1 - region->y0) - kernel->numRows/2.0) /
+            (float)kernel->numRows;
+        psImage *image = pmSubtractionKernelImage(kernel, xNorm, yNorm, false);
+        if (!image) {
             psError(PS_ERR_UNKNOWN, false, "Unable to generate kernel image.");
             psFree(convRO);
@@ -86,13 +102,23 @@
         }
         float sum = 0.0;
-        for (int y = 0; y < kernel->numRows; y++) {
-            for (int x = 0; x < kernel->numCols; x++) {
-                sum += kernel->data.F32[y][x];
+        for (int y = 0; y < image->numRows; y++) {
+            for (int x = 0; x < image->numCols; x++) {
+                sum += image->data.F32[y][x];
             }
         }
-        psFree(kernel);
+        psFree(image);
 
-        psImage *subConv = psImageSubset(convRO->image, *region); // Sub-image of convolved image
-        psBinaryOp(subConv, subConv, "*", psScalarAlloc(1.0 / sum, PS_TYPE_F32));
+        // Range for normalisation
+        int yMin = PS_MAX(minRows, region->y0) - inRO->row0;
+        int yMax = PS_MIN(numRows - 1, region->y1) - inRO->row0;
+        int xMin = PS_MAX(minCols, region->x0) - inRO->col0;
+        int xMax = PS_MIN(numCols - 1, region->x1) - inRO->col0;
+        psTrace("psModules.imcombine", 2, "Normalising convolved mask image by %f over %d:%d,%d:%d\n",
+                sum, xMin, xMax, yMin, yMax);
+        for (int y = yMin; y <= yMax; y++) {
+            for (int x = xMin; x <= xMax; x++) {
+                convRO->image->data.F32[y][x] /= sum;
+            }
+        }
     }
     psFree(inRO);
@@ -124,4 +150,5 @@
         for (int y = yMin; y <= yMax; y++) {
             for (int x = xMin; x <= xMax; x++) {
+                assert(x < mask->numCols && y < mask->numRows);
                 mask->data.PS_TYPE_MASK_DATA[y][x] = 0xff;
             }
