Index: trunk/archive/scripts/src/phase2/pmFPAWrite.c
===================================================================
--- trunk/archive/scripts/src/phase2/pmFPAWrite.c	(revision 5371)
+++ trunk/archive/scripts/src/phase2/pmFPAWrite.c	(revision 5564)
@@ -5,12 +5,13 @@
 #include "pmFPA.h"
 #include "pmFPAConceptsSet.h"
+#include "pmFPARead.h"
 
 static bool writeHDU(psFits *fits,	// FITS file to which to write
-		     pmPixelData *pixelData // Pixel data to write
+		     p_pmHDU *hdu	// Pixel data to write
     )
 {
     bool status = true;			// Status of write, to return
-    for (int i = 0; i < pixelData->images->n; i++) {
-	status &= psFitsWriteImage(fits, pixelData->header, pixelData->images->data[i], i);
+    for (int i = 0; i < hdu->images->n; i++) {
+	status &= psFitsWriteImage(fits, hdu->header, hdu->images->data[i], i);
 	// XXX: Insert here the writing on mask and weight images
     }
@@ -47,12 +48,12 @@
 		    pmCellOutgestConcepts(cell, db);
 
-		    if (cell->data && strlen(cell->data->extname) > 0) {
-			status &= writeHDU(fits, cell->data);
+		    if (cell->hdu && strlen(cell->hdu->extname) > 0) {
+			status &= writeHDU(fits, cell->hdu);
 		    }
 		}
 	    }
 	    
-	    if (chip->data && strlen(chip->data->extname) > 0) {
-		status &= writeHDU(fits, chip->data);
+	    if (chip->hdu && strlen(chip->hdu->extname) > 0) {
+		status &= writeHDU(fits, chip->hdu);
 	    }
 	}
@@ -60,8 +61,213 @@
     }
 
-    if (fpa->data && strlen(fpa->data->extname) > 0) {
-	status &= writeHDU(fits, fpa->data);
+    if (fpa->hdu && strlen(fpa->hdu->extname) > 0) {
+	status &= writeHDU(fits, fpa->hdu);
     }
 
     return status;
 }
