Index: /trunk/psModules/src/camera/pmFPAMaskWeight.c
===================================================================
--- /trunk/psModules/src/camera/pmFPAMaskWeight.c	(revision 7402)
+++ /trunk/psModules/src/camera/pmFPAMaskWeight.c	(revision 7403)
@@ -1,6 +1,92 @@
 #include <stdio.h>
-#include "pslib.h"
+#include <assert.h>
+
+#include <pslib.h>
 #include "pmFPA.h"
+#include "pmHDU.h"
+#include "pmHDUUtils.h"
+#include "pmHDUGenerate.h"
 #include "pmFPAMaskWeight.h"
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// File-static (private) functions
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+// Create the parent mask images that reside in the HDU
+static void createParentMasks(pmHDU *hdu // The HDU for which to create
+                             )
+{
+    assert(hdu);
+    assert(hdu->images);
+
+    // Generate the parent mask images
+    psArray *images = hdu->images;      // Array of images
+    psArray *masks = hdu->masks;        // Array of masks
+    if (!masks) {
+        masks = psArrayAlloc(images->n);
+        masks->n = images->n;
+        hdu->masks = masks;
+    }
+
+    for (long i = 0; i < images->n; i++) {
+        psImage *image = images->data[i]; // The image for this readout
+        if (!image || masks->data[i]) {
+            continue;
+        }
+        masks->data[i] = psImageAlloc(image->numCols, image->numRows, PS_TYPE_F32);
+    }
+
+    return;
+}
+
+// Create the parent weight images that reside in the HDU
+static void createParentWeights(pmHDU *hdu // The HDU for which to create
+                               )
+{
+    assert(hdu);
+    assert(hdu->images);
+
+    // Generate the parent mask images
+    psArray *images = hdu->images;      // Array of images
+    psArray *weights = hdu->weights;    // Array of weight images
+    if (!masks) {
+        weights = psArrayAlloc(images->n);
+        weights->n = images->n;
+        hdu->weights = weights;
+    }
+
+    for (long i = 0; i < images->n; i++) {
+        psImage *image = images->data[i]; // The image for this readout
+        if (!image || weights->data[i]) {
+            continue;
+        }
+        weights->data[i] = psImageAlloc(image->numCols, image->numRows, PS_TYPE_F32);
+    }
+
+    return;
+}
+
+// Identify a readout within the HDU, on the basis of the image pointer.
+// This is a little dirty, but hopefully should work....
+static long identifyReadout(pmHDU *hdu, // The HDU containing the readouts
+                            pmReadout *readout // The readout to be identified
+                           )
+{
+    assert(hdu);
+    assert(readout);
+
+    long index = -1;                    // Index of the readout
+    for (long i = 0; i < hdu->images->n && index == -1; i++) {
+        if (hdu->images->data[i] == readout->image) {
+            index = i;
+        }
+    }
+
+    return index;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Public functions
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
 bool pmReadoutSetMask(pmReadout *readout // Readout for which to set mask
@@ -25,17 +111,44 @@
     psTrace(__func__, 5, "Saturation: %f, bad: %f\n", saturation, bad);
 
+    // Create the mask image if required
+    if (!readout->mask) {
+        psRegion *trimsec = psMetadataLookupPtr(&mdok, cell->concepts, "CELL.TRIMSEC"); // Trim section
+        if (!mdok || psRegionIsNaN(*trimsec)) {
+            psError(PS_ERR_IO, true, "CELL.TRIMSEC is not set --- unable to set mask.\n");
+            return false;
+        }
+
+        pmHDU *hdu = pmHDUFromCell(cell);   // The HDU containing the cell's pixels
+        PS_ASSERT_PTR_NON_NULL(hdu, false);
+        if (!hdu->images && !pmHDUGenerateForCell(cell)) {
+            psError(PS_ERR_UNKNOWN, false, "Unable to generate HDU for cell.\n");
+            return false;
+        }
+
+        createParentMasks(hdu);
+
+        // Need to identify which readout we're working with....
+        long index = identifyReadout(hdu, readout); // Index of the readout
+        if (index == -1) {
+            psError(PS_ERR_UNKNOWN, true, "Unable to identify readout image in HDU.\n");
+            return false;
+        }
+
+        psImage *mask = psImageSubset(hdu->images->data[index], *trimsec); // The mask pixels
+        if (!mask) {
+            psString trimsecString = psRegionToString(*trimsec);
+            psError(PS_ERR_UNKNOWN, false, "Unable to set mask from HDU with trimsec: %s.\n", trimsecString);
+            psFree(trimsecString);
+            return NULL;
+        }
+        psImageInit(mask, 0);
+        readout->mask = mask;
+    }
+
+    // Set up the mask
     psImage *image = readout->image;    // The image pixels
     psImage *mask = readout->mask;      // The mask pixels
-    if (!mask) {
-        mask = psImageAlloc(image->numCols, image->numRows, PS_TYPE_U8);
-        mask->col0 = image->col0;
-        mask->row0 = image->row0;
-        readout->mask = mask;
-        psImageInit(mask, 0);
-    }
-
-    // Set up the mask
-    for (int i = 0; i < image->numRows; i++) {
-        for (int j = 0; j < image->numCols; j++) {
+    for (long i = 0; i < image->numRows; i++) {
+        for (long j = 0; j < image->numCols; j++) {
             if (image->data.F32[i][j] >= saturation) {
                 mask->data.U8[i][j] |= PM_MASK_SAT;
@@ -70,15 +183,42 @@
     }
 
+    // Create the weight image if required
+    if (!readout->weight) {
+        psRegion *trimsec = psMetadataLookupPtr(&mdok, cell->concepts, "CELL.TRIMSEC"); // Trim section
+        if (!mdok || psRegionIsNaN(*trimsec)) {
+            psError(PS_ERR_IO, true, "CELL.TRIMSEC is not set --- unable to set weight.\n");
+            return false;
+        }
+
+        pmHDU *hdu = pmHDUFromCell(cell);   // The HDU containing the cell's pixels
+        PS_ASSERT_PTR_NON_NULL(hdu, false);
+        if (!hdu->images && !pmHDUGenerateForCell(cell)) {
+            psError(PS_ERR_UNKNOWN, false, "Unable to generate HDU for cell.\n");
+            return false;
+        }
+
+        createParentWeights(hdu);
+
+        // Need to identify which readout we're working with....
+        long index = identifyReadout(hdu, readout); // Index of the readout
+        if (index == -1) {
+            psError(PS_ERR_UNKNOWN, true, "Unable to identify readout image in HDU.\n");
+            return false;
+        }
+
+        psImage *weight = psImageSubset(hdu->images->data[index], *trimsec); // The weight pixels
+        if (!weight) {
+            psString trimsecString = psRegionToString(*trimsec);
+            psError(PS_ERR_UNKNOWN, false, "Unable to set weight from HDU with trimsec: %s.\n",
+                    trimsecString);
+            psFree(trimsecString);
+            return NULL;
+        }
+        psImageInit(weight, 0);
+        readout->weight = weight;
+    }
+
+    // Set weight image to the variance in ADU = f/g + rn^2
     psImage *image = readout->image;    // The image pixels
-    psImage *weight = readout->weight;  // The weight pixels
-    if (!weight) {
-        weight = psImageAlloc(image->numCols, image->numRows, PS_TYPE_F32);
-        weight->col0 = image->col0;
-        weight->row0 = image->row0;
-        readout->weight = weight;
-        psImageInit(weight, 0.0);
-    }
-
-    // Set weight image to the variance in ADU = f/g + rn^2
     psBinaryOp(readout->weight, image, "/", psScalarAlloc(gain, PS_TYPE_F32));
     psBinaryOp(readout->weight, readout->weight, "+",
@@ -104,5 +244,5 @@
 }
 
-bool pmReadoutSetMaskWeight(pmReadout *readout // Readout for which to set weights
+bool pmReadoutSetMaskWeight(pmReadout *readout // Readout for which to set mask and weights
                            )
 {
