Index: /branches/pap_branch_20090128/psModules/src/camera/pmFPARead.c
===================================================================
--- /branches/pap_branch_20090128/psModules/src/camera/pmFPARead.c	(revision 21268)
+++ /branches/pap_branch_20090128/psModules/src/camera/pmFPARead.c	(revision 21269)
@@ -9,4 +9,6 @@
 #include <pslib.h>
 
+#include "pmConfig.h"
+#include "pmConfigMask.h"
 #include "pmHDU.h"
 #include "pmFPA.h"
@@ -732,10 +734,4 @@
             return NULL;
         }
-
-        if (type == FPA_READ_TYPE_VARIANCE && hdu->covariances) {
-            psArray *covariances = hdu->covariances; // Covariances in HDU
-            for (int i = 0; i < covariances->n; i++) {
-                pmHDUCovariances *covar = covariances->data[i]; // Covariance information
-
         psFree(readout);                // Drop reference
     }
@@ -1143,5 +1139,8 @@
     PS_ASSERT_FITS_NON_NULL(fits, false);
 
-    return cellRead(cell, fits, config, FPA_READ_TYPE_VARIANCE);
+    if (!cellRead(cell, fits, config, FPA_READ_TYPE_VARIANCE)) {
+        return false;
+    }
+    return pmCellReadCovariance(cell, fits);
 }
 
@@ -1151,5 +1150,8 @@
     PS_ASSERT_FITS_NON_NULL(fits, false);
 
-    return chipRead(chip, fits, config, FPA_READ_TYPE_VARIANCE);
+    if (!chipRead(chip, fits, config, FPA_READ_TYPE_VARIANCE)) {
+        return false;
+    }
+    return pmChipReadCovariance(chip, fits);
 }
 
@@ -1159,5 +1161,8 @@
     PS_ASSERT_FITS_NON_NULL(fits, false);
 
-    return fpaRead(fpa, fits, config, FPA_READ_TYPE_VARIANCE);
+    if (!fpaRead(fpa, fits, config, FPA_READ_TYPE_VARIANCE)) {
+        return false;
+    }
+    return pmFPAReadCovariance(fpa, fits);
 }
 