+
+
+bool pmFPAWriteMask(pmFPA *fpa, 	// FPA containing mask to write
+		    psFits *fits	// FITS file for image
+    )
+{
+    const psMetadata *camera = fpa->camera; // Camera configuration for FPA
+    bool mdok = false;			// Status of MD lookup
+
+    // Get the required information from the camera configuration
+    psMetadata *supps = psMetadataLookupMD(&mdok, camera, "SUPPLEMENTARY"); // Rules for supplementary data
+    if (! mdok || ! supps) {
+	psError(PS_ERR_IO, false, "Unable to find SUPPLEMENTARY in camera configuration!\n");
+	return false;
+    }
+    psString sourceType = psMetadataLookupString(&mdok, supps, "MASK.SOURCE"); // Type of source: EXT | FILE
+    if (! mdok || strlen(sourceType) <= 0) {
+	psError(PS_ERR_IO, false, "Unable to find MASK.SOURCE in SUPPLEMENTARY section of camera "
+		"configuration!\n");
+	return false;
+    }
+    psString name = psMetadataLookupString(&mdok, supps, "MASK.NAME"); // Name of mask
+    if (! mdok || strlen(sourceType) <= 0) {
+	psError(PS_ERR_IO, false, "Unable to find MASK.NAME in SUPPLEMENTARY section of camera "
+		"configuration!\n");
+	return false;
+    }
+
+    // Go through the FPA to each cell/readout to get the mask
+    p_pmHDU *hdu = fpa->hdu;		// The HDU into which we will read the mask
+    psArray *chips = fpa->chips;	// Array of chips
+    for (int chipNum = 0; chipNum < chips->n; chipNum++) {
+	pmChip *chip = chips->data[chipNum]; // The current chip of interest
+	if (chip->valid) {
+	    if (chip->hdu) {
+		hdu = chip->hdu;
+	    }
+	    psArray *cells = chip->cells;	// Array of cells
+	    for (int cellNum = 0; cellNum < cells->n; cellNum++) {
+		pmCell *cell = cells->data[cellNum]; // The current cell of interest
+		if (cell->valid) {
+		    if (cell->hdu) {
+			hdu = cell->hdu;
+		    }
+
+		    // Now, need to find out where to write the pixels
+		    psFits *maskDest = psMemIncrRefCounter(fits); // Destination of mask image
+		    psMetadata *header = psMetadataAlloc(); // A dummy header, containing the extension name
+		    if (strcasecmp(sourceType, "FILE") == 0) {
+			// Source is a file (with optional extension, e.g., "myMaskFile.fits:thisExt"
+			psString filenameExt = p_pmFPATranslateName(name, cell);
+			char *colon = strchr(filenameExt, ':');	// Pointer to a colon in the filename-extn
+			psString filename = NULL; // The filename
+			psString extname = NULL;// The extenstion name
+			if (colon) {
+			    filename = psStringNCopy(filenameExt, strlen(filenameExt) - strlen(colon));
+			    if (strlen(colon) > 1) {
+				extname = psStringCopy(colon + 1);
+			    }
+			} else {
+			    filename = psMemIncrRefCounter(filenameExt);
+			}
+
+			psFree(maskDest);
+			maskDest = psFitsAlloc(filename);
+			if (extname) {
+			    psMetadataAddStr(header, PS_LIST_TAIL, "EXTNAME", 0, "Extension name", extname);
+			}
+			psFree(filename);
+			psFree(extname);
+			psFree(filenameExt);
+		    } else if (strncasecmp(sourceType, "EXT", 3) == 0) {
+			// Source is an extension in the original file
+			psString extname = p_pmFPATranslateName(name, cell);
+			psMetadataAddStr(header, PS_LIST_TAIL, "EXTNAME", 0, "Extension name", extname);
+			psFree(extname);
+		    }
+		    
+		    // We've arrived where the pixels are.  Now we need to write them out.
+		    psArray *readouts = cell->readouts; // The array of readouts
+		    for (int readNum = 0; readNum < readouts->n; readNum++) {
+			pmReadout *readout = readouts->data[readNum]; // The readout of interest
+			if (! readout->mask) {
+			    psLogMsg(__func__, PS_LOG_WARN, "No mask to write out in %d,%d,%d\n",
+				     chipNum, cellNum, readNum);
+			} else {
+			    // XXX: Need to add the extname to the existing header
+			    if (! psFitsWriteImage(maskDest, header, readout->mask, readNum)) {
+				psError(PS_ERR_IO, false, "Unable to write mask plane %d in extension %s\n",
+					readNum, hdu->extname);
+				return false;
+			    }
+			}
+		    } // Iterating over readouts
+		    psFree(header);
+		    psFree(maskDest);
+		} // Valid cells
+	    } // Iterating over cells
+	} // Valid chips
+    } // Iterating over chips
+
+    return true;
+}
+
+
+bool pmFPAWriteWeight(pmFPA *fpa, 	// FPA containing mask to write
+		      psFits *fits	// FITS file for image
+    )
+{
+    const psMetadata *camera = fpa->camera; // Camera configuration for FPA
+    bool mdok = false;			// Status of MD lookup
+
+    // Get the required information from the camera configuration
+    psMetadata *supps = psMetadataLookupMD(&mdok, camera, "SUPPLEMENTARY"); // Rules for supplementary data
+    if (! mdok || ! supps) {
+	psError(PS_ERR_IO, false, "Unable to find SUPPLEMENTARY in camera configuration!\n");
+	return false;
+    }
+    psString sourceType = psMetadataLookupString(&mdok, supps, "WEIGHT.SOURCE"); // Type of source: EXT | FILE
+    if (! mdok || strlen(sourceType) <= 0) {
+	psError(PS_ERR_IO, false, "Unable to find WEIGHT.SOURCE in SUPPLEMENTARY section of camera "
+		"configuration!\n");
+	return false;
+    }
+    psString name = psMetadataLookupString(&mdok, supps, "WEIGHT.NAME"); // Name of weight
+    if (! mdok || strlen(sourceType) <= 0) {
+	psError(PS_ERR_IO, false, "Unable to find WEIGHT.NAME in SUPPLEMENTARY section of camera "
+		"configuration!\n");
+	return false;
+    }
+
+    // Go through the FPA to each cell/readout to get the weight
+    p_pmHDU *hdu = fpa->hdu;		// The HDU into which we will read the weight
+    psArray *chips = fpa->chips;	// Array of chips
+    for (int chipNum = 0; chipNum < chips->n; chipNum++) {
+	pmChip *chip = chips->data[chipNum]; // The current chip of interest
+	if (chip->valid) {
+	    if (chip->hdu) {
+		hdu = chip->hdu;
+	    }
+	    psArray *cells = chip->cells;	// Array of cells
+	    for (int cellNum = 0; cellNum < cells->n; cellNum++) {
+		pmCell *cell = cells->data[cellNum]; // The current cell of interest
+		if (cell->valid) {
+		    if (cell->hdu) {
+			hdu = cell->hdu;
+		    }
+
+		    // Now, need to find out where to write the pixels
+		    psFits *weightDest = psMemIncrRefCounter(fits); // Destination of weight image
+		    psMetadata *header = psMetadataAlloc(); // A dummy header, containing the extension name
+		    if (strcasecmp(sourceType, "FILE") == 0) {
+			// Source is a file (with optional extension, e.g., "myWeightFile.fits:thisExt"
+			psString filenameExt = p_pmFPATranslateName(name, cell);
+			char *colon = strchr(filenameExt, ':');	// Pointer to a colon in the filename-extn
+			psString filename = NULL; // The filename
+			psString extname = NULL;// The extenstion name
+			if (colon) {
+			    filename = psStringNCopy(filenameExt, strlen(filenameExt) - strlen(colon));
+			    if (strlen(colon) > 1) {
+				extname = psStringCopy(colon + 1);
+			    }
+			} else {
+			    filename = psMemIncrRefCounter(filenameExt);
+			}
+
+			psFree(weightDest);
+			weightDest = psFitsAlloc(filename);
+			if (extname) {
+			    psMetadataAddStr(header, PS_LIST_TAIL, "EXTNAME", 0, "Extension name", extname);
+			}
+			psFree(filename);
+			psFree(extname);
+			psFree(filenameExt);
+		    } else if (strncasecmp(sourceType, "EXT", 3) == 0) {
+			// Source is an extension in the original file
+			psString extname = p_pmFPATranslateName(name, cell);
+			psMetadataAddStr(header, PS_LIST_TAIL, "EXTNAME", 0, "Extension name", extname);
+			psFree(extname);
+		    }
+
+		    // We've arrived where the pixels are.  Now we need to write them out.
+		    psArray *readouts = cell->readouts; // The array of readouts
+		    for (int readNum = 0; readNum < readouts->n; readNum++) {
+			pmReadout *readout = readouts->data[readNum]; // The readout of interest
+			if (! readout->weight) {
+			    psLogMsg(__func__, PS_LOG_WARN, "No weight image to write out in %d,%d,%d\n",
+				     chipNum, cellNum, readNum);
+			} else {
+			    if (! psFitsWriteImage(weightDest, header, readout->weight, readNum)) {
+				psError(PS_ERR_IO, false, "Unable to write weight plane %d in extension %s\n",
+					readNum, hdu->extname);
+				return false;
+			    }
+			}
+		    } // Iterating over readouts
+		    psFree(header);
+		    psFree(weightDest);
+		} // Valid cells
+	    } // Iterating over cells
+	} // Valid chips
+    } // Iterating over chips
+
+    return true;
+}
