Index: trunk/psModules/src/camera/pmFPARead.c
===================================================================
--- trunk/psModules/src/camera/pmFPARead.c	(revision 11687)
+++ trunk/psModules/src/camera/pmFPARead.c	(revision 11793)
@@ -26,5 +26,6 @@
     FPA_READ_TYPE_IMAGE,                // Read image
     FPA_READ_TYPE_MASK,                 // Read mask
-    FPA_READ_TYPE_WEIGHT                // Read weight map
+    FPA_READ_TYPE_WEIGHT,               // Read weight map
+    FPA_READ_TYPE_HEADER                // Read header
 } fpaReadType;
 
@@ -35,8 +36,8 @@
 // Carve a readout from the image pixels
 static bool readoutCarve(pmReadout *readout, // Readout to be carved up
-                         psImage **target, // Target pointer for the carved image
                          psImage *image, // Image that will be carved
                          const psRegion *trimsec, // Trim section
-                         const psList *biassecs // Bias sections
+                         const psList *biassecs, // Bias sections
+			 fpaReadType type
                         )
 {
@@ -59,10 +60,33 @@
                                   PS_MIN(trimsec->y1 - readout->row0, image->numRows) // y1
                                  );
-    if (readout->image) {
-        psFree(readout->image);         // Make way!
-    }
-    *target = psMemIncrRefCounter(psImageSubset(image, region));
-
+
+    // place the image subset in the appropriate target location, freeing if needed
+    // XXX why psMemIncrRefCounter on psImageSubset??
+    switch (type) {
+      case FPA_READ_TYPE_IMAGE:
+	if (readout->image) {
+	    psFree (readout->image);
+	}
+	readout->image = psMemIncrRefCounter(psImageSubset(image, region));	
+	break;
+      case FPA_READ_TYPE_MASK:
+	if (readout->mask) {
+	    psFree (readout->mask);
+	}
+	readout->mask = psMemIncrRefCounter(psImageSubset(image, region));	
+	break;
+      case FPA_READ_TYPE_WEIGHT:
+	if (readout->weight) {
+	    psFree (readout->weight);
+	}
+	readout->weight = psMemIncrRefCounter(psImageSubset(image, region));	
+	break;
+      default:
+	psAbort("Unknown read type: %x\n", type);
+    }
+    
     // Get the list of overscans
+    // XXX should this step only be performed for IMAGE, not MASK and WEIGHT types?
+    // XXX that would allow us to overlay a MASK and WEIGHT which have been trimmed...
     if (readout->bias->n != 0) {
         // Make way!
@@ -184,36 +208,68 @@
     }
 
+    // check if we have read the desired data, read it if needed
     bool (*hduReadFunc)(pmHDU*, psFits*) = NULL; // Function to use to read the HDU
-    psArray **imageArray = NULL; // Array of images in the HDU
-    psElemType imageType = PS_TYPE_F32; // Expected type for image
+    void *dataPointer = NULL; 		// pointer to location of desired data
     switch (type) {
-    case FPA_READ_TYPE_IMAGE:
+      case FPA_READ_TYPE_IMAGE:
         hduReadFunc = pmHDURead;
-        imageArray = &hdu->images;
-        imageType = PS_TYPE_F32;
+        dataPointer = hdu->images;
         break;
-    case FPA_READ_TYPE_MASK:
+      case FPA_READ_TYPE_HEADER:
+        hduReadFunc = pmHDUReadHeader;
+        dataPointer = hdu->header;
+        break;
+      case FPA_READ_TYPE_MASK:
         hduReadFunc = pmHDUReadMask;
-        imageArray = &hdu->masks;
-        imageType = PS_TYPE_MASK;
+        dataPointer = hdu->masks;
         break;
-    case FPA_READ_TYPE_WEIGHT:
+      case FPA_READ_TYPE_WEIGHT:
         hduReadFunc = pmHDUReadWeight;
-        imageArray = &hdu->weights;
-        imageType = PS_TYPE_F32;
+        dataPointer = hdu->weights;
         break;
-    default:
+      default:
         psAbort("Unknown read type: %x\n", type);
     }
 