@@ -1285,2 +1290,111 @@
     return numRead;
 }
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Reading covariance matrices
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+bool pmCellReadCovariance(pmCell *cell, psFits *fits)
+{
+    PS_ASSERT_PTR_NON_NULL(cell, false);
+    PS_ASSERT_FITS_NON_NULL(fits, false);
+
+    const char *chipName = psMetadataLookupStr(NULL, cell->parent->concepts, "CHIP.NAME"); // Name of chip
+    const char *cellName = psMetadataLookupStr(NULL, cell->concepts, "CELL.NAME"); // Name of cell
+    psString extname = NULL;            // Extension name
+    psStringAppend(&extname, "COVAR_%s_%s", chipName, cellName);
+
+    if (!psFitsMoveExtName(fits, extname)) {
+        psError(PS_ERR_IO, false, "Unable to move to extension %s\n", extname);
+        psFree(extname);
+        return false;
+    }
+    psFree(extname);
+
+    psMetadata *header = psFitsReadHeader(NULL, fits); // The FITS header
+    if (!header) {
+        psError(PS_ERR_IO, false, "Unable to read header for extension %s\n", extname);
+        psFree(header);
+        return false;
+    }
+
+    bool mdok;                          // Status of MD lookup
+    int x0 = psMetadataLookupS32(&mdok, header, "COVARIANCE.CENTRE.X"); // Centre of matrix in x
+    if (!mdok) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Unable to read covariance centre");
+        psFree(header);
+        return false;
+    }
+    int y0 = psMetadataLookupS32(&mdok, header, "COVARIANCE.CENTRE.Y"); // Centre of matrix in y
+    if (!mdok) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Unable to read covariance centre");
+        psFree(header);
+        return false;
+    }
+    psFree(header);
+
+    psArray *images = psFitsReadImageCube(fits, psRegionSet(0,0,0,0)); // Covariance matrices
+    if (!images) {
+        psError(PS_ERR_IO, false, "Unable to read covariance matrices for chip %s, cell %s",
+                chipName, cellName);
+        return false;
+    }
+
+    psArray *readouts = cell->readouts; // Readouts of cell
+    if (images->n != readouts->n) {
+        psError(PS_ERR_BAD_PARAMETER_SIZE, true,
+                "Number of covariance matrices (%ld) doesn't match number of readouts (%ld)",
+                images->n, readouts->n);
+        psFree(images);
+        return false;
+    }
+
+    for (int i = 0; i < readouts->n; i++) {
+        pmReadout *ro = readouts->data[i]; // Readout of interest
+        psImage *image = images->data[i]; // Image of interest
+        if (ro->covariance) {
+            psWarning("Clobbering extant covariance matrix in chip %s, cell %s, readout %d",
+                      chipName, cellName, i);
+            psFree(ro->covariance);
+        }
+        ro->covariance = psKernelAllocFromImage(image, x0, y0);
+    }
+    psFree(images);
+
+    return true;
+}
+
+
+bool pmChipReadCovariance(pmChip *chip, psFits *fits)
+{
+    PS_ASSERT_PTR_NON_NULL(chip, false);
+    PS_ASSERT_FITS_NON_NULL(fits, false);
+
+    psArray *cells = chip->cells;       // Array of cells
+    for (int i = 0; i < cells->n; i++) {
+        pmCell *cell = cells->data[i];  // Cell of interest
+        if (!pmCellReadCovariance(cell, fits)) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+
+bool pmFPAReadCovariance(pmFPA *fpa, psFits *fits)
+{
+    PS_ASSERT_PTR_NON_NULL(fpa, false);
+    PS_ASSERT_FITS_NON_NULL(fits, false);
+
+    psArray *chips = fpa->chips;        // Array of chips
+    for (int i = 0; i < chips->n; i++) {
+        pmChip *chip = chips->data[i];  // Chip of interest
+        if (!pmChipReadCovariance(chip, fits)) {
+            return false;
+        }
+    }
+
+    return true;
+}
Index: /branches/pap_branch_20090128/psModules/src/camera/pmFPARead.h
===================================================================
--- /branches/pap_branch_20090128/psModules/src/camera/pmFPARead.h	(revision 21268)
+++ /branches/pap_branch_20090128/psModules/src/camera/pmFPARead.h	(revision 21269)
@@ -4,6 +4,6 @@
  * @author Paul Price, IfA
  *
- * @version $Revision: 1.15.44.1 $ $Name: not supported by cvs2svn $
- * @date $Date: 2009-01-29 00:33:51 $
+ * @version $Revision: 1.15.44.2 $ $Name: not supported by cvs2svn $
+ * @date $Date: 2009-02-03 00:37:06 $
  * Copyright 2005-2006 Institute for Astronomy, University of Hawaii
  */
@@ -226,5 +226,5 @@
 /// also read and included in the cell analysis metadata under "name.HEADER".
 int pmCellReadTable(pmCell *cell,       ///< Cell for which to read table
-                    psFits *fits,       ///< FITS file from which the table
+                    psFits *fits,       ///< FITS file from which to read the table
                     const char *name    ///< Specifies the extension name, and target in the analysis metadata
                    );
@@ -233,6 +233,6 @@
 ///
 /// Iterates over component cells, calling pmCellReadTable.
-int pmChipReadTable(pmChip *chip,       ///< Cell for which to read table
-                    psFits *fits,       ///< FITS file from which the table
+int pmChipReadTable(pmChip *chip,       ///< Chip for which to read table
+                    psFits *fits,       ///< FITS file from which to read the table
                     const char *name    ///< Specifies the extension name, and target in the analysis metadata
                    );
@@ -241,8 +241,26 @@
 ///
 /// Iterates over component chips, calling pmChipReadTable.
-int pmFPAReadTable(pmFPA *fpa,          ///< Cell for which to read table
-                   psFits *fits,        ///< FITS file from which the table
+int pmFPAReadTable(pmFPA *fpa,          ///< FPA for which to read table
+                   psFits *fits,        ///< FITS file from which to read the table
                    const char *name     ///< Specifies the extension name, and target in the analysis metadata
                   );
+
+/// Read covariance matrices for a cell
+bool pmCellReadCovariance(pmCell *cell, ///< Cell for which to read covariance matrices
+                          psFits *fits  ///< FITS file from which to read
+    );
+
+/// Read covariance matrices for a chip
+bool pmChipReadCovariance(pmChip *chip, ///< Chip for which to read covariance matrices
+                          psFits *fits  ///< FITS file from which to read
+    );
+
+/// Read covariance matrices for a cell
+bool pmFPAReadCovariance(pmFPA *fpa,    ///< FPA for which to read covariance matrices
+                         psFits *fits   ///< FITS file from which to read
+    );
+
+
+
 /// @}
 #endif
Index: /branches/pap_branch_20090128/psModules/src/camera/pmFPAWrite.c
===================================================================
--- /branches/pap_branch_20090128/psModules/src/camera/pmFPAWrite.c	(revision 21268)
+++ /branches/pap_branch_20090128/psModules/src/camera/pmFPAWrite.c	(revision 21269)
@@ -9,4 +9,5 @@
 
 #include "pmConfig.h"
+#include "pmConfigMask.h"
 #include "pmHDU.h"
 #include "pmFPA.h"
@@ -74,6 +75,30 @@
 }
 
-
-
+// Indicate whether a covariance matrix is defined
+static bool readoutSearchCovariances(pmReadout *ro)
+{
+    return ro->covariance ? true : false;
+}
+
+// Search for a covariance matrix
+#define SEARCH_COVARIANCES(NAME, PARENT, CHILD, CHILDREN, TESTFUNC) \
+static bool NAME(PARENT *parent) \
+{ \
+    if (!parent || !parent->CHILDREN) { \
+        return false; \
+    } \
+    psArray *children = parent->CHILDREN; /* Array of children */ \
+    for (int i = 0; i < children->n; i++) { \
+        CHILD *child = children->data[i]; /* Child of interest */ \
+        if (child && TESTFUNC(child)) { \
+            return true; \
+        } \
+    } \
+    return false; \
+}
+
+SEARCH_COVARIANCES(cellSearchCovariances, pmCell, pmReadout, readouts, readoutSearchCovariances);
+SEARCH_COVARIANCES(chipSearchCovariances, pmChip, pmCell,    cells,    cellSearchCovariances);
+SEARCH_COVARIANCES(fpaSearchCovariances,  pmFPA,  pmChip,    chips,    chipSearchCovariances);
 
 // Some type-specific additions to the header
@@ -81,6 +106,7 @@
                               pmChip *chip, // Chip of interest, or NULL
                               pmCell *cell, // Cell of interest, or NULL
-                              fpaWriteType type // Type to write
-    )
+                              fpaWriteType type, // Type to write
+                              pmConfig *config // Configuration
+                              )
 {
     switch (type) {
@@ -94,6 +120,22 @@
       }
       case FPA_WRITE_TYPE_VARIANCE: {
+          bool covar = false;           // Are covariances present?
+          if ((cell && cellSearchCovariances(cell)) ||
+              (!cell && ((chip && chipSearchCovariances(chip)) ||
+                         (!chip && fpa && fpaSearchCovariances)))) {
+              covar = true;
+          }
+
           pmHDU *hdu = pmHDUGetLowest(fpa, chip, cell); // Header being written
-
+          psMetadataAddBool(hdu->header, PS_LIST_TAIL, PM_HDU_COVARIANCE_KEYWORD, PS_META_REPLACE,
+                            "Is a covariance matrix present?", covar);
+          break;
+      }
+      default:
+        break;
+    }
+
+    return true;
+}
 
 
@@ -137,6 +179,8 @@
             return false;
         }
