Index: trunk/psModules/src/camera/pmHDUGenerate.c
===================================================================
--- trunk/psModules/src/camera/pmHDUGenerate.c	(revision 9730)
+++ trunk/psModules/src/camera/pmHDUGenerate.c	(revision 9983)
@@ -218,7 +218,18 @@
 
         pmReadout *readout = cell->readouts->data[0]; // The first readout, as representative
-        psImage *image = readout->image;// The proper image
+        // The proper image, used to get the size
+        psImage *image = readout->image ? readout->image : (readout->mask ? readout->mask : readout->weight);
         if (!image) {
             continue;
+        }
+        if (readout->mask &&
+                (readout->mask->numCols != image->numCols || readout->mask->numRows != image->numRows)) {
+            psLogMsg(__func__, PS_LOG_WARN, "Image and mask have different sizes (%dx%d vs %dx%d)!\n",
+                     image->numCols, image->numRows, readout->mask->numCols, readout->mask->numRows);
+        }
+        if (readout->weight &&
+                (readout->weight->numCols != image->numCols || readout->weight->numRows != image->numRows)) {
+            psLogMsg(__func__, PS_LOG_WARN, "Image and weight have different sizes (%dx%d vs %dx%d)!\n",
+                     image->numCols, image->numRows, readout->weight->numCols, readout->weight->numRows);
         }
         // New reference
@@ -239,4 +250,47 @@
     return (position > 0);
 }
+
+// Check the type for a current image against a previous type
+static psElemType checkTypes(psElemType previous, // Previously defined type, or 0
+                             psElemType current // Current type
+                            )
+{
+    if (previous == 0) {
+        return current;
+    }
+
+    if (previous != current) {
+        psLogMsg(__func__, PS_LOG_WARN, "Images within the HDU are of different types "
+                 "(%x vs %x) --- promoting\n", previous, current);
+        return PS_MAX(previous, current);
+    }
+
+    return previous;
+}
+
+
+// Paste the source image into the target, according to the provided region.  The source is then updated to
+// reference the region within the target.
+static void pasteImage(psImage *target, // Target image, into which the paste is made
+                       psImage **sourcePtr,// Source image, from which the paste is made, and then changed
+                       psRegion *region // Image section into which to paste
+                      )
+{
+    psImage *source = *sourcePtr;       // Dereference pointer, for convenience
+    if (source->numCols != region->x1 - region->x0 || source->numRows != region->y1 - region->y0) {
+        psString regionString = psRegionToString(*region);
+        psLogMsg(__func__, PS_LOG_WARN, "Image size (%dx%d) does not match region (%s).\n",
+                 source->numCols, source->numRows, regionString);
+        psFree(regionString);
+    }
+    psImageOverlaySection(target, source, region->x0, region->y0, "=");
+
+    // Reference the HDU version, so that subsequent changes will touch the HDU
+    psFree(source);
+    *sourcePtr = psImageSubset(target, *region);
+
+    return;
+}
+
 
 // Generate the HDU, given a list of cells below that HDU.  This is the main engine function, that does all
@@ -248,5 +302,7 @@
     // Check the number of readouts is consistent within the HDU
     int numReadouts = -1;               // Number of readouts