-    if (!(*imageArray) && !hduReadFunc(hdu, fits)) {
-        psError(PS_ERR_UNKNOWN, false, "Unable to read HDU for cell.\n");
-        return false;
-    }
-
+    // do we have the data we want (image, header, or etc).
+    if (!dataPointer) {
+	// attempt to read in the desired data
+	if (!hduReadFunc(hdu, fits)) {
+	    psError(PS_ERR_UNKNOWN, false, "Unable to read HDU for cell.\n");
+	    return false;
+	}
+    }
+
+    // load in the concept information for this cell
     if (!pmConceptsReadCell(cell, PM_CONCEPT_SOURCE_HEADER, true, NULL)) {
         //psError(PS_ERR_UNKNOWN, false, "Failed to read concepts for cell");
         //return false;
         psWarning("Difficulty reading concepts for cell; attempting to proceed.");
+    }
+
+    // skip the image arrays completely for the header-only files
+    if (type == FPA_READ_TYPE_HEADER) {
+	pmCellSetDataStatus(cell, true);
+	return true;
+    }
+
+    // set up pointers for the different possible image arrays
+    psArray *imageArray = NULL;	// Array of images in the HDU
+    psElemType imageType = PS_TYPE_F32; // Expected type for image
+    switch (type) {
+      case FPA_READ_TYPE_IMAGE:
+        imageArray = hdu->images;
+        imageType = PS_TYPE_F32;
+        break;
+      case FPA_READ_TYPE_MASK:
+	imageArray = hdu->masks;
+        imageType = PS_TYPE_MASK;
+        break;
+      case FPA_READ_TYPE_WEIGHT:
+        imageArray = hdu->weights;
+        imageType = PS_TYPE_F32;
+        break;
+      default:
+        psAbort("Unknown read type: %x\n", type);
     }
 
@@ -228,12 +284,12 @@
     // Iterate over each of the image planes, converting type if necessary, and extracting the bits that
     // matter (CELL.TRIMSEC, CELL.BIASSEC) into readouts with readoutCarve.
-    for (int i = 0; i < (*imageArray)->n; i++) {
-        psImage *source = (*imageArray)->data[i]; // Source image, from the i-th plane
+    for (int i = 0; i < imageArray->n; i++) {
+        psImage *source = imageArray->data[i]; // Source image, from the i-th plane
 
         // Type conversion here to support the modules, which don't have multiple type support yet
         if (source->type.type != imageType) {
             psImage *temp = psImageCopy(NULL, source, imageType); // Temporary image
-            psFree((*imageArray)->data[i]);
-            (*imageArray)->data[i] = temp;
+            psFree(imageArray->data[i]);
+            imageArray->data[i] = temp;
             source = temp;
         }
@@ -246,20 +302,5 @@
         }
 
-        psImage **target = NULL;               // Place in readout to put carved image
-        switch (type) {
-        case FPA_READ_TYPE_IMAGE:
-            target = &readout->image;
-            break;
-        case FPA_READ_TYPE_MASK:
-            target = &readout->mask;
-            break;
-        case FPA_READ_TYPE_WEIGHT:
-            target = &readout->weight;
-            break;
-        default:
-            psAbort("Unknown read type: %x\n", type);
-        }
-
-        if (!readoutCarve(readout, target, source, trimsec, biassecs)) {
+        if (!readoutCarve(readout, source, trimsec, biassecs, type)) {
             psError(PS_ERR_UNEXPECTED_NULL, false,
                     "Unable to carve readout into image and bias sections for %d the plane.", i);
@@ -594,4 +635,32 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Reading the image header
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+bool pmCellReadHeaderSet(pmCell *cell, psFits *fits, psDB *db)
+{
+    PS_ASSERT_PTR_NON_NULL(cell, false);
+    PS_ASSERT_PTR_NON_NULL(fits, false);
+
+    return cellRead(cell, fits, db, FPA_READ_TYPE_HEADER);
+}
+
+bool pmChipReadHeaderSet(pmChip *chip, psFits *fits, psDB *db)
+{
+    PS_ASSERT_PTR_NON_NULL(chip, false);
+    PS_ASSERT_PTR_NON_NULL(fits, false);
+
+    return chipRead(chip, fits, db, FPA_READ_TYPE_HEADER);
+}
+
+bool pmFPAReadHeaderSet(pmFPA *fpa, psFits *fits, psDB *db)
+{
+    PS_ASSERT_PTR_NON_NULL(fpa, false);
+    PS_ASSERT_PTR_NON_NULL(fits, false);
+
+    return fpaRead(fpa, fits, db, FPA_READ_TYPE_HEADER);
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
 // Reading FITS tables
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
