Index: /trunk/psModules/src/camera/pmFPAConstruct.c
===================================================================
--- /trunk/psModules/src/camera/pmFPAConstruct.c	(revision 7468)
+++ /trunk/psModules/src/camera/pmFPAConstruct.c	(revision 7469)
@@ -138,5 +138,5 @@
     fpa->hdu = psMemIncrRefCounter(hdu);
     bool success = true;                // Success of reading concepts
-    if (hdu->header && !pmConceptsReadFPA(fpa, PM_CONCEPT_SOURCE_HEADER, NULL)) {
+    if (hdu->header && !pmConceptsReadFPA(fpa, PM_CONCEPT_SOURCE_HEADER, false, NULL)) {
         psError(PS_ERR_UNKNOWN, false, "Unable to read concepts from header.\n");
         success = false;
@@ -164,5 +164,5 @@
     chip->hdu = psMemIncrRefCounter(hdu);
     bool success = true;                // Success of reading concepts
-    if (hdu->header && !pmConceptsReadChip(chip, PM_CONCEPT_SOURCE_HEADER, true, NULL)) {
+    if (hdu->header && !pmConceptsReadChip(chip, PM_CONCEPT_SOURCE_HEADER, true, false, NULL)) {
         psError(PS_ERR_UNKNOWN, false, "Unable to read concepts from header.\n");
         success = false;
@@ -299,5 +299,5 @@
         }
 
-        if (!pmConceptsReadChip(newChip, PM_CONCEPT_SOURCE_DEFAULTS, false, NULL)) {
+        if (!pmConceptsReadChip(newChip, PM_CONCEPT_SOURCE_DEFAULTS, false, false, NULL)) {
             psError(PS_ERR_UNKNOWN, false, "Unable to read concepts from camera and defaults for chip %s\n",
                     chipName);
@@ -751,5 +751,5 @@
     psFree(contentsIter);
 
-    if (!pmConceptsReadFPA(fpa, PM_CONCEPT_SOURCE_DEFAULTS, NULL)) {
+    if (!pmConceptsReadFPA(fpa, PM_CONCEPT_SOURCE_DEFAULTS, true, NULL)) {
         psError(PS_ERR_UNKNOWN, false, "Unable to read concepts from defaults for FPA %s.  Attempting to "
                 "proceed anyway.\n", currentFPAname);
Index: /trunk/psModules/src/camera/pmFPAHeader.c
===================================================================
--- /trunk/psModules/src/camera/pmFPAHeader.c	(revision 7468)
+++ /trunk/psModules/src/camera/pmFPAHeader.c	(revision 7469)
@@ -6,49 +6,4 @@
 #include "pmConcepts.h"
 #include "pmFPAHeader.h"
-
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// File-static (private) functions
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-// Read concepts for all cells in a chip
-static bool chipConcepts(pmChip *chip   // The chip for which to read the concepts
-                        )
-{
-    assert(chip);
-
-    bool status = true;                 // Status of concept reading
-    status |= pmConceptsReadChip(chip, PM_CONCEPT_SOURCE_HEADER, false, NULL);
-    psArray *cells = chip->cells;       // The cells
-    for (int i = 0; i < cells->n; i++) {
-        pmCell *cell = cells->data[i];  // The cell of interest
-        if (!cell) {
-            continue;
-        }
-        status |= pmConceptsReadCell(cell, PM_CONCEPT_SOURCE_HEADER, false, NULL);
-    }
-
-    return status;
-}
-
-// Read concepts for all chips in an FPA
-static bool fpaConcepts(pmFPA *fpa   // The FPA for which to read the concepts
-                       )
-{
-    assert(fpa);
-
-    bool status = true;                 // Status of concept reading
-    status |= pmConceptsReadFPA(fpa, PM_CONCEPT_SOURCE_HEADER, NULL);
-    psArray *chips = fpa->chips;        // The chips
-    for (int i = 0; i < chips->n; i++) {
-        pmChip *chip = chips->data[i];  // The chip of interest
-        if (!chip) {
-            continue;
-        }
-        status |= chipConcepts(chip);
-    }
-
-    return status;
-}
-
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -90,5 +45,5 @@
     }
 
-    if (!chipConcepts(chip)) {
+    if (!pmConceptsReadChip(chip, PM_CONCEPT_SOURCE_HEADER, true, true, NULL)) {
         psError(PS_ERR_UNKNOWN, false, "Unable to read concepts for chip.\n");
         return false;
@@ -114,5 +69,5 @@
     }
 
-    if (!fpaConcepts(fpa)) {
+    if (!pmConceptsReadFPA(fpa, PM_CONCEPT_SOURCE_HEADER, true, NULL)) {
         psError(PS_ERR_UNKNOWN, false, "Unable to read concepts for FPA.\n");
         return false;
Index: /trunk/psModules/src/camera/pmFPARead.c
===================================================================
--- /trunk/psModules/src/camera/pmFPARead.c	(revision 7468)
+++ /trunk/psModules/src/camera/pmFPARead.c	(revision 7469)
@@ -183,6 +183,9 @@
 
     // Make sure we have the information we need
-    pmConceptsReadCell(cell, PM_CONCEPT_SOURCE_HEADER | PM_CONCEPT_SOURCE_CAMERA | PM_CONCEPT_SOURCE_DEFAULTS,
-                       false, NULL);
+    if (!pmConceptsReadCell(cell, PM_CONCEPT_SOURCE_HEADER | PM_CONCEPT_SOURCE_CAMERA |
+                            PM_CONCEPT_SOURCE_DEFAULTS, true, NULL)) {
+        psError(PS_ERR_IO, false, "Failed to read concepts for cell.\n");
+        return false;
+    }
 
     // Get the trim and bias sections
@@ -322,5 +325,5 @@
     }
 
-    if (!pmConceptsReadCell(cell, PM_CONCEPT_SOURCE_HEADER, false, NULL)) {
+    if (!pmConceptsReadCell(cell, PM_CONCEPT_SOURCE_HEADER, true, NULL)) {
         psError(PS_ERR_UNKNOWN, false, "Failed to read concepts for cell");
         return false;
@@ -354,5 +357,5 @@
     }
 
-    pmCellSetDataStatus (cell, true);
+    pmCellSetDataStatus(cell, true);
     return true;
 }
@@ -374,7 +377,10 @@
     }
     if (success) {
-        pmConceptsReadChip(chip, PM_CONCEPT_SOURCE_HEADER, false, NULL);
+        if (!pmConceptsReadChip(chip, PM_CONCEPT_SOURCE_HEADER, true, true, NULL)) {
+            psError(PS_ERR_IO, false, "Failed to read concepts for FPA.\n");
+            return false;
+        }
         // XXX probably could just use chip->data_exists
-        pmChipSetDataStatus (chip, true);
+        pmChipSetDataStatus(chip, true);
     }
 
@@ -398,5 +404,8 @@
     }
     if (success) {
-        pmConceptsReadFPA(fpa, PM_CONCEPT_SOURCE_HEADER, NULL);
+        if (!pmConceptsReadFPA(fpa, PM_CONCEPT_SOURCE_HEADER, true, NULL)) {
+            psError(PS_ERR_IO, false, "Failed to read concepts for FPA.\n");
+            return false;
+        }
     } else {
         psError(PS_ERR_UNKNOWN, false, "Unable to read any chips in FPA");
Index: /trunk/psModules/src/camera/pmFPAWrite.c
===================================================================
--- /trunk/psModules/src/camera/pmFPAWrite.c	(revision 7468)
+++ /trunk/psModules/src/camera/pmFPAWrite.c	(revision 7469)
@@ -136,5 +136,5 @@
             (pixels && (hdu->images || (!hdu->images && pmHDUGenerateForChip(chip) && hdu->images)))) { // Data
         success &= pmConceptsWriteChip(chip, PM_CONCEPT_SOURCE_HEADER | PM_CONCEPT_SOURCE_CAMERA |
-                                       PM_CONCEPT_SOURCE_DEFAULTS, false, NULL);
+                                       PM_CONCEPT_SOURCE_DEFAULTS, false, true, NULL);
         success &= pmHDUWrite(hdu, fits);
     }
@@ -177,5 +177,5 @@
             (pixels && (hdu->images || (!hdu->images && pmHDUGenerateForFPA(fpa) && hdu->images)))) { // Data
         success &= pmConceptsWriteFPA(fpa, PM_CONCEPT_SOURCE_HEADER | PM_CONCEPT_SOURCE_CAMERA |
-                                      PM_CONCEPT_SOURCE_DEFAULTS, NULL);
+                                      PM_CONCEPT_SOURCE_DEFAULTS, true, NULL);
         success &= pmHDUWrite(hdu, fits);
     }
Index: /trunk/psModules/src/concepts/pmConcepts.c
===================================================================
--- /trunk/psModules/src/concepts/pmConcepts.c	(revision 7468)
+++ /trunk/psModules/src/concepts/pmConcepts.c	(revision 7469)
@@ -189,4 +189,6 @@
     }
 
+    psTrace(__func__, 3, "Writing concepts (%x %x %x): %x\n", fpa, chip, cell, source);
+
     if (source & PM_CONCEPT_SOURCE_CAMERA) {
         pmConceptsWriteToCamera(*specs, cell, concepts);
@@ -218,10 +220,22 @@
 bool pmConceptsReadFPA(pmFPA *fpa,      // FPA for which to read concepts
                        pmConceptSource source, // The source of the concepts to read
-                       psDB *db         // Database handle
+                       bool propagateDown, // Propagate to lower levels?
+                       psDB *db        // Database handle
                       )
 {
     PS_ASSERT_PTR_NON_NULL(fpa, false);
     psTrace("psModule.concepts", 5, "Reading FPA concepts: %x %x\n", conceptsFPA, fpa->concepts);
-    return conceptsRead(&conceptsFPA, fpa, NULL, NULL, &fpa->conceptsRead, source, db, fpa->concepts);
+    bool success = conceptsRead(&conceptsFPA, fpa, NULL, NULL, &fpa->conceptsRead, source, db, fpa->concepts);
+    if (propagateDown) {
+        psArray *chips = fpa->chips;    // Array of chips
+        for (long i = 0; i < chips->n; i++) {
+            pmChip *chip = chips->data[i]; // Chip of interest
+            if (chip && !chip->hdu) {
+                success |= pmConceptsReadChip(chip, source, false, true, db);
+            }
+        }
+    }
+
+    return success;
 }
 
@@ -229,4 +243,5 @@
 bool pmConceptsWriteFPA(pmFPA *fpa,     // FPA for which to write concepts
                         pmConceptSource source, // The source of the concepts to read
+                        bool propagateDown, // Propagate to lower levels?
                         psDB *db        // Database handle
                        )
@@ -234,5 +249,15 @@
     PS_ASSERT_PTR_NON_NULL(fpa, false);
     psTrace("psModule.concepts", 5, "Writing FPA concepts: %x %x\n", conceptsFPA, fpa->concepts);
-    return conceptsWrite(&conceptsFPA, fpa, NULL, NULL, source, db, fpa->concepts);
+    bool success = conceptsWrite(&conceptsFPA, fpa, NULL, NULL, source, db, fpa->concepts);
+    if (propagateDown) {
+        psArray *chips = fpa->chips;        // Array of chips
+        for (long i = 0; i < chips->n; i++) {
+            pmChip *chip = chips->data[i];  // Chip of interest
+            if (chip && !chip->hdu) {
+                success |= pmConceptsWriteChip(chip, source, false, true, db);
+            }
+        }
+    }
+    return success;
 }
 
@@ -249,5 +274,6 @@
 bool pmConceptsReadChip(pmChip *chip,   // Chip for which to read concepts
                         pmConceptSource source, // The source of the concepts to read
-                        bool propagate, // Propagate to higher levels as well?
+                        bool propagateUp, // Propagate to higher levels?
+                        bool propagateDown, // Propagate to lower levels?
                         psDB *db        // Database handle
                        )
@@ -256,8 +282,19 @@
     psTrace("psModule.concepts", 5, "Reading chip concepts: %x %x\n", conceptsChip, chip->concepts);
     pmFPA *fpa = chip->parent;          // FPA to which the chip belongs
-    return conceptsRead(&conceptsChip, fpa, chip, NULL, &chip->conceptsRead, source, db, chip->concepts) &&
-           ((propagate && conceptsRead(&conceptsFPA, fpa, chip, NULL, &fpa->conceptsRead, source, db,
-                                       fpa->concepts)) ||
-            !propagate);
+    bool success = conceptsRead(&conceptsChip, fpa, chip, NULL, &chip->conceptsRead, source, db,
+                                chip->concepts);
+    if (propagateUp && !fpa->hdu) {
+        success |= conceptsRead(&conceptsFPA, fpa, chip, NULL, &fpa->conceptsRead, source, db, fpa->concepts);
+    }
+    if (propagateDown) {
+        psArray *cells = chip->cells;        // Array of cells
+        for (long i = 0; i < cells->n; i++) {
+            pmCell *cell = cells->data[i];  // Cell of interest
+            if (cell && !cell->hdu) {
+                success |= pmConceptsReadCell(cell, source, false, db);
+            }
+        }
+    }
+    return success;
 }
 
@@ -265,5 +302,6 @@
 bool pmConceptsWriteChip(pmChip *chip,  // Chip for which to write concepts
                          pmConceptSource source, // The source of the concepts to read
-                         bool propagate,// Propagate to higher levels as well?
+                         bool propagateUp, // Propagate to higher levels?
+                         bool propagateDown, // Propagate to lower levels?
                          psDB *db        // Database handle
                         )
@@ -272,7 +310,18 @@
     psTrace("psModule.concepts", 5, "Writing chip concepts: %x %x\n", conceptsChip, chip->concepts);
     pmFPA *fpa = chip->parent;          // FPA to which the chip belongs
-    return conceptsWrite(&conceptsChip, fpa, chip, NULL, source, db, chip->concepts) &&
-           ((propagate && conceptsWrite(&conceptsFPA, fpa, chip, NULL, source, db, fpa->concepts)) ||
-            !propagate);
+    bool success = conceptsWrite(&conceptsChip, fpa, chip, NULL, source, db, chip->concepts);
+    if (propagateUp && !fpa->hdu) {
+        success |= conceptsWrite(&conceptsFPA, fpa, chip, NULL, source, db, fpa->concepts);
+    }
+    if (propagateDown) {
+        psArray *cells = chip->cells;        // Array of cells
+        for (long i = 0; i < cells->n; i++) {
+            pmCell *cell = cells->data[i];  // Cell of interest
+            if (cell && !cell->hdu) {
+                success |= pmConceptsWriteCell(cell, source, false, db);
+            }
+        }
+    }
+    return success;
 }
 