-
-
+        if (!writeUpdateHeader(NULL, NULL, cell, type, config)) {
+            psError(PS_ERR_UNKNOWN, false, "Unable to update header for writing");
+            return false;
+        }
         if (!appropriateWriteFunc(hdu, fits, config, type)) {
             psError(PS_ERR_IO, false, "Unable to write HDU for cell.\n");
@@ -189,4 +233,10 @@
                 return false;
             }
+
+            if (!writeUpdateHeader(NULL, chip, NULL, type, config)) {
+                psError(PS_ERR_UNKNOWN, false, "Unable to update header for writing");
+                return false;
+            }
+
             if (!appropriateWriteFunc(hdu, fits, config, type)) {
                 psError(PS_ERR_IO, false, "Unable to write HDU for chip.\n");
@@ -253,4 +303,8 @@
                 return false;
             }
+            if (!writeUpdateHeader(fpa, NULL, NULL, type, config)) {
+                psError(PS_ERR_UNKNOWN, false, "Unable to update header for writing");
+                return false;
+            }
             if (!appropriateWriteFunc(hdu, fits, config, type))  {
                 psError(PS_ERR_IO, false, "Unable to write HDU for FPA.\n");
@@ -535,2 +589,120 @@
     return numWrite;
 }
+
+bool pmCellWriteCovariance(psFits *fits, const pmCell *cell)
+{
+    PS_ASSERT_PTR_NON_NULL(cell, false);
+    PS_ASSERT_PTR_NON_NULL(fits, false);
+
+    int numCovar = 0;
+    psArray *readouts = cell->readouts; // Array of readouts
+    for (int i = 0; i < readouts->n; i++) {
+        pmReadout *readout = readouts->data[i]; // The readout of interest
+        if (readout && readout->covariance) {
+            numCovar++;
+        }
+    }
+    if (numCovar == 0) {
+        return true;
+    }
+    if (numCovar != readouts->n) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                "Number of covariances (%d) doesn't match number of readouts (%ld)",
+                numCovar, readouts->n);
+        return false;
+    }
+
+    // Check size of covariances
+    int xMinCovar = INT_MAX, xMaxCovar = INT_MIN, yMinCovar = INT_MAX, yMaxCovar = INT_MIN; // Size
+    for (int i = 0; i < readouts->n; i++) {
+        pmReadout *readout = readouts->data[i]; // The readout of interest
+        psAssert(readout, "Should be defined.");
+        psKernel *covar = readout->covariance; // Covariance matrix
+        psAssert(covar, "Should be defined.");
+        xMinCovar = PS_MIN(xMinCovar, covar->xMin);
+        xMaxCovar = PS_MAX(xMaxCovar, covar->xMax);
+        yMinCovar = PS_MIN(yMinCovar, covar->yMin);
+        yMaxCovar = PS_MAX(yMaxCovar, covar->yMax);
+    }
+
+    // Correct covariances to common size
+    psArray *images = psArrayAlloc(numCovar); // Array of images
+    for (int i = 0; i < readouts->n; i++) {
+        pmReadout *readout = readouts->data[i]; // The readout of interest
+        psAssert(readout, "Should be defined.");
+        psKernel *covar = readout->covariance; // Covariance matrix
+        psAssert(covar, "Should be defined.");
+        int xMin = covar->xMin, xMax = covar->xMax, yMin = covar->yMin, yMax = covar->yMax;// Size
+        if (xMin == xMinCovar && xMax == xMaxCovar && yMin == yMinCovar && yMax == yMaxCovar) {
+            images->data[i] = psMemIncrRefCounter(covar->image);
+        } else {
+            psImage *new = psImageAlloc(xMaxCovar - xMinCovar + 1, yMaxCovar - yMinCovar + 1, PS_TYPE_F32);
+            psImageInit(new, 0);
+            psImageOverlaySection(new, covar->image, xMinCovar - xMin, yMinCovar - yMin, "=");
+            images->data[i] = new;
+        }
+    }
+
+    // Determine extension name
+    const char *chipName = psMetadataLookupStr(NULL, cell->parent->concepts, "CHIP.NAME"); // Name of chip
+    const char *cellName = psMetadataLookupStr(NULL, cell->concepts, "CELL.NAME"); // Name of cell
+    psString extname = NULL;            // Extension name
+    psStringAppend(&extname, "COVAR_%s_%s", chipName, cellName);
+
+    // Generate header
+    pmHDU *hdu = pmHDUFromCell(cell);   // HDU for cell
+    psMetadata *header = psMetadataCopy(NULL, hdu->header); // Header to write
+    psMetadataAddS32(header, PS_LIST_TAIL, "COVARIANCE.CENTRE.X", PS_META_REPLACE,
+                     "Centre of covariance matrix in x", -xMinCovar);
+    psMetadataAddS32(header, PS_LIST_TAIL, "COVARIANCE.CENTRE.Y", PS_META_REPLACE,
+                     "Centre of covariance matrix in y", -yMinCovar);
+
+    // Write images
+    if (!psFitsWriteImageCube(fits, header, images, extname)) {
+        psError(PS_ERR_UNKNOWN, false, "Unable to write covariances from chip %s, cell %s to extension %s",
+                chipName, cellName, extname);
+        psFree(extname);
+        psFree(header);
+        psFree(images);
+        return 0;
+    }
+    psFree(extname);
+    psFree(header);
+    psFree(images);
+
+    return true;
+}
+
+
+bool pmChipWriteCovariance(psFits *fits, const pmChip *chip)
+{
+    PS_ASSERT_PTR_NON_NULL(chip, false);
+    PS_ASSERT_PTR_NON_NULL(fits, false);
+
+    psArray *cells = chip->cells;       // Array of cells
+    for (int i = 0; i < cells->n; i++) {
+        pmCell *cell = cells->data[i];  // Cell of interest
+        if (!pmCellWriteCovariance(fits, cell)) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+
+bool pmFPAWriteCovariance(psFits *fits, const pmFPA *fpa)
+{
+    PS_ASSERT_PTR_NON_NULL(fpa, false);
+    PS_ASSERT_PTR_NON_NULL(fits, false);
+
+    psArray *chips = fpa->chips;        // Array of chips
+    for (int i = 0; i < chips->n; i++) {
+        pmChip *chip = chips->data[i];  // Chip of interest
+        if (!pmChipWriteCovariance(fits, chip)) {
+            return false;
+        }
+    }
+
+    return true;
+}
Index: /branches/pap_branch_20090128/psModules/src/camera/pmHDU.c
===================================================================
--- /branches/pap_branch_20090128/psModules/src/camera/pmHDU.c	(revision 21268)
+++ /branches/pap_branch_20090128/psModules/src/camera/pmHDU.c	(revision 21269)
@@ -12,6 +12,4 @@
 #include "pmHDU.h"
 #include "pmFPA.h"
-
-#define COVARIANCE_INDICATOR "PS_COVAR" // FITS keyword to indicate if covariance matrices are present
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -162,9 +160,5 @@
     PS_ASSERT_PTR_NON_NULL(fits, false);
 
-    if (!hduRead(hdu, &hdu->variances, fits)) {
-        return false;
-    }
-
-    return true;
+    return hduRead(hdu, &hdu->variances, fits);
 }
 
@@ -246,17 +240,5 @@
     PS_ASSERT_PTR_NON_NULL(fits, false);
 
-    pmHDUCovariancesWriteHeader(hdu);
-
     psImageMaskType maskVal = pmConfigMaskGet("MASK.VALUE", config); // Value to mask
-    if (!hduWrite(hdu, hdu->variances, hdu->masks, maskVal, fits)) {
-        return false;
-    }
-    pmHDUCovarianceClearHeader(hdu);
-
-    if (!pmHDUCovarianceWrite(hdu, fits)) {
-        psError(PS_ERR_UNKNOWN, false, "Unable to write covariance");
-        return false;
-    }
-
-    return true;
-}
+    return hduWrite(hdu, hdu->variances, hdu->masks, maskVal, fits);
+}
Index: /branches/pap_branch_20090128/psModules/src/camera/pmHDU.h
===================================================================
--- /branches/pap_branch_20090128/psModules/src/camera/pmHDU.h	(revision 21268)
+++ /branches/pap_branch_20090128/psModules/src/camera/pmHDU.h	(revision 21269)
@@ -4,6 +4,6 @@
  * @author Paul Price, IfA
  *
