Index: trunk/archive/scripts/src/phase2/pmFPA.c
===================================================================
--- trunk/archive/scripts/src/phase2/pmFPA.c	(revision 4820)
+++ trunk/archive/scripts/src/phase2/pmFPA.c	(revision 5104)
@@ -1,4 +1,5 @@
 #include <stdio.h>
 #include <string.h>
+#include <assert.h>
 #include "pslib.h"
 #include "psAdditionals.h"
@@ -6,15 +7,31 @@
 #include "pmFPA.h"
 
-
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
 // Allocators
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
-pmFPA *pmFPAAlloc(const psMetadata *camera, // Camera configuration
-		  psDB *db		// Database
+p_pmHDU *p_pmHDUAlloc(const char *extname)
+{
+    p_pmHDU *hdu = psAlloc(sizeof(p_pmHDU));
+    psMemSetDeallocator(hdu, (psFreeFunc)p_pmHDUFree);
+
+    hdu->extname = extname;
+    hdu->pixels = NULL;
+    hdu->header = NULL;
+
+    return hdu;
+}
+
+void p_pmHDUFree(p_pmHDU *hdu)
+{
+    psFree(hdu->pixels);
+    psFree(hdu->header);
+}
+
+pmFPA *pmFPAAlloc(const psMetadata *camera // Camera configuration
     )
 {
     pmFPA *fpa = psAlloc(sizeof(pmFPA));// The FPA
-    psMemSetDeallocator(fpa, (psFreeFcn)p_pmFPAFree);
+    psMemSetDeallocator(fpa, (psFreeFunc)p_pmFPAFree);
 
     // Fill in the components
@@ -23,12 +40,9 @@
     fpa->projection = NULL;
 
-    fpa->values = psMetadataAlloc();
-//    fpa->camera = psMemIncrRefCounter((psPtr)camera);
-    fpa->db = db;
+    fpa->concepts = psMetadataAlloc();
+    fpa->camera = psMemIncrRefCounter((psPtr)camera);
     fpa->chips = psArrayAlloc(0);
 
-    fpa->extname = NULL;
-    fpa->pixels = NULL;
-    fpa->header = NULL;
+    fpa->private = NULL;
 
     return fpa;
@@ -41,11 +55,9 @@
     psFree(fpa->projection);
 
-    psFree(fpa->values);
+    psFree(fpa->concepts);
     psFree((psPtr)fpa->camera);
-    psFree(fpa->db);
     psFree(fpa->chips);
 
-    psFree(fpa->pixels);
-    psFree(fpa->header);
+    psFree(fpa->private);
 }
 
@@ -55,5 +67,5 @@
 {
     pmChip *chip = psAlloc(sizeof(pmChip)); // The chip
-    psMemSetDeallocator(chip, (psFreeFcn)p_pmChipFree);
+    psMemSetDeallocator(chip, (psFreeFunc)p_pmChipFree);
 
     // Push onto the array of chips
@@ -67,13 +79,14 @@
     chip->fromFPA = NULL;
 
-    chip->values = psMetadataAlloc();
-//    chip->parent = psMemIncrRefCounter(fpa);
+    chip->concepts = psMetadataAlloc();
     chip->cells = psArrayAlloc(0);
-
-    chip->extname = NULL;
-    chip->pixels = NULL;
-    chip->header = NULL;
-
-    psMetadataAddStr(chip->values, PS_LIST_HEAD, "CHIP.NAME", "Chip name added at pmChipAlloc", name);
+    chip->parent = fpa;			// We don't increment the reference counter on this --- it's a
+					// "hidden" link.  If we increment the reference counter, we get stuck
+					// in a circle.
+    chip->valid = true;    
+
+    chip->private = NULL;
+
+    psMetadataAddStr(chip->concepts, PS_LIST_HEAD, "CHIP.NAME", 0, "Chip name added at pmChipAlloc", name);
 
     return chip;
@@ -85,19 +98,20 @@
     psFree(chip->fromFPA);
 
-    psFree(chip->values);
+    psFree(chip->concepts);
     psFree(chip->cells);
-//    psFree(chip->parent);
-
-    psFree(chip->pixels);
-    psFree(chip->header);
+
+    psFree(chip->private);
+
+    // We don't free the parent member, since that would generate a circular call.  We don't increment the
+    // reference counter when we add it, anyway, so that's OK.
 }
 
 pmCell *pmCellAlloc(pmChip *chip,	// Chip to which the cell belongs
-		    psMetadata *values,	// Initial values for concepts
+		    psMetadata *cameraData, // Camera data
 		    psString name	// Name of cell
     )
 {
     pmCell *cell = psAlloc(sizeof(pmCell)); // The cell
-    psMemSetDeallocator(cell, (psFreeFcn)p_pmCellFree);
+    psMemSetDeallocator(cell, (psFreeFunc)p_pmCellFree);
 
     // Push onto the array of chips
@@ -114,13 +128,15 @@
     cell->toSky = NULL;
 
-    cell->values = psMemIncrRefCounter(values);
+    cell->concepts = psMetadataAlloc();
+    psMetadataAddStr(cell->concepts, PS_LIST_HEAD, "CELL.NAME", 0, "Cell name added at pmCellAlloc", name);
+    cell->camera = psMemIncrRefCounter(cameraData);
+
     cell->readouts = psArrayAlloc(0);
-//    cell->parent = psMemIncrRefCounter(chip);
-
-    cell->extname = NULL;
-    cell->pixels = NULL;
-    cell->header = NULL;
-
-    psMetadataAddStr(cell->values, PS_LIST_HEAD, "CELL.NAME", "Cell name added at pmCellAlloc", name);
+    cell->parent = chip;		// We don't increment the reference counter on this --- it's a
+					// "hidden" link.  If we increment the reference counter, we get stuck
+					// in a circle.
+    cell->valid = true;
+
+    cell->private = NULL;
 
     return cell;
@@ -135,14 +151,15 @@
     psFree(cell->toSky);
 
-    psFree(cell->values);
+    psFree(cell->concepts);
+    psFree(cell->camera);
     psFree(cell->readouts);
-//    psFree(cell->parent);
-
-    psFree(cell->pixels);
-    psFree(cell->header);
+
+    psFree(cell->private);
+
+    // We don't free the parent member, since that would generate a circular call.  We don't increment the
+    // reference counter when we add it, anyway, so that's OK.
 }
 
 pmReadout *pmReadoutAlloc(pmCell *cell, // Cell to which the readout belongs
-			  int readoutNum, // Number of the readout
 			  psImage *image, // The pixels
 			  psList *overscans, // The overscan images
@@ -151,17 +168,13 @@
 {
     pmReadout *readout = psAlloc(sizeof(pmReadout));
-    psMemSetDeallocator(readout, (psFreeFcn)p_pmReadoutFree);
-    psArray *readouts = cell->readouts;
-    if (readoutNum >= readouts->nalloc) {
-	readouts = psArrayRealloc(readouts, readoutNum);
-	cell->readouts = readouts;
-    }
-    readouts->data[readoutNum] = readout;
+    psMemSetDeallocator(readout, (psFreeFunc)p_pmReadoutFree);
+    cell->readouts = psArrayAdd(cell->readouts, 0, readout);
     
     // Set the components
-    readout->image = image;
-    readout->overscans = overscans;
+    readout->image = psMemIncrRefCounter(image);
+    readout->mask = NULL;
+    readout->overscans = psMemIncrRefCounter(overscans);
     
-    readout->values = psMetadataAlloc();
+    //readout->concepts = psMetadataAlloc();
     
     *(int*)&readout->col0 = col0;
@@ -178,5 +191,70 @@
 {
     psFree(readout->image);
+    psFree(readout->mask); 
     psFree(readout->overscans);
-    psFree(readout->values);
-}
+    //psFree(readout->concepts);
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Select and Exclude chips
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+bool pmFPASelectChip(pmFPA *fpa, int chipNum)
+{
+    assert(fpa);
+
+    if (chipNum < 0 || chipNum > fpa->chips->n) {
+	return false;
+    }
+    psArray *chips = fpa->chips;	// Component chips
+    for (int i = 0; i < chips->n; i++) {
+	pmChip *chip = chips->data[i];	// The chip of interest
+	if (i == chipNum) {
+	    psTrace(__func__, 5, "Marking chip %d valid.\n", i);
+	    chip->valid = true;
+	    psArray *cells = chip->cells; // Component cells
+	    for (int j = 0; j < cells->n; j++) {
+		pmCell *cell = cells->data[j]; // Cell of interest
+		cell->valid = true;
+	    }
+	} else {
+	    psTrace(__func__, 5, "Marking chip %d invalid.\n", i);
+	    chip->valid = false;
+	    psArray *cells = chip->cells; // Component cells
+	    for (int j = 0; j < cells->n; j++) {
+		pmCell *cell = cells->data[j]; // Cell of interest
+		cell->valid = false;
+	    }
+	}
+    }
+    return true;
+}
+
+int pmFPAExcludeChip(pmFPA *fpa, int chipNum)
+{
+    assert(fpa);
+
+    if (chipNum < 0 || chipNum > fpa->chips->n) {
+	psLogMsg(__func__, PS_LOG_WARN, "Invalid chip number: %d\n", chipNum);
+    }
+    int numValid = 0;			// Number of valid chips
+    psArray *chips = fpa->chips;	// Component chips
+    for (int i = 0; i < chips->n; i++) {
+	pmChip *chip = chips->data[i];	// The chip of interest
+	if (i == chipNum) {
+	    psTrace(__func__, 5, "Marking chip %d invalid.\n", i);
+	    chip->valid = false;
+	    psArray *cells = chip->cells; // Component cells
+	    for (int j = 0; j < cells->n; j++) {
+		pmCell *cell = cells->data[j]; // Cell of interest
+		cell->valid = false;
+	    }
+	} else if (chip->valid) {
+	    numValid++;
+	}
+    }
+
+    psTrace(__func__, 5, "%d valid chips in fpa.\n", numValid);
+    return numValid;
+}