@@ -289,5 +338,5 @@
 bool pmConceptsReadCell(pmCell *cell,   // Cell for which to read concepts
                         pmConceptSource source, // The source of the concepts to read
-                        bool propagate,// Propagate to higher levels as well?
+                        bool propagateUp, // Propagate to higher levels?
                         psDB *db        // Database handle
                        )
@@ -298,17 +347,18 @@
     pmFPA *fpa = chip->parent;          // FPA to which the chip belongs
 
-    bool cellSuccess = conceptsRead(&conceptsCell, fpa, chip, cell, &cell->conceptsRead, source, db, cell->concepts);
-
-    bool chipSuccess = true;
-    if (propagate) {
-        chipSuccess = conceptsRead(&conceptsChip, fpa, chip, cell, &chip->conceptsRead, source, db, chip->concepts);
-    }
-
-    bool fpaSuccess = true;
-    if (propagate) {
-        fpaSuccess = conceptsRead(&conceptsFPA, fpa, chip, cell, &fpa->conceptsRead, source, db, fpa->concepts);
-    }
-
-    return (cellSuccess && chipSuccess && fpaSuccess);
+    bool success = conceptsRead(&conceptsCell, fpa, chip, cell, &cell->conceptsRead, source, db,
+                                cell->concepts);
+    if (propagateUp) {
+        if (!chip->hdu) {
+            success |= conceptsRead(&conceptsChip, fpa, chip, cell, &chip->conceptsRead, source, db,
+                                    chip->concepts);
+            if (!fpa->hdu) {
+                success |= conceptsRead(&conceptsFPA, fpa, chip, cell, &fpa->conceptsRead, source, db,
+                                        fpa->concepts);
+            }
+        }
+    }
+
+    return success;
 }
 