- * @version $Revision: 1.9.22.2 $ $Name: not supported by cvs2svn $
- * @date $Date: 2009-02-02 18:05:38 $
+ * @version $Revision: 1.9.22.3 $ $Name: not supported by cvs2svn $
+ * @date $Date: 2009-02-03 00:37:06 $
  * Copyright 2005-2006 Institute for Astronomy, University of Hawaii
  */
@@ -17,4 +17,6 @@
 /// @addtogroup Camera Camera Layout
 /// @{
+
+#define PM_HDU_COVARIANCE_KEYWORD "PS_COVAR" // FITS keyword to indicate presence of a covariance matrix
 
 /// An instance of the FITS Header Data Unit
@@ -30,5 +32,4 @@
     psArray *variances;                 ///< Variance in the pixel data, or NULL
     psArray *masks;                     ///< Mask for the pixel data, or NULL
-    psArray *covariances;               ///< Covariance matrices (pmHDUCovariance), or NULL
 } pmHDU;
 
Index: anches/pap_branch_20090128/psModules/src/camera/pmHDUCovariances.c
===================================================================
--- /branches/pap_branch_20090128/psModules/src/camera/pmHDUCovariances.c	(revision 21268)
+++ 	(revision )
@@ -1,167 +1,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <pslib.h>
-
-#include "pmHDU.h"
-#include "pmFPA.h"
-
-#include "pmHDUCovariances.h"
-
-/// Storage for covariance matrices of a cell
-///
-/// We want to store the covariance matrices applicable for a single HDU together.  However, when we write an
-/// HDU, we know nothing about chips and cells, so we require that it be populated for us.  This structure is
-/// more convenient than carrying embedded psMetadata.
-typedef struct {
-    psString chipName;                  ///< Name of chip
-    psString cellName;                  ///< Name of cell
-    int xMin, xMax, yMin, yMax;         ///< Size of covariance matrices
-    psArray *covariances;               ///< Covariance matrices for cell (one per readout)
-} pmHDUCovariance;
-
-// Deallocator
-static void hduCovarianceFree(pmHDUCovariance *covar)
-{
-    psFree(covar->chipName);
-    psFree(covar->cellName);
-    psFree(covar->covariances);
-    return;
-}
-
-/// Allocator
-pmHDUCovariance *pmHDUCovarianceAlloc(void)
-{
-    pmHDUCovariance *covar = psAlloc(sizeof(pmHDUCovariance)); // Covariance information to return
-    psMemSetDeallocator(covar, (psFreeFunc)hduCovarianceFree);
-
-    covar->chipName = NULL;
-    covar->cellName = NULL;
-    covar->xMin = 0;
-    covar->xMax = 0;
-    covar->yMin = 0;
-    covar->yMax = 0;
-    covar->covariances = NULL;
-
-    return covar;
-}
-
-bool pmHDUCovarianceWriteHeader(pmHDU *hdu)
-{
-    PM_ASSERT_HDU_NON_NULL(hdu, false);
-
-    return psMetadataAddBool(hdu->header, PS_LIST_TAIL, COVARIANCE_INDICATOR, PS_META_REPLACE,
-                             "Covariance matrices present?", hdu->covariances ? true : false);
-}
-
-bool pmHDUCovarianceClearHeader(pmHDU *hdu)
-{
-    PM_ASSERT_HDU_NON_NULL(hdu, false);
-
-    return psMetadataRemoveKey(hdu->header, COVARIANCE_INDICATOR);
-}
-
-bool pmHDUCovarianceWrite(pmHDU *hdu, psFits *fits)
-{
-    PM_ASSERT_HDU_NON_NULL(hdu, false);
-    PS_ASSERT_FITS_NON_NULL(fits, false);
-
-    psArray *covariances = hdu->covariances; // Covariance matrices
-    if (!covariances) {
-        return true;
-    }
-
-    psArray *table = psArrayAlloc(covariances->n); // FITS table to write
-    for (int i = 0; i < covariances->n; i++) {
-        pmHDUCovariance *covar = covariances->data[i]; // Covariance information
-        psMetadata *row = psMetadataAlloc(); // Table row
-        psMetadataAddStr(row, PS_LIST_TAIL, "CHIP", 0, "Chip name", covar->chipName);
-        psMetadataAddStr(row, PS_LIST_TAIL, "CELL", 0, "Cell name", covar->cellName);
-        psMetadataAddS32(row, PS_LIST_TAIL, "READOUT", 0, "Readout number", covar->readoutNum);
-        psMetadataAddS32(row, PS_LIST_TAIL, "XMIN", 0, "Minimum x value", covar->xMin);
-        psMetadataAddS32(row, PS_LIST_TAIL, "XMAX", 0, "Maximum x value", covar->xMax);
-        psMetadataAddS32(row, PS_LIST_TAIL, "YMIN", 0, "Minimum y value", covar->yMin);
-        psMetadataAddS32(row, PS_LIST_TAIL, "YMAX", 0, "Maximum x value", covar->yMax);
-        int numCols = covar->xMax - covar->xMin + 1, numRows = covar->yMax - covar->yMin + 1; // Size
-        psVector *data = psVectorAlloc(numCols * numRows, PS_TYPE_F32); // Vector with data
-        for (int i = 0, j = 0; i < numRows; i++, j += numCols) {
-            memcpy(&data->data.F32[j], kernel->image[i], numCols * PS_ELEMTYPE_SIZEOF(PS_TYPE_F32));
-        }
-        psMetadataAddVector(row, PS_LIST_TAIL, "COVAR", 0, "Covariance matrix, row-major order", data);
-        psFree(data);               // Drop reference
-        table->data[i] = row;
-    }
-    psString *extname = NULL;       // Extension name for covariance data
-    psStringAppend(&extname, "%s_COVAR", hdu->extname);
-    if (!psFitsWriteTable(fits, hdu->header, table, extname)) {
-        psError(PS_ERR_IO, false, "Unable to write covariance table.");
-        psFree(extname);
-        psFree(table);
-        return false;
-    }
-    psFree(extname);
-    psFree(table);
-
-    return true;
-}
-
-
-/// Read covariance into an HDU
-bool pmHDUCovarianceRead(pmHDU *hdu)
-{
-    PM_ASSERT_HDU_NON_NULL(hdu, false);
-    PS_ASSERT_METADATA_NON_NULL(hdu->header, false);
-
-    bool mdok;                          // Status of MD lookup
-    if (!psMetadataLookupBool(&mdok, hdu->header, COVARIANCE_INDICATOR)) {
-        return true;
-    }
-
-    psString extname = NULL;            // Name of extension
-    psStringAppend(&extname, "%s_COVAR", hdu->extname);
-    if (!psFitsMoveExtName(fits, extname)) {
-        psError(PS_ERR_IO, false, "Unable to move to covariance extension");
-        psFree(extname);
-        return false;
-    }
-    psFree(extname);
-
-    psArray *table = psFitsReadTable(fits); // Table with covariances
-    if (!table) {
-        psError(PS_ERR_IO, false, "Unable to read covariances table");
-        return false;
-    }
-    psArray *covariances = hdu->covariances = psArrayAlloc(table->n); // Covariance matrices
-    for (int i = 0; i < table->n; i++) {
-        psMetadata *row = table->data[i]; // Table row
-        pmHDUCovariance *covar = pmHDUCovarianceAlloc();
-        covar->chipName = psMetadataLookupStr(NULL, row, "CHIP");
-        covar->cellName = psMetadataLookupStr(NULL, row, "CELL");
-        covar->xMin = psMetadataLookupStr(NULL, row, "XMIN");
-        covar->xMax = psMetadataLookupStr(NULL, row, "XMAX");
-        covar->yMin = psMetadataLookupStr(NULL, row, "YMIN");
-        covar->yMax = psMetadataLookupStr(NULL, row, "YMAX");
-
-        covariances->data[i] = covar;
-    }
-}
-
-
-bool pmHDUCovarianceAdd(pmHDU *hdu, pmReadout *readout)
-{
-    PM_ASSERT_HDU_NON_NULL(hdu, false);
-    PM_ASSERT_READOUT_NON_NULL(readout, false);
-    PM_ASSERT_READOUT_PARENT_NON_NULL(readout, false);
-
-}
-
-/// Select the appropriate covariance from an HDU
-bool pmHDUCovarianceSelect(
-    pmReadout *readout,                 ///< Readout for which to select covariance
-    pmHDU *hdu,                         ///< Header data unit with covariance
-    );
-
-
-#endif
Index: anches/pap_branch_20090128/psModules/src/camera/pmHDUCovariances.h
===================================================================
--- /branches/pap_branch_20090128/psModules/src/camera/pmHDUCovariances.h	(revision 21268)
+++ 	(revision )
@@ -1,41 +1,0 @@
-#ifndef PM_HDU_COVARIANCES_H
-#define PM_HDU_COVARIANCES_H
-
-#include <pslib.h>
-#include "pmHDU.h"
-#include "pmFPA.h"
-
-/// Storage for covariance matrices of a cell
-///
-/// We want to store the covariance matrices applicable for a single HDU together.  However, when we write an
-/// HDU, we know nothing about chips and cells, so we require that it be populated for us.  This structure is
-/// more convenient than carrying embedded psMetadata.
-typedef struct {
-    psString chipName;                  ///< Name of chip
-    psString cellName;                  ///< Name of cell
-    int readoutNum;                     ///< Number of readout
-    int xMin, xMax, yMin, yMax;         ///< Size of covariance matrices
-    psArray *covariances;               ///< Covariance matrices for cell (one per readout)
-} pmHDUCovariance;
-
-/// Allocator
-pmHDUCovariance *pmHDUCovarianceAlloc(void);
-
-/// Read covariance into an HDU
-bool pmHDUCovarianceRead(
-    pmHDU *hdu                          ///< Header data unit into which to read
-    );
-
-/// Write covariance from an HDU
-bool pmHDUCovarianceWrite(
-    pmHDU *hdu                          ///< Header data unit from which to write
-    );
-
-/// Select the appropriate covariance from an HDU
-bool pmHDUCovarianceSelect(
-    pmReadout *readout,                 ///< Readout for which to select covariance
-    pmHDU *hdu,                         ///< Header data unit with covariance
-    );
-
-
-#endif
Index: /branches/pap_branch_20090128/psModules/src/camera/pmHDUGenerate.c
===================================================================
--- /branches/pap_branch_20090128/psModules/src/camera/pmHDUGenerate.c	(revision 21268)
+++ /branches/pap_branch_20090128/psModules/src/camera/pmHDUGenerate.c	(revision 21269)
@@ -356,5 +356,4 @@
     psElemType maskType = 0;            // Type of readout masks
     psElemType varianceType = 0;        // Type of readout variances
