Index: /trunk/psModules/src/camera/pmFPAConstruct.c
===================================================================
--- /trunk/psModules/src/camera/pmFPAConstruct.c	(revision 7716)
+++ /trunk/psModules/src/camera/pmFPAConstruct.c	(revision 7717)
@@ -522,4 +522,5 @@
     // Case 1: PHU=FPA and EXTENSIONS=NONE.  We need to parse the single list of chip:cell:cellType entries.
     if (strcasecmp(phuType, "FPA") == 0 && strcasecmp(extType, "NONE") == 0) {
+        phdu->blankPHU = false;
         const char *contents = psMetadataLookupStr(&mdok, format, "CONTENTS"); // The contents of the file
         if (!mdok || !contents || strlen(contents) == 0) {
@@ -529,5 +530,4 @@
             return NULL;
         }
-
         if (processContents(fpa, NULL, NULL, phdu, PM_FPA_LEVEL_FPA, contents, format) < 0) {
             psError(PS_ERR_IO, false, "Error setting CONTENTS");
@@ -563,4 +563,5 @@
     // chip/cell directly from that.
     if (strcasecmp(extType, "NONE") == 0) {
+        phdu->blankPHU = false;
         pmChip *chip = NULL;        // The chip of interest
         pmCell *cell = NULL;        // The cell of interest
@@ -650,4 +651,5 @@
     // Case 3: EXTENSIONS=CHIP or EXTENSIONS=CELL.  We have extensions that we iterate through.  The CONTENTS
     // is a list of extensions.
+    phdu->blankPHU = true;
     pmChip *chip = NULL;                // The chip of interest
     pmCell *cell = NULL;                // The cell of interest
Index: /trunk/psModules/src/camera/pmFPACopy.c
===================================================================
--- /trunk/psModules/src/camera/pmFPACopy.c	(revision 7716)
+++ /trunk/psModules/src/camera/pmFPACopy.c	(revision 7717)
@@ -32,18 +32,18 @@
 }
 
-static pmHDU *findPHU(const pmCell *cell// The cell for which to find the PHU
-                     )
+static pmHDU *findBlankPHU(const pmCell *cell// The cell for which to find the PHU
+                          )
 {
     assert(cell);
 
-    if (cell->hdu && cell->hdu->phu) {
+    if (cell->hdu && cell->hdu->blankPHU) {
         return cell->hdu;
     }
     pmChip *chip = cell->parent;        // The parent chip
-    if (chip->hdu && chip->hdu->phu) {
+    if (chip->hdu && chip->hdu->blankPHU) {
         return chip->hdu;
     }
     pmFPA *fpa = chip->parent;  // The parent FPA
-    if (fpa->hdu && fpa->hdu->phu) {
+    if (fpa->hdu && fpa->hdu->blankPHU) {
         return fpa->hdu;
     }
@@ -261,7 +261,7 @@
     }
     // Copy the PHU over as well, if required
-    pmHDU *targetPHU = findPHU(target); // The target PHU
+    pmHDU *targetPHU = findBlankPHU(target); // The target PHU
     if (targetPHU && targetPHU != targetHDU && !targetPHU->header) {
-        pmHDU *sourcePHU = findPHU(source); // The source PHU
+        pmHDU *sourcePHU = findBlankPHU(source); // The source PHU
         targetPHU->header = psMetadataCopy(targetPHU->header, sourcePHU->header);
     }
Index: /trunk/psModules/src/camera/pmFPAWrite.c
===================================================================
--- /trunk/psModules/src/camera/pmFPAWrite.c	(revision 7716)
+++ /trunk/psModules/src/camera/pmFPAWrite.c	(revision 7717)
@@ -1,5 +1,5 @@
 #include <stdio.h>
 #include <strings.h>
-#include "pslib.h"
+#include <pslib.h>
 
 #include "pmFPA.h"
@@ -73,7 +73,6 @@
 
     // We can simply update an existing HDU
-    if (((hdu->phu || strcasecmp(hdu->extname, "PHU") == 0) && !psFitsMoveExtNum(fits, 0, false)) ||
-            !psFitsMoveExtName(fits, hdu->extname)) {
-        psError(PS_ERR_IO, false, "Unable to move to extension %s\n", hdu->extname);
+    if (hdu->blankPHU && !psFitsMoveExtNum(fits, 0, false)) {
+        psError(PS_ERR_IO, false, "Unable to move to PHU\n");
         return false;
     }
@@ -87,5 +86,5 @@
                  psFits *fits,          // FITS file to which to write
                  psDB *db,              // Database handle for "concepts" update
-                 bool pixels            // Write the pixels, or only the PHU header?
+                 bool blank             // Write a blank PHU?
                 )
 {
@@ -98,20 +97,31 @@
     }
 
-    bool success = true;                // Success of writing
-    if ((!pixels && hdu->phu && !hdu->images) || // Data-less PHU
-            (pixels && (hdu->images || (!hdu->images && pmHDUGenerateForCell(cell) && hdu->images)))) { // Data
-        success &= pmConceptsWriteCell(cell, PM_CONCEPT_SOURCE_HEADER | PM_CONCEPT_SOURCE_CAMERA |
-                                       PM_CONCEPT_SOURCE_DEFAULTS, false, NULL);
-        success &= pmHDUWrite(hdu, fits);
-    }
-
-    if (!success) {
-        psError(PS_ERR_IO, false, "Unable to write HDU for Chip.\n");
-        return false;
-    }
-
+    // Generate the HDU if needed --- this is required after a pmFPACopy, or similar, which does not
+    // generate the HDU, but only copies the structure.
+    if (!hdu->blankPHU && !hdu->images) {
+        if (!pmHDUGenerateForCell(cell) || !hdu->images) {
+            psAbort(__func__, "Unable to generate HDU for cell --- likely programming error.\n");
+        }
+    }
+
+    // We only write out a blank PHU if it's specifically requested.
+    bool writeBlank = blank && hdu->blankPHU && !hdu->images; // Write a blank PHU?
+    bool writeImage = !hdu->blankPHU && hdu->images; // Write an image?
+
+    if (writeBlank || writeImage) {
+        pmConceptSource source = PM_CONCEPT_SOURCE_HEADER | PM_CONCEPT_SOURCE_CAMERA |
+                                 PM_CONCEPT_SOURCE_DEFAULTS;
+        if (!pmConceptsWriteCell(cell, source, false, NULL)) {
+            psError(PS_ERR_IO, false, "Unable to write concepts for cell.\n");
+            return false;
+        }
+        if (!pmHDUWrite(hdu, fits)) {
+            psError(PS_ERR_IO, false, "Unable to write HDU for cell.\n");
+            return false;
+        }
+    }
     // No lower levels to which to recurse
 
-    return success;
+    return true;
 }
 
@@ -120,5 +130,5 @@
                  psFits *fits,          // FITS file to which to write
                  psDB *db,              // Database handle for "concepts" update
-                 bool pixels,           // Write the pixels, or only the PHU header?
+                 bool blank,            // Write a blank PHU?
                  bool recurse           // Recurse to lower levels?
                 )
@@ -129,43 +139,38 @@
     pmHDU *hdu = chip->hdu;             // The HDU
 
-    // XXXX this makes no sense to me at all:
-    // an image made up of only cells would not have
-    // any entries at this level, and could not be written out!!!
-
-    // if we have data at this level, try to write it out
+    // If we have data at this level, try to write it out
     if (hdu) {
-        // generate the HDU if needed
-        if (pixels && !hdu->images) {
-            if (!pmHDUGenerateForChip(chip))
-                psAbort ("pmFPAWrite", "error generating HDU");
-            if (!hdu->images)
-                psAbort ("pmChipWrite", "programming error: failure generating HDU");
-        }
-
-        // chip->hdu represents a blank data segment
-        bool blankSegment = !pixels && hdu->phu && !hdu->images;
-
-        // chip->hdu represents an image data segment
-        bool imageSegment = pixels && hdu->images;
-
-        if (blankSegment || imageSegment) {
-            pmConceptSource source = PM_CONCEPT_SOURCE_HEADER | PM_CONCEPT_SOURCE_CAMERA | PM_CONCEPT_SOURCE_DEFAULTS;
+        // Generate the HDU if needed --- this is required after a pmFPACopy, or similar, which does not
+        // generate the HDU, but only copies the structure.
+        if (!blank && !hdu->blankPHU && !hdu->images) {
+            if (!pmHDUGenerateForChip(chip) || !hdu->images) {
+                psAbort (__func__, "Unable to generate HDU for chip --- likely programming error.\n");
+            }
+        }
+
+        // We only write out a blank PHU if it's specifically requested.
+        bool writeBlank = blank && hdu->blankPHU && !hdu->images; // Write a blank HDU?
+        bool writeImage = !hdu->blankPHU && hdu->images; // Write an image?
+
+        if (writeBlank || writeImage) {
+            pmConceptSource source = PM_CONCEPT_SOURCE_HEADER | PM_CONCEPT_SOURCE_CAMERA |
+                                     PM_CONCEPT_SOURCE_DEFAULTS;
             if (!pmConceptsWriteChip(chip, source, false, true, NULL)) {
-                psError(PS_ERR_IO, false, "Unable to write Concepts for Chip.\n");
+                psError(PS_ERR_IO, false, "Unable to write concepts for chip.\n");
                 return false;
             }
             if (!pmHDUWrite(hdu, fits)) {
-                psError(PS_ERR_IO, false, "Unable to write HDU for Chip.\n");
-                return false;
-            }
-        }
-    }
-
-    // XXX are we allowed to recurse if we have already written data at this level?
+                psError(PS_ERR_IO, false, "Unable to write HDU for chip.\n");
+                return false;
+            }
+        }
+    }
+
+    // Recurse to lower level if specifically requested.
     if (recurse) {
         psArray *cells = chip->cells;       // Array of cells
         for (int i = 0; i < cells->n; i++) {
             pmCell *cell = cells->data[i];  // The cell of interest
-            if (!pmCellWrite(cell, fits, db, pixels)) {
+            if (!pmCellWrite(cell, fits, db, blank)) {
                 psError(PS_ERR_IO, false, "Unable to write Chip.\n");
                 return false;
@@ -182,5 +187,5 @@
                 psFits *fits,           // FITS file to which to write
                 psDB *db,               // Database handle for "concepts" update
-                bool pixels,            // Write the pixels, or only the PHU header?
+                bool blank,             // Write a blank PHU?
                 bool recurse            // Recurse to lower levels?
                )
@@ -191,33 +196,26 @@
     pmHDU *hdu = fpa->hdu;              // The HDU
 
-    // XXXX this makes no sense to me at all:
-    // an image made up of only chips or cells would not have
-    // any entries at this level, and could not be written out!!!
-
-    // if we have data at this level, try to write it out
+    // If we have data at this level, try to write it out
     if (hdu) {
-
-        // XXXXXXXXX this was extremely unclear.  the conditions MUST be written more explicitly
-        // so someone else has a chance to understand it without massive reverse engineering!!!!
-
-        // generate the HDU if needed
-        if (pixels && !hdu->images) {
-            if (!pmHDUGenerateForFPA(fpa))
-                psAbort ("pmFPAWrite", "error generating HDU");
-            if (!hdu->images)
-                psAbort ("pmFPAWrite", "programming error: failure generating HDU");
-        }
-
-        // fpa->hdu represents a blank data segment
-        bool blankSegment = !pixels && hdu->phu && !hdu->images;
-
-        // fpa->hdu represents an image data segment
-        bool imageSegment = pixels && hdu->images;
-
-        // if neither of these conditions is true, we probably need to recurse down to the next level and try again
-        if (blankSegment || imageSegment) {
-            pmConceptSource source = PM_CONCEPT_SOURCE_HEADER | PM_CONCEPT_SOURCE_CAMERA | PM_CONCEPT_SOURCE_DEFAULTS;
+        // Generate the HDU if needed --- this is required after a pmFPACopy, or similar, which does not
+        // generate the HDU, but only copies the structure.
+        if (!blank && !hdu->blankPHU && !hdu->images) {
+            if (!pmHDUGenerateForFPA(fpa)) {
+                psAbort("pmFPAWrite", "error generating HDU");
+            }
+            if (!hdu->images) {
+                psAbort("pmFPAWrite", "programming error: failure generating HDU");
+            }
+        }
+
+        // We only write out a blank PHU if it's specifically requested.
+        bool writeBlank = blank && hdu->blankPHU && !hdu->images; // Write a blank PHU?
+        bool writeImage = !hdu->blankPHU && hdu->images; // Write an image?
+
+        if (writeBlank || writeImage) {
+            pmConceptSource source = PM_CONCEPT_SOURCE_HEADER | PM_CONCEPT_SOURCE_CAMERA |
+                                     PM_CONCEPT_SOURCE_DEFAULTS;
             if (!pmConceptsWriteFPA(fpa, source, true, NULL)) {
-                psError(PS_ERR_IO, false, "Unable to write Concepts for FPA.\n");
+                psError(PS_ERR_IO, false, "Unable to write concepts for FPA.\n");
                 return false;
             }
@@ -229,10 +227,10 @@
     }
 
-    // XXX what are the rules on when we allow recursion?
+    // Recurse to lower levels if requested
     if (recurse) {
         psArray *chips = fpa->chips;        // Array of chips
         for (int i = 0; i < chips->n; i++) {
             pmChip *chip = chips->data[i];  // The chip of interest
-            if (!pmChipWrite(chip, fits, db, pixels, true)) {
+            if (!pmChipWrite(chip, fits, db, blank, true)) {
                 psError(PS_ERR_IO, false, "Unable to write FPA.\n");
                 return false;
@@ -242,10 +240,3 @@
 
     return true;
-
-    // summary:
-    // pmHDUWrite writes out the PHU header or the header + pixels
-    // we need to generate the HDU (why?)
-    // we call pmHDUWrite if:
-    // - the fpa->hdu represents a blank data segment (header w/ no pixels)
-    // - the fpa->hdu represents an image data segment (header w/ pixels)
-}
+}
Index: /trunk/psModules/src/camera/pmFPAview.c
===================================================================
--- /trunk/psModules/src/camera/pmFPAview.c	(revision 7716)
+++ /trunk/psModules/src/camera/pmFPAview.c	(revision 7717)
@@ -3,6 +3,6 @@
  *  @author EAM, IfA
  *
- *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2006-06-17 01:50:43 $
+ *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2006-06-28 05:12:19 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -253,5 +253,5 @@
     if (view->chip < 0) {
         hdu = pmHDUFromFPA (fpa);
-        if (hdu->phu)
+        if (hdu->blankPHU)
             return hdu;
         return NULL;
@@ -260,5 +260,5 @@
         chip = pmFPAviewThisChip (view, fpa);
         hdu  = pmHDUFromChip (chip);
-        if (hdu->phu)
+        if (hdu->blankPHU)
             return hdu;
         new.chip = -1;
@@ -269,5 +269,5 @@
         cell = pmFPAviewThisCell (view, fpa);
         hdu  = pmHDUFromCell (cell);
-        if (hdu->phu)
+        if (hdu->blankPHU)
             return hdu;
         new.cell = -1;
Index: /trunk/psModules/src/camera/pmHDU.c
===================================================================
--- /trunk/psModules/src/camera/pmHDU.c	(revision 7716)
+++ /trunk/psModules/src/camera/pmHDU.c	(revision 7717)
@@ -15,22 +15,15 @@
 {
     // Deal with the PHU case
-    if (strcasecmp(hdu->extname, "PHU") == 0 || hdu->phu) {
-        if (! psFitsMoveExtNum(fits, 0, false)) {
+    if (hdu->blankPHU) {
+        if (!psFitsMoveExtNum(fits, 0, false)) {
             psError(PS_ERR_IO, false, "Unable to move to primary header!\n");
             return false;
         }
-        hdu->phu = true;
-        return true;
-    }
-
-    if (! psFitsMoveExtName(fits, hdu->extname)) {
+        return true;
+    }
+
+    if (!psFitsMoveExtName(fits, hdu->extname)) {
         psError(PS_ERR_IO, false, "Unable to move to extension %s\n", hdu->extname);
         return false;
-    }
-    // Now, just in case for some reason the PHU has an extension name that we've moved to....
-    if (psFitsGetExtNum(fits) == 0) {
-        hdu->phu = true;
-    } else {
-        hdu->phu = false;
     }
 
@@ -61,12 +54,8 @@
 
     if (!extname || strlen(extname) == 0) {
-        hdu->phu = true;
-        hdu->extname = psStringCopy("PHU");
+        hdu->blankPHU = true;
+        hdu->extname = NULL;
     } else {
-        if (strcasecmp(extname, "PHU") == 0) {
-            hdu->phu = true;
-        } else {
-            hdu->phu = false;
-        }
+        hdu->blankPHU = false;
         hdu->extname = psStringCopy(extname);
     }
Index: /trunk/psModules/src/camera/pmHDU.h
===================================================================
--- /trunk/psModules/src/camera/pmHDU.h	(revision 7716)
+++ /trunk/psModules/src/camera/pmHDU.h	(revision 7717)
@@ -6,5 +6,5 @@
 {
     psString extname;                   // The extension name
-    bool phu;                           // Is this the FITS Primary Header Unit
+    bool blankPHU;                      // Is this a blank FITS Primary Header Unit, i.e., no data?
     psMetadata *format;                 // The camera format
     psMetadata *header;                 // The FITS header, or NULL if primary for FITS; or section info
Index: /trunk/psModules/src/camera/pmHDUUtils.c
===================================================================
--- /trunk/psModules/src/camera/pmHDUUtils.c	(revision 7716)
+++ /trunk/psModules/src/camera/pmHDUUtils.c	(revision 7717)
@@ -94,6 +94,6 @@
     PS_ASSERT_PTR_NON_NULL(hdu,);
 
-    if (hdu->phu) {
-        psTrace(__func__, level, "HDU: %s (PHU)\n", hdu->extname);
+    if (hdu->blankPHU) {
+        psTrace(__func__, level, "HDU: (PHU)\n");
     } else {
         psTrace(__func__, level, "HDU: %s\n", hdu->extname);