@@ -316,5 +366,5 @@
 bool pmConceptsWriteCell(pmCell *cell,  // FPA for which to write concepts
                          pmConceptSource source, // The source of the concepts to read
-                         bool propagate,// Propagate to higher levels as well?
+                         bool propagateUp, // Propagate to higher levels?
                          psDB *db       // Database handle
                         )
@@ -324,7 +374,16 @@
     pmChip *chip = cell->parent;        // Chip to which the cell belongs
     pmFPA *fpa = chip->parent;          // FPA to which the chip belongs
-    return conceptsWrite(&conceptsCell, fpa, chip, cell, source, db, cell->concepts) &&
-           ((propagate && conceptsWrite(&conceptsChip, fpa, chip, cell, source, db, chip->concepts) &&
-             conceptsWrite(&conceptsFPA, fpa, chip, cell, source, db, fpa->concepts)) || !propagate);
+
+    bool success = conceptsWrite(&conceptsCell, fpa, chip, cell, source, db, cell->concepts);
+    if (propagateUp) {
+        if (!chip->hdu) {
+            success |= conceptsWrite(&conceptsChip, fpa, chip, cell, source, db, chip->concepts);
+            if (!fpa->hdu) {
+                success |= conceptsWrite(&conceptsFPA, fpa, chip, cell, source, db, fpa->concepts);
+            }
+        }
+    }
+
+    return success;
 }
 