-    psElemType covarianceType = 0;      // Type of readout covariances
     {
         psListIterator *iter = psListIteratorAlloc(cells, PS_LIST_HEAD, false); // Iterator for cells
@@ -385,12 +384,9 @@
                     varianceType = checkTypes(varianceType, readout->variance->type.type);
                 }
-                if (!hdu->covariances && readout->covariance) {
-                    covarianceType = checkTypes(covarianceType, PS_TYPE_F32);
-                }
             }
         }
         psFree(iter);
     }
-    if (numReadouts == 0 || (imageType == 0 && maskType == 0 && varianceType == 0 && covarianceType == 0)) {
+    if (numReadouts == 0 || (imageType == 0 && maskType == 0 && varianceType == 0)) {
         // Nothing from which to create an HDU
         psFree(cells);
@@ -432,7 +428,4 @@
             hdu->variances->data[i] = variance;
         }
-    }
-    if (covarianceType) {
-        hdu->covariances = psHashAlloc(psListLength(cells));
     }
 
@@ -456,24 +449,7 @@
             psArray *readouts = cell->readouts; // Array of readouts
 
-            // Check size of covariances
-            int xMinCovar = INT_MAX, xMaxCovar = INT_MIN, yMinCovar = INT_MAX, yMaxCovar = INT_MIN; // Size
-            if (covarianceType) {
-                for (int i = 0; i < readouts->n; i++) {
-                    pmReadout *readout = readouts->data[i]; // The readout of interest
-                    if (!readout) {
-                        continue;
-                    }
-                    psKernel *covar = readout->covariance; // Covariance matrix
-                    xMinCovar = PS_MIN(xMinCovar, covar->xMin);
-                    xMaxCovar = PS_MAX(xMaxCovar, covar->xMax);
-                    yMinCovar = PS_MIN(yMinCovar, covar->yMin);
-                    yMaxCovar = PS_MAX(yMaxCovar, covar->yMax);
-                }
-            }
-
             psArray *hduImages = hdu->images; // Array of images in the HDU
             psArray *hduMasks = hdu->masks; // Array of masks in the HDU
             psArray *hduVariances = hdu->variances; // Array of variances in the HDU