-    psElemType type = 0;                // Type of readout images
+    psElemType imageType = 0;           // Type of readout images
+    psElemType maskType = 0;   // Type of readout masks
+    psElemType weightType = 0;          // Type of readout weights
     {
         psListIterator *iter = psListIteratorAlloc(cells, PS_LIST_HEAD, false); // Iterator for cells
@@ -264,14 +320,16 @@
             for (int i = 0; i < numReadouts; i++) {
                 pmReadout *readout = readouts->data[i]; // The readout
-                if (!readout || !readout->image) {
+                if (!readout) {
                     continue;
                 }
-                psElemType imageType = readout->image->type.type; // Type for this image
-                if (type == 0) {
-                    type = imageType;
-                } else if (type != imageType) {
-                    psLogMsg(__func__, PS_LOG_WARN, "Images within the HDU are of different types "
-                             "(%x vs %x) --- promoting\n", type, imageType);
-                    type = PS_MAX(type, imageType);
+
+                if (readout->image) {
+                    imageType = checkTypes(imageType, readout->image->type.type);
+                }
+                if (readout->mask) {
+                    maskType = checkTypes(maskType, readout->mask->type.type);
+                }
+                if (readout->weight) {
+                    weightType = checkTypes(weightType, readout->weight->type.type);
                 }
             }
@@ -279,5 +337,5 @@
         psFree(iter);
     }
-    if (numReadouts == 0 || type == 0) {
+    if (numReadouts == 0 || (imageType == 0 && maskType == 0 && weightType == 0)) {
         // Nothing from which to create an HDU
         psFree(cells);
@@ -293,9 +351,27 @@
 
     // Generate the HDU
-    hdu->images = psArrayAlloc(numReadouts);
-    for (int i = 0; i < numReadouts; i++) {
-        psImage *image = psImageAlloc(xSize, ySize, type);
-        psImageInit(image, 0.0);
-        hdu->images->data[i] = image;
+    if (imageType) {
+        hdu->images = psArrayAlloc(numReadouts);
+        for (int i = 0; i < numReadouts; i++) {
+            psImage *image = psImageAlloc(xSize, ySize, imageType);
+            psImageInit(image, 0.0);
+            hdu->images->data[i] = image;
+        }
+    }
+    if (maskType) {
+        hdu->masks = psArrayAlloc(numReadouts);
+        for (int i = 0; i < numReadouts; i++) {
+            psImage *mask = psImageAlloc(xSize, ySize, maskType);
+            psImageInit(mask, 0);
+            hdu->masks->data[i] = mask;
+        }
+    }
+    if (weightType) {
+        hdu->weights = psArrayAlloc(numReadouts);
+        for (int i = 0; i < numReadouts; i++) {
+            psImage *weight = psImageAlloc(xSize, ySize, weightType);
+            psImageInit(weight, 0.0);
+            hdu->weights->data[i] = weight;
+        }
     }
 
@@ -319,4 +395,6 @@
             psArray *readouts = cell->readouts; // Array of readouts
             psArray *hduImages = hdu->images; // Array of images in the HDU
+            psArray *hduMasks = hdu->masks; // Array of masks in the HDU
+            psArray *hduWeights = hdu->weights; // Array of weights in the HDU
             for (int i = 0; i < readouts->n; i++) {
                 pmReadout *readout = readouts->data[i]; // The readout of interest
@@ -324,19 +402,14 @@
                     continue;
                 }
-                psImage *image = readout->image; // The image pixels
-                psImage *hduImage = hduImages->data[i]; // The HDU image of interest
-
-                if (image->numCols != trimsec->x1 - trimsec->x0 ||
-                        image->numRows != trimsec->y1 - trimsec->y0) {
-                    psString trimsecString = psRegionToString(*trimsec);
-                    psLogMsg(__func__, PS_LOG_WARN, "Image size (%dx%d) does not match CELL.TRIMSEC (%s).\n",
-                             image->numCols, image->numRows, trimsecString);
-                    psFree(trimsecString);
-                }
-                psImageOverlaySection(hduImage, image, trimsec->x0, trimsec->y0, "=");
-
-                // Reference the HDU version, so that subsequent changes will touch the HDU
-                psFree(image);
-                readout->image = psImageSubset(hduImage, *trimsec);
+
+                if (readout->image) {
+                    pasteImage(hduImages->data[i], &readout->image, trimsec);
+                }
+                if (readout->mask) {
+                    pasteImage(hduMasks->data[i], &readout->mask, trimsec);
+                }
+                if (readout->weight) {
+                    pasteImage(hduWeights->data[i], &readout->weight, trimsec);
+                }
 
                 if (biassecs->n != readout->bias->n) {
@@ -351,16 +424,5 @@
                 while ((bias = psListGetAndIncrement(biasIter)) &&
                         (biassec = psListGetAndIncrement(biassecsIter))) {
-                    if (bias->numCols != biassec->x1 - biassec->x0 ||
-                            bias->numRows != biassec->y1 - biassec->y0) {
-                        psString biassecString = psRegionToString(*biassec);
-                        psLogMsg(__func__, PS_LOG_WARN, "Bias size (%dx%d) does not match CELL.BIASSEC (%s)."
-                                 "\n", bias->numCols, bias->numRows, biassecString);
-                        psFree(biassecString);
-                    }
-
-                    psImageOverlaySection(hduImage, bias, biassec->x0, biassec->y0, "=");
-
-                    // Reference the HDU version, so that subsequent changes will touch the HDU
-                    bias = psImageSubset(hduImage, *biassec);
+                    pasteImage(hduImages->data[i], &bias, biassec);
                     psListAdd(newBias, PS_LIST_TAIL, bias);
                 }