Index: /trunk/psModules/src/concepts/pmConcepts.h
===================================================================
--- /trunk/psModules/src/concepts/pmConcepts.h	(revision 7468)
+++ /trunk/psModules/src/concepts/pmConcepts.h	(revision 7469)
@@ -47,8 +47,10 @@
 bool pmConceptsReadFPA(pmFPA *fpa,      // FPA for which to read concepts
                        pmConceptSource source, // Source for concepts
+                       bool propagateDown, // Propagate to lower levels?
                        psDB *db         // Database handle
                       );
 bool pmConceptsWriteFPA(pmFPA *fpa,     // FPA for which to write concepts
                         pmConceptSource source, // Source for concepts
+                        bool propagateDown, // Propagate to lower levels?
                         psDB *db        // Database handle
                        );
@@ -57,10 +59,12 @@
 bool pmConceptsReadChip(pmChip *chip,   // Chip for which to read concepts
                         pmConceptSource source, // Source for concepts
-                        bool propagate, // Propagate to higher levels as well?
+                        bool propagateUp, // Propagate to higher levels?
+                        bool propagateDown, // Propagate to lower levels?
                         psDB *db        // Database handle
                        );
 bool pmConceptsWriteChip(pmChip *chip,  // Chip for which to write concepts
                          pmConceptSource source, // Source for concepts
-                         bool propagate,// Propagate to higher levels as well?
+                         bool propagateUp,// Propagate to higher levels?
+                         bool propagateDown, // Propagate to lower levels?
                          psDB *db       // Database handle
                         );