-            psArray *covariances = (covarianceType ? psArrayAlloc(readouts->n) : NULL; // Covariance images
             for (int i = 0; i < readouts->n; i++) {
                 pmReadout *readout = readouts->data[i]; // The readout of interest
@@ -496,17 +472,4 @@
                     psFree(readout->variance);
                     readout->variance = new;
-                }
-                if (readout->covariance) {
-                    psKernel *covar = readout->covariance; // Covariance matrix
-                    int xMin = covar->xMin, xMax = covar->xMax, yMin = covar->yMin, yMax = covar->yMax;// Size
-                    if (xMin == xMinCovar && xMax == xMaxCovar && yMin == yMinCovar && yMax == yMaxCovar) {
-                        variances->data[i] = psMemIncrRefCounter(readout->covariance);
-                    } else {
-                        psKernel *new = psKernelAlloc(xMinCovar, xMaxCovar, yMinCovar, yMaxCovar);// New covar
-                        psImageInit(covar->image, 0);
-                        psImageOverlaySection(new->image, covar->image,
-                                              xMinCovar - xMin, yMinCovar - yMin, "=");
-                        variances->data[i] = new;
-                    }
                 }
 
@@ -533,21 +496,4 @@
             }
             psFree(biassecsIter);
-
-            if (covariances) {
-                const char *cellName = psMetadataLookupStr(NULL, cell->concepts, "CELL.NAME"); // Name of cell
-                pmChip *chip = cell->parent; // Parent chip
-                const char *chipName = psMetadataLookupStr(NULL, chip->concepts, "CHIP.NAME"); // Name of chip
-                if (!cellName || !chipName) {
-                    psError(PS_ERR_UNKNOWN, false, "Unable to find cell or chip name.");
-                    return false;
-                }
-                psString name = NULL; // Name for covariance extension
-                psStringAppend(&name, "COVAR_%s_%s", chipName, cellName);
-                if (psHashLookup(hdu->covariances, name)) {
-                    psHashRemove(hash, name);
-                }
-                psHashAdd(hdu->covariances, name, covariance);
-                psFree(name);
-            }
         } // Iterating over cells within the HDU
         psFree(iter);
@@ -636,5 +582,5 @@
         return false;
     }
-    if (hdu->images && hdu->masks && hdu->variances && hdu->covariances) {
+    if (hdu->images && hdu->masks && hdu->variances) {
         // It's already here!
         return true;
@@ -686,5 +632,5 @@
         return generateForCells(chip);
     }
-    if (hdu->images && hdu->masks && hdu->variances && hdu->covariances) {
+    if (hdu->images && hdu->masks && hdu->variances) {
         // It's already here!
         return true;
@@ -735,5 +681,5 @@
         return generateForChips(fpa);
     }
-    if (hdu->images && hdu->masks && hdu->variances && hdu->covariances) {
+    if (hdu->images && hdu->masks && hdu->variances) {
         // It's already here!
         return true;
