Index: trunk/archive/scripts/src/pmFPARead.c
===================================================================
--- trunk/archive/scripts/src/pmFPARead.c	(revision 4386)
+++ trunk/archive/scripts/src/pmFPARead.c	(revision 4694)
@@ -5,4 +5,5 @@
 #include "papStuff.h"
 #include "papFocalPlane.h"
+#include "pmFPARead.h"
 
 // NOTE: Need to deal with header inheritance
@@ -11,42 +12,4 @@
 // File-static functions
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-// Copy metadata elements into another metadata
-static void metadataCopy(psMetadata *to, // Metadata to which to copy
-			 psMetadata *from // Metdata from which to copy
-    )
-{
-    psMetadataIterator *mdIter = psMetadataIteratorAlloc(from, PS_LIST_HEAD, NULL); // Iterator for the MD
-    psMetadataItem *item = NULL;	// Item from the metadata
-    while (item = psMetadataGetAndIncrement(mdIter)) {
-	psTrace(__func__, 9, "Adding %s to metadata...\n", item->name);
-	if (! psMetadataAddItem(to, item, PS_LIST_TAIL, PS_META_REPLACE)) {
-	    psLogMsg(__func__, PS_LOG_WARN, "Unable to add item (%s: %s) to metadata: ignored\n", item->name,
-		     item->comment);
-	}
-    }
-    psFree(mdIter);
-}
-
-// Read data for a particular cell from the camera configuration
-static psMetadata *getCellData(const psMetadata *camera, // The camera configuration
-			       const char *cellName // The name of the cell
-    )
-{
-    bool status = true;			// Result of MD lookup
-    psMetadata *cells = psMetadataLookupMD(&status, camera, "CELLS"); // The CELLS
-    if (! status) {
-	psError(PS_ERR_IO, false, "Unable to determine CELLS of camera.\n");
-	return NULL;
-    }
-
-    psMetadata *cellData = psMetadataLookupMD(&status, cells, cellName); // The data for the particular cell
-    if (! status) {
-	psError(PS_ERR_IO, false, "Unable to find specs for cell %s: ignored\n", cellName);
-	return NULL;
-    } else {
-	return cellData;
-    }
-}
 
 // Read a FITS extension into a chip
@@ -57,4 +20,5 @@
     )
 {
+    psTrace(__func__, 7, "Moving to extension %s...\n", extName);
     if (strncmp(extName, "PHU", 3) == 0) {
 	if (!psFitsMoveExtNum(fits, 0, false)) {
@@ -66,5 +30,12 @@
 	return false;
     }
+    psTrace(__func__, 7, "Reading header....\n");
     *header = psFitsReadHeader(*header, fits);
+    if (! *header) {
+	psError(PS_ERR_IO, false, "Unable to read FITS header!\n");
+	return false;
+    }
+
+    psTrace(__func__, 7, "Checking NAXIS....\n");
     bool mdStatus = false;
     int nAxis = psMetadataLookupS32(&mdStatus, *header, "NAXIS");
@@ -77,4 +48,5 @@
 		 "anyway.\n");
     }
+    psTrace(__func__, 9, "NAXIS = %d\n", nAxis);
 
     int numPlanes = 1;			// Number of planes
@@ -89,7 +61,11 @@
 
     // Read each plane into the array