@@ -69,10 +73,10 @@
 bool pmConceptsReadCell(pmCell *cell,   // Cell for which to read concepts
                         pmConceptSource source, // Source for concepts
-                        bool propagate, // Propagate to higher levels as well?
+                        bool propagateUp, // Propagate to higher levels?
                         psDB *db        // Database handle
                        );
 bool pmConceptsWriteCell(pmCell *cell,  // FPA for which to write concepts
                          pmConceptSource source, // Source for concepts
-                         bool propagate,// Propagate to higher levels as well?
+                         bool propagateUp, // Propagate to higher levels?
                          psDB *db       // Database handle
                         );
Index: /trunk/psModules/src/concepts/pmConceptsWrite.c
===================================================================
--- /trunk/psModules/src/concepts/pmConceptsWrite.c	(revision 7468)
+++ /trunk/psModules/src/concepts/pmConceptsWrite.c	(revision 7469)
@@ -141,17 +141,22 @@
     switch (item->type) {
     case PS_DATA_STRING:
+        psTrace(__func__, 9, "Writing header %s: %s\n", keyword, item->data.V);
         return psMetadataAddStr(hdu->header, PS_LIST_TAIL, keyword, PS_META_REPLACE, item->comment,
                                 item->data.V);
     case PS_DATA_S32:
+        psTrace(__func__, 9, "Writing header %s: %d\n", keyword, item->data.S32);
         return psMetadataAddS32(hdu->header, PS_LIST_TAIL, keyword, PS_META_REPLACE, item->comment,
                                 item->data.S32);
     case PS_DATA_F32:
+        psTrace(__func__, 9, "Writing header %s: %f\n", keyword, item->data.F32);
         return psMetadataAddF32(hdu->header, PS_LIST_TAIL, keyword, PS_META_REPLACE, item->comment,
                                 item->data.F32);
     case PS_DATA_F64:
+        psTrace(__func__, 9, "Writing header %s: %f\n", keyword, item->data.F64);
         return psMetadataAddF64(hdu->header, PS_LIST_TAIL, keyword, PS_META_REPLACE, item->comment,
                                 item->data.F64);
     case PS_DATA_REGION: {
             psString region = psRegionToString(*(psRegion*)item->data.V);
+            psTrace(__func__, 9, "Writing header %s: %s\n", keyword, region);
             bool result = psMetadataAddStr(hdu->header, PS_LIST_TAIL, keyword, PS_META_REPLACE, item->comment,
                                            region);
@@ -378,4 +383,5 @@
                 continue;
             }
+            psTrace(__func__, 3, "Writing %s to header %s\n", name, headerItem->data.V);
             psMetadataItem *conceptItem = psMetadataLookup(concepts, name); // The item from the concepts
             psMetadataItem *formatted = conceptFormat(spec, conceptItem, cameraFormat, fpa, chip, cell);