+    psTrace(__func__, 7, "Reading %d planes into array....\n", numPlanes);
     *images = psArrayAlloc(numPlanes); // Array of images
     for (int i = 0; i < numPlanes; i++) {
-	(*images)->data[i] = psFitsReadImage((*images)->data[i], fits, region, 0);
+	psTrace(__func__, 9, "Reading plane %d\n", i);
+	psMemCheckCorruption(true);
+	(*images)->data[i] = psFitsReadImage(NULL, fits, region, i);
+	psTrace(__func__, 10, "Done\n");
         if (! (*images)->data[i]) {
 	    psError(PS_ERR_IO, false, "Unable to read image for extension %s, plane %d\n", extName, i);
@@ -119,4 +95,8 @@
 		    region.y1);
 	    numFound++;
+	    // Convert from FITS standard to PS standard
+	    region.x0 -= 1;
+	    region.y0 -= 1;
+	    // We don't touch the x1 and y1 values because they aren't included by psImageSubset.
 	    psImage *subImage = psImageSubset(image, region);
 	    psListAdd(list, PS_LIST_TAIL, subImage);
@@ -166,4 +146,8 @@
 		// We have the region: [x0:x1,y0:y1]
 		psRegion region = psRegionFromString(regionString);
+		// Convert from FITS standard to PS standard
+		region.x0 -= 1;
+		region.y0 -= 1;
+		// We don't touch the x1 and y1 values because they aren't included by psImageSubset.
 		psImage *subImage = psImageSubset(image, region);
 		psListAdd(subImages, PS_LIST_TAIL, subImage);
@@ -251,292 +235,57 @@
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
-papFPA *pmFPARead(psFits *fits, // A FITS file
-		  const psMetadata *camera, // The camera configuration
-		  psDB *db		// Database
-    )
-{
-    papFPA *fpa = papFPAAlloc(camera, db); // The FPA to fill out
-    bool mdStatus = true;		// Status from metadata lookups
-    const char *phuType = psMetadataLookupString(&mdStatus, camera, "PHU"); // What is the PHU?
-    const char *extType = psMetadataLookupString(&mdStatus, camera, "EXTENSIONS"); // What's in the extensions?
-    if (strncmp(phuType, "FPA", 3) == 0) {
-	// The FITS file contains an entire FPA
-
-	psMetadata *contents = psMetadataLookupMD(&mdStatus, camera, "CONTENTS"); // The CONTENTS
-	if (! mdStatus) {
-	    psError(PS_ERR_IO, false, "Unable to determine CONTENTS of camera.\n");
-	    psFree(fpa);
-	    return NULL;
-	}
-
-	// Set up iteration over the contents
-	psMetadataIterator *contentsIter = psMetadataIteratorAlloc(contents, PS_LIST_HEAD, NULL);
-	psMetadataItem *contentItem = NULL; // Item from the metadata
-
-	if (strncmp(extType, "CHIP", 4) == 0) {
-	    // Extensions are chips; Content contains a list of cells
-	    while (contentItem = psMetadataGetAndIncrement(contentsIter)) {
-		const char *extName = contentItem->name; // The name of the extension
-		papChip *chip = papChipAlloc(fpa, extName); // The chip
-		readExtension(&(chip->pixels), &(chip->header), fits, extName);
-		if (contentItem->type != PS_META_STR) {
-		    psLogMsg(__func__, PS_LOG_WARN, "Type of content item (%x) is not string: ignored\n",
-			     contentItem->type);
-		} else {
-		    const char *content = contentItem->data.V; // The content of the extension
-		    psTrace(__func__, 7, "Content of %s is: %s\n", extName, content);
-		    psList *cellNames = papSplit(content, " ,"); // A list of the component cells
-		    psListIterator *cellNamesIter = psListIteratorAlloc(cellNames, PS_LIST_HEAD, NULL);
-		    char *cellName = NULL; // The name of a cell
-		    while (cellName = psListGetAndIncrement(cellNamesIter)) {
-			// Get the cell data
-			papCell *cell = papCellAlloc(chip, cellName, ((psArray*)chip->pixels)->n); // The cell
-			psMetadata *cellData = getCellData(camera, cellName);
-			metadataCopy(cell->values, cellData);
-			portionCell(cell, chip->pixels, chip->header);
-		    }
-		    psFree(cellNamesIter);
-		    psFree(cellNames);
+bool pmFPARead(papFPA *fpa,		// FPA to read into
+	       psFits *fits		// FITS file from which to read
+    )
+{
+    psArray *pixels = NULL;		// Current pixels from FITS file (array of images)
+    psMetadata *header = NULL;		// Current header from FITS file
+
+    psTrace(__func__, 1, "Working on FPA...\n");
+    if (fpa->extname) {
+	psTrace(__func__, 3, "Reading pixels from extension %s into FPA.\n", fpa->extname);
+	if (! readExtension(&fpa->pixels, &fpa->header, fits, fpa->extname)) {
+	    psError(PS_ERR_IO, false, "Unable to read pixels from extension %s\n", fpa->extname);
+	    return false;
+	}
+	pixels = fpa->pixels;
+	header = fpa->header;
+    }
+
+    psArray *chips = fpa->chips;	// Array of chips
+    // Iterate over the FPA
+    for (int i = 0; i < chips->n; i++) {
+	papChip *chip = chips->data[i]; // The chip
+	psTrace(__func__, 2, "Working on chip %d...\n", i);
+	if (chip->extname) {
+	    psTrace(__func__, 3, "Reading pixels from extension %s into chip %d.\n", chip->extname, i);
+	    if (! readExtension(&chip->pixels, &chip->header, fits, chip->extname)) {
+		psError(PS_ERR_IO, false, "Unable to read pixels from extension %s\n", chip->extname);
+		return false;
+	    }
+	    pixels = chip->pixels;
+	    header = chip->header;
+	}
+	// Iterate over the chip
+	psArray *cells = chip->cells;	// Array of cells
+	for (int j = 0; j < cells->n; j++) {
+	    papCell *cell = cells->data[j]; // The cell
+	    psTrace(__func__, 3, "Working on cell %d...\n", j);
+	    if (cell->extname) {
+		psTrace(__func__, 5, "Reading pixels from extension %s into cell %d.\n", cell->extname, j);
+		if (! readExtension(&cell->pixels, &cell->header, fits, cell->extname)) {
+		    psError(PS_ERR_IO, false, "Unable to read pixels from extension %s\n", cell->extname);
+		    return false;
 		}
-	    }
-
-	} else if (strncmp(extType, "CELL", 4) == 0) {
-	    // Extensions are cells; Content contains a chip name and cell type
-	    psMetadata *chipNumbers = psMetadataAlloc(); // Given a chip name, holds the chip number
-	    while (contentItem = psMetadataGetAndIncrement(contentsIter)) {
-		const char *extName = contentItem->name; // The name of the extension
-		psTrace(__func__, 1, "Getting %s....\n", extName);
-
-		if (contentItem->type != PS_META_STR) {
-		    psLogMsg(__func__, PS_LOG_WARN, "Type of content item (%x) is not string: ignored\n",
-			     contentItem->type);
-		} else {
-		    const char *content = contentItem->data.V; // The content of the extension
-		    psList *contents = papSplit(content, ": "); // Split the name from the type
-		    if (contents->size != 2) {
-			psLogMsg(__func__, PS_LOG_WARN, "Unable to read contents of %s: ignored.\n", extName);
-		    } else {
-			const char *chipName = psListGet(contents, 0); // The name of the chip
-			const char *cellType = psListGet(contents, 1); // The type of cell
-			psTrace(__func__, 7, "Extension is cell of type %s, from chip %s\n", cellType,
-				chipName);
-
-			papChip *chip = psMetadataLookupChip(&mdStatus, fpa->chips, chipName); // The chip
-			if (! mdStatus && ! chip) {
-			    chip = papChipAlloc(fpa, chipName);
-			}
-			// The cell
-			psArray *images = NULL;
-			psMetadata *header = NULL;
-			psTrace(__func__, 7, "Reading extension %s\n", extName);
-			readExtension(&images, &header, fits, extName);
-			psTrace(__func__, 7, "Allocating cell %s\n", cellType);
-			papCell *cell = papCellAlloc(chip, cellType, images->n); // The cell
-			cell->pixels = images;
-			cell->header = header;
-			psMetadata *cellData = getCellData(camera, cellType);
-			metadataCopy(cell->values, cellData);
-			psTrace(__func__, 7, "Portioning cell....\n");
-			portionCell(cell, cell->pixels, cell->header);
-			psTrace(__func__, 7, "Done.\n");
-		    }
-		}
-	    }
-
-	} else if (strncmp(extType, "NONE", 4) == 0) {
-	    // No extensions; Content contains metadata, each entry is a chip with its component cells
-	    readExtension(&(fpa->pixels), &(fpa->header), fits, "PHU");
-	    while (contentItem = psMetadataGetAndIncrement(contentsIter)) {
-		const char *chipName = contentItem->name; // The name of the chip
-
-		if (contentItem->type != PS_META_STR) {
-		    psLogMsg(__func__, PS_LOG_WARN, "Type of content item (%x) is not string: ignored\n",
-			     contentItem->type);
-		} else {
-		    const char *content = contentItem->data.V; // The content of the extension
-		    papChip *chip = papChipAlloc(fpa, content); // The chip
-		    psList *cellNames = papSplit(content, ", "); // Split the list of cells
-		    psListIterator *cellNamesIter = psListIteratorAlloc(cellNames, PS_LIST_HEAD, false);
-		    char *cellName = NULL; // Name of the cell
-		    while (cellName = psListGetAndIncrement(cellNamesIter)) {
-			papCell *cell = papCellAlloc(chip, cellName, ((psArray*)fpa->pixels)->n); // The cell
-			psMetadata *cellData = getCellData(camera, cellName);
-			metadataCopy(cell->values, cellData);
-			portionCell(cell, fpa->pixels, fpa->header);
-		    }
-		    psFree(cellNamesIter);
-		}
-	    }
-
-	} else {
-	    psError(PS_ERR_IO, false, "EXTENSIONS in camera definition is not CHIP, CELL or NONE.\n");
-	    psFree(fpa);
-	    return NULL;
-	} // Type of extension
-
-	psFree(contentsIter);
-
-    } else if (strncmp(phuType, "CHIP", 4) == 0) {
-	// The FITS file contains a single chip only
-	papChip *chip = papChipAlloc(fpa, "CHIP"); // The chip
-	
-	if (strncmp(extType, "NONE", 4) == 0) {
-	    // There are no extensions --- only the PHU
-	    readExtension(&(fpa->pixels), &(fpa->header), fits, "PHU");
-
-	    const char *contents = psMetadataLookupString(&mdStatus, camera, "CONTENTS");
-	    if (! mdStatus) {
-		psError(PS_ERR_IO, false, "Unable to determine CONTENTS of camera.\n");
-		psFree(fpa);
-		return NULL;
-	    }
-	    psList *cellNames = papSplit(contents, " ,"); // Names of cells
-	    psListIterator *cellIter = psListIteratorAlloc(cellNames, PS_LIST_HEAD, false); // Iterator
-	    const char *cellName = NULL;
-	    while (cellName = psListGetAndIncrement(cellIter)) {
-		papCell *cell = papCellAlloc(chip, cellName, ((psArray*)fpa->pixels)->n); // The cell
-		psMetadata *cellData = getCellData(camera, cellName);
-		metadataCopy(cell->values, cellData);
-		portionCell(cell, fpa->pixels, fpa->header);
-	    }
-	    psFree(cellIter);
-	} else if (strncmp(extType, "CELL", 4) == 0) {
-	    // Extensions are cells
-	    psMetadata *contents = psMetadataLookupMD(&mdStatus, camera, "CONTENTS"); // The CONTENTS
-	    if (! mdStatus) {
-		psError(PS_ERR_IO, false, "Unable to determine CONTENTS of camera.\n");
-		psFree(fpa);
-		return NULL;
-	    }
-	    
-	    if (strncmp(extType, "CELL", 4) != 0) {
-		psLogMsg(__func__, PS_LOG_WARN, "EXTENSIONS in camera definition is %s, but PHU is CHIP.\n"
-			 "EXTENSIONS assumed to be CELL.\n", extType);
-	    }
-
-	    // Iterate through the contents
-	    psMetadataIterator *contentsIter = psMetadataIteratorAlloc(contents, PS_LIST_HEAD, NULL);
-	    psMetadataItem *contentItem = NULL; // Item from metadata
-	    while (contentItem = psMetadataGetAndIncrement(contentsIter)) {
-		const char *extName = contentItem->name; // The name of the extension
-
-		psMemCheckCorruption(true);
-		
-		psTrace(__func__, 1, "Getting %s....\n", extName);
-
-		// Content is a cell type
-		if (contentItem->type != PS_META_STR) {
-		    psLogMsg(__func__, PS_LOG_WARN,
-			     "CONTENT metadata for extension %s is not of type string, but %x --- ignored\n",
-			     extName, contentItem->type);
-		} else {
-		    const char *cellType = contentItem->data.V; // The type of cell
-		    psTrace(__func__, 2, "Cell type is %s\n", cellType);
-		    psArray *images = NULL;
-		    psMetadata *header = NULL;
-		    readExtension(&images, &header, fits, extName);
-		    papCell *cell = papCellAlloc(chip, extName, images->n); // The cell
-		    cell->pixels = images;
-		    cell->header = header;
-		    psMetadata *cellData = getCellData(camera, cellType);
-		    metadataCopy(cell->values, cellData);
-		    portionCell(cell, cell->pixels, cell->header);
-		}
-	    } // Iterating through contents
-	    psFree(contentsIter);
-
-	} else {
-	    psError(PS_ERR_IO, false, "EXTENSIONS in camera definition is neither CELL or NONE.\n");
-	    psFree(fpa);
-	    return NULL;
-	}
-
-    } else {
-	psError(PS_ERR_IO, true,
-		"The PHU type specified in the camera configuration (%s) is not FPA or CHIP.\n",
-		phuType);
-	psFree(fpa);
-	return NULL;
-    }
-
-    return fpa;
-}
-
-void pmFPAPrint(papFPA *fpa		// FPA to print
-    )
-{
-    // Print out the focal plane
-    psMetadataIterator *fpaIter = psMetadataIteratorAlloc(fpa->chips, PS_LIST_HEAD, NULL); // Iterator for FPA
-    psMetadataItem *fpaItem = NULL;	// Item from metadata
-    psTrace("pmFPARead", 0, "FPA:\n");
-    if (fpa->pixels) {
-	psTrace("pmFPARead", 1, "---> FPA contains pixels.\n");
-    }
-    while (fpaItem = psMetadataGetAndIncrement(fpaIter)) {
-	if (fpaItem->type != PS_META_CHIP) {
-	    psError(PS_ERR_IO, false, "FPA content is not a chip.\n");
-	} else {
-	    psTrace("pmFPARead", 1, "Chip: %s\n", fpaItem->name);
-	    papChip *chip = fpaItem->data.V; // The chip
-	    if (chip->pixels) {
-		psTrace("pmFPARead", 2, "---> Chip contains pixels.\n");
-	    }
-	    // Iterator for chip
-	    psMetadataIterator *chipIter = psMetadataIteratorAlloc(chip->cells, PS_LIST_HEAD, NULL); 
-	    psMetadataItem *chipItem = NULL; // Item from metadata
-	    while (chipItem = psMetadataGetAndIncrement(chipIter)) {
-		if (chipItem->type != PS_META_CELL) {
-		    psError(PS_ERR_IO, false, "Chip content is not a cell.\n");
-		} else {
-		    psTrace("pmFPARead", 2, "Cell: %s\n", chipItem->name);
-		    papCell *cell = chipItem->data.V; // The cell
-		    if (cell->pixels) {
-			psTrace("pmFPARead", 3, "---> Cell contains pixels.\n");
-		    }
-		    // Iterator for cell values
-		    psMetadataIterator *cellIter = psMetadataIteratorAlloc(cell->values, PS_LIST_HEAD, NULL);
-		    psMetadataItem *cellItem = NULL; // Item from metadata
-		    while (cellItem = psMetadataGetAndIncrement(cellIter)) {
-			switch(cellItem->type) {
-			  case PS_META_STR:
-			    psTrace("pmFPARead", 3, "%s: %s\n", cellItem->name, cellItem->data.V);
-			    break;
-			  case PS_META_F32:
-			    psTrace("pmFPARead", 3, "%s: %f\n", cellItem->name, cellItem->data.F32);
-			    break;
-			  case PS_META_S32:
-			    psTrace("pmFPARead", 3, "%s: %d\n", cellItem->name, cellItem->data.S32);
-			    break;
-			  case PS_META_META:
-			    psTrace("pmFPARead", 3, "%s:\n", cellItem->name);
-			    psMetadataPrint(cellItem->data.V, 4);
-			    break;
-			  default:
-			    psError(PS_ERR_IO, false, "Unknown type for cell (%x).\n", cellItem->type);
-			}
-		    } // Iterating through cell
-		    psFree(cellIter);
-
-		    // Iterator for cell
-		    psTrace("pmFPARead", 3, "Readouts:\n");
-		    psArray *readouts = cell->readouts;	// The readouts
-		    for (int i = 0; i < readouts->n; i++) {
-			papReadout *readout = readouts->data[i]; // The readout
-			psImage *image = readout->image; // The image
-			psTrace("pmFPARead", 4, "Image: [%d:%d,%d:%d]\n", image->col0, image->col0 + 
-				image->numCols, image->row0, image->row0 + image->numRows);
-			psList *overscans = readout->overscans;	// The list of overscans
-			psListIterator *overscansIter = psListIteratorAlloc(overscans, PS_LIST_HEAD, false);
-			while (image = psListGetAndIncrement(overscansIter)) {
-			    psTrace("pmFPARead", 4, "Overscan: [%d:%d,%d:%d]\n", image->col0, image->col0 + 
-				image->numCols, image->row0, image->row0 + image->numRows);
-			}
-			psFree(overscansIter);
-		    }
-		}
-	    } // Iterating through chip
-	    psFree(chipIter);
-	}
-    } // Iterating through FPA
-    psFree(fpaIter);
-}
+		pixels = cell->pixels;
+		header = cell->header;
+	    }
+
+	    psTrace(__func__, 5, "Allocating readouts and extracting overscans etc for chip %d cell %d...\n",
+		    i, j);
+	    portionCell(cell, pixels, header);
+	}
+    }
+
+    return true;
+}
