Index: /branches/rel10_ifa/psModules/src/astrom/Makefile.am
===================================================================
--- /branches/rel10_ifa/psModules/src/astrom/Makefile.am	(revision 6712)
+++ /branches/rel10_ifa/psModules/src/astrom/Makefile.am	(revision 6713)
@@ -35,5 +35,4 @@
 	pmHDUUtils.h \
 	pmReadout.h \
-	psAdditionals.h \
 	pmConcepts.h \
 	pmConceptsRead.h \
@@ -45,4 +44,3 @@
 #	pmFPAAstrometry.h
 #	pmAstrometryObjects.h
-#
 #	pmChipMosaic.h 
Index: /branches/rel10_ifa/psModules/src/astrom/pmFPA.c
===================================================================
--- /branches/rel10_ifa/psModules/src/astrom/pmFPA.c	(revision 6712)
+++ /branches/rel10_ifa/psModules/src/astrom/pmFPA.c	(revision 6713)
@@ -12,6 +12,6 @@
 * XXX: Should we implement non-linear cell->chip transforms?
 *
-*  @version $Revision: 1.1.4.4 $ $Name: not supported by cvs2svn $
-*  @date $Date: 2006-03-23 03:09:57 $
+*  @version $Revision: 1.1.4.5 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2006-03-28 02:16:26 $
 *
 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -255,4 +255,9 @@
         cell->readouts = psArrayAdd(cell->readouts, 1, (psPtr) tmpReadout);
     }
+
+    tmpReadout->process = true;            // All cells are processed by default
+    tmpReadout->file_exists = false;       // file not yet identified
+    tmpReadout->data_exists = false;       // data yet read in
+
     psMemSetDeallocator(tmpReadout, (psFreeFunc) readoutFree);
     return(tmpReadout);
@@ -287,5 +292,6 @@
     }
     tmpCell->process = true;            // All cells are processed by default
-    tmpCell->exists = false;            // Not yet read in
+    tmpCell->file_exists = false;       // Not yet identified
+    tmpCell->data_exists = false;       // Not yet read in
     tmpCell->hdu = NULL;
 
@@ -331,5 +337,6 @@
     }
     tmpChip->process = true;            // Work on all chips, by default
-    tmpChip->exists = false;            // Not read in yet
+    tmpChip->file_exists = false;       // Not yet identified
+    tmpChip->data_exists = false;       // Not yet read in
     tmpChip->hdu = NULL;
 
@@ -421,5 +428,69 @@
 }
 
-
+/** functions to turn on/off the file_exists flag **/
+bool pmFPASetFileStatus (pmFPA *fpa, bool status)
+{
+
+    for (int i = 0; i < fpa->chips->n; i++) {
+        pmChip *chip = fpa->chips->data[i];
+        pmChipSetFileStatus (chip, status);
+    }
+    return true;
+}
+
+bool pmChipSetFileStatus (pmChip *chip, bool status)
+{
+
+    chip->file_exists = status;
+    for (int i = 0; i < chip->cells->n; i++) {
+        pmCell *cell = chip->cells->data[i];
+        pmCellSetFileStatus (cell, status);
+    }
+    return true;
+}
+
+bool pmCellSetFileStatus (pmCell *cell, bool status)
+{
+
+    cell->file_exists = status;
+    for (int i = 0; i < cell->readouts->n; i++) {
+        pmReadout *readout = cell->readouts->data[i];
+        readout->file_exists = status;
+    }
+    return true;
+}
+
+/** functions to turn on/off the data_exists flag **/
+bool pmFPASetDataStatus (pmFPA *fpa, bool status)
+{
+
+    for (int i = 0; i < fpa->chips->n; i++) {
+        pmChip *chip = fpa->chips->data[i];
+        pmChipSetDataStatus (chip, status);
+    }
+    return true;
+}
+
+bool pmChipSetDataStatus (pmChip *chip, bool status)
+{
+
+    chip->data_exists = status;
+    for (int i = 0; i < chip->cells->n; i++) {
+        pmCell *cell = chip->cells->data[i];
+        pmCellSetDataStatus (cell, status);
+    }
+    return true;
+}
+
+bool pmCellSetDataStatus (pmCell *cell, bool status)
+{
+
+    cell->data_exists = status;
+    for (int i = 0; i < cell->readouts->n; i++) {
+        pmReadout *readout = cell->readouts->data[i];
+        readout->data_exists = status;
+    }
+    return true;
+}
 
 /*****************************************************************************
Index: /branches/rel10_ifa/psModules/src/astrom/pmFPA.h
===================================================================
--- /branches/rel10_ifa/psModules/src/astrom/pmFPA.h	(revision 6712)
+++ /branches/rel10_ifa/psModules/src/astrom/pmFPA.h	(revision 6713)
@@ -7,6 +7,6 @@
 *  @author GLG, MHPCC
 *
-*  @version $Revision: 1.1.4.4 $ $Name: not supported by cvs2svn $
-*  @date $Date: 2006-03-23 03:09:57 $
+*  @version $Revision: 1.1.4.5 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2006-03-28 02:16:26 $
 *
 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -88,5 +88,6 @@
     pmFPA *parent;                      ///< Parent FPA
     bool process;                       ///< Do we bother about reading and working with this chip?
-    bool exists;                        ///< Does the chip exist --- has it been read in?
+    bool file_exists;                   ///< Does the file for this chip exist (read case only)?
+    bool data_exists;                   ///< Does the data for this chip exist (read case only)?
     pmHDU *hdu;                         ///< FITS data
 }
@@ -110,5 +111,6 @@
     pmChip *parent;                     ///< Parent chip
     bool process;                       ///< Do we bother about reading and working with this cell?
-    bool exists;                        ///< Does the cell exist --- has it been read in?
+    bool file_exists;                   ///< Does the file for this cell exist (read case only)?
+    bool data_exists;                   ///< Does the data for this cell exist (read case only)?
     pmHDU *hdu;                         ///< FITS data
 }
@@ -133,4 +135,7 @@
     psMetadata *analysis;               ///< Readout-level analysis metadata
     pmCell *parent;                     ///< Parent cell
+    bool process;                       ///< Do we bother about reading and working with this readout?
+    bool file_exists;                   ///< Does the file for this readout exist (read case only)?
+    bool data_exists;                   ///< Does the data for this readout exist (read case only)?
 }
 pmReadout;
@@ -207,5 +212,13 @@
 );
 
-
+/* functions to turn on/off the file_exists flags */
+bool pmFPASetFileStatus (pmFPA *fpa, bool status);
+bool pmChipSetFileStatus (pmChip *chip, bool status);
+bool pmCellSetFileStatus (pmCell *cell, bool status);
+
+/* functions to turn on/off the data_exists flags */
+bool pmFPASetDataStatus (pmFPA *fpa, bool status);
+bool pmChipSetDataStatus (pmChip *chip, bool status);
+bool pmCellSetDataStatus (pmCell *cell, bool status);
 
 /** FUNC DESC
Index: /branches/rel10_ifa/psModules/src/astrom/pmFPAConstruct.c
===================================================================
--- /branches/rel10_ifa/psModules/src/astrom/pmFPAConstruct.c	(revision 6712)
+++ /branches/rel10_ifa/psModules/src/astrom/pmFPAConstruct.c	(revision 6713)
@@ -184,5 +184,4 @@
     view->cell = -1;
     view->readout = -1;
-    view->fpa = psMemIncrRefCounter(fpa);
     if (strcasecmp(phuType, "FPA") == 0) {
         if (fpa->hdu) {
@@ -194,4 +193,5 @@
         fpa->hdu = phdu;
         pmConceptsReadFPA(fpa, PM_CONCEPT_SOURCE_HEADER, NULL);
+        pmFPASetFileStatus (fpa, true);
     } else {
         // Get the chip
@@ -215,4 +215,5 @@
             chip->hdu = phdu;
             pmConceptsReadChip(chip, PM_CONCEPT_SOURCE_HEADER, true, NULL);
+            pmChipSetFileStatus (chip, true);
         } else if (strcasecmp(phuType, "CELL") == 0) {
             psError(PS_ERR_IO, true, "Not yet sure how to handle PHU=CELL.\n");
@@ -239,4 +240,5 @@
             cell->hdu = phdu;
             pmConceptsReadCell(cell, PM_CONCEPT_SOURCE_HEADER, true, NULL);
+            pmCellSetFileStatus (cell, true);
             #endif
 
Index: /branches/rel10_ifa/psModules/src/astrom/pmFPARead.c
===================================================================
--- /branches/rel10_ifa/psModules/src/astrom/pmFPARead.c	(revision 6712)
+++ /branches/rel10_ifa/psModules/src/astrom/pmFPARead.c	(revision 6713)
@@ -8,4 +8,5 @@
 #include "pmConcepts.h"
 #include "psRegionIsBad.h"
+#include "pmHDUUtils.h"
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -107,4 +108,5 @@
     }
 
+    pmCellSetDataStatus (cell, true);
     return true;
 }
@@ -124,4 +126,6 @@
     if (success) {
         pmConceptsReadChip(chip, PM_CONCEPT_SOURCE_HEADER, false, NULL);
+        // XXX probably could just use chip->data_exists
+        pmChipSetDataStatus (chip, true);
     }
 
@@ -379,5 +383,5 @@
     for (int chipNum = 0; chipNum < chips->n; chipNum++) {
         pmChip *chip = chips->data[chipNum]; // The current chip of interest
-        if (chip->process && !chip->exists) {
+        if (chip->process && !chip->data_exists) {
             if (chip->hdu) {
                 hdu = chip->hdu;
@@ -386,5 +390,5 @@
             for (int cellNum = 0; cellNum < cells->n; cellNum++) {
                 pmCell *cell = cells->data[cellNum]; // The current cell of interest
-                if (cell->process && !cell->exists) {
+                if (cell->process && !cell->data_exists) {
                     if (cell->hdu) {
                         hdu = cell->hdu;
@@ -517,5 +521,5 @@
     for (int chipNum = 0; chipNum < chips->n; chipNum++) {
         pmChip *chip = chips->data[chipNum]; // The current chip of interest
-        if (chip->process && !chip->exists) {
+        if (chip->process && !chip->data_exists) {
             if (chip->hdu) {
                 hdu = chip->hdu;
@@ -524,5 +528,5 @@
             for (int cellNum = 0; cellNum < cells->n; cellNum++) {
                 pmCell *cell = cells->data[cellNum]; // The current cell of interest
-                if (cell->process && !cell->exists) {
+                if (cell->process && !cell->data_exists) {
                     if (cell->hdu) {
                         hdu = cell->hdu;
Index: /branches/rel10_ifa/psModules/src/astrom/pmFPAfile.c
===================================================================
--- /branches/rel10_ifa/psModules/src/astrom/pmFPAfile.c	(revision 6712)
+++ /branches/rel10_ifa/psModules/src/astrom/pmFPAfile.c	(revision 6713)
@@ -16,11 +16,20 @@
         return;
 
-    psFree (file->fits);
+    psFree (file->fpa);
+    psFree (file->names);
+
+    psFitsClose (file->fits);
+
     psFree (file->filerule);
     psFree (file->filextra);
     psFree (file->extrule);
     psFree (file->extxtra);
-    psFree (file->filename);
-    psFree (file->extname);
+
+    // these are just views:
+    // psFree (file->filename);
+    // psFree (file->extname);
+    // psFree (file->phu);
+    // psFree (file->header);
+
     return;
 }
@@ -32,98 +41,159 @@
     psMemSetDeallocator (file, (psFreeFunc) pmFPAfileFree);
 
+    file->phu = NULL;
+    file->header = NULL;
+
+    file->fpa = NULL;
     file->fits = NULL;
+    file->names = psMetadataAlloc();
+
     file->filerule = NULL;
     file->filextra = NULL;
     file->extrule  = NULL;
     file->extxtra  = NULL;
+
     file->filename = NULL;
     file->extname  = NULL;
+
+    file->type = PM_FPA_FILE_NONE;
+    file->mode = PM_FPA_MODE_NONE;
+    file->state = PM_FPA_STATE_CLOSED;
+
     return (file);
 }
 
 // XXX is a file allowed to be both READ and WRITE?
-pmFPAfile *pmFPAfileDefine (psMetadata *files, psMetadata *camera, pmFPA *fpa, char *name)
+pmFPAfile *pmFPAfileDefine (psMetadata *files, psMetadata *format, pmFPA *fpa, char *name)
 {
 
     bool status;
     char *depth;
-
-    // select the name from the camera config data
-    psMetadata *data = psMetadataLookupPtr (&status, camera, name);
+    char *type;
+
+    // select the FILERULES from the camera format
+    psMetadata *filerules = psMetadataLookupPtr (&status, format, "FILERULES");
+    if (filerules == NULL) {
+        psErrorStackPrint(stderr, "Can't find FILERULES in the FORMAT configuration!\n");
+        return NULL;
+    }
+
+    // select the name from the FILERULES
+    // check for indirect name (type == STR, name is aliased name)
+    char *realname = psMetadataLookupStr (&status, filerules, name);
+    if (realname == NULL)
+        realname = name;
+
+    psMetadata *data = psMetadataLookupPtr (&status, filerules, realname);
     if (data == NULL) {
+        psErrorStackPrint(stderr, "Can't find file concept %s!\n", name);
         return NULL;
     }
 
     pmFPAfile *file = pmFPAfileAlloc ();
-    file->filerule = psMetadataLookupStr (&status, data, "FILENAME.RULE");
-    file->filextra = psMetadataLookupStr (&status, data, "FILENAME.XTRA");
-    file->extrule  = psMetadataLookupStr (&status, data, "EXTNAME.RULE");
-    file->extxtra  = psMetadataLookupStr (&status, data, "EXTNAME.XTRA");
-
-    file->openDepth = PM_FPA_DEPTH_NONE;
-    depth = psMetadataLookupStr (&status, data, "OPEN.DEPTH");
+    file->filerule = psMemIncrRefCounter(psMetadataLookupStr (&status, data, "FILENAME.RULE"));
+    file->filextra = psMemIncrRefCounter(psMetadataLookupStr (&status, data, "FILENAME.XTRA"));
+    file->extrule  = psMemIncrRefCounter(psMetadataLookupStr (&status, data, "EXTNAME.RULE"));
+    file->extxtra  = psMemIncrRefCounter(psMetadataLookupStr (&status, data, "EXTNAME.XTRA"));
+
+    file->fileDepth = PM_FPA_DEPTH_NONE;
+    depth = psMetadataLookupStr (&status, data, "FILE.DEPTH");
     if (depth != NULL) {
         if (!strcasecmp (depth, "FPA"))     {
-            file->openDepth = PM_FPA_DEPTH_FPA;
+            file->fileDepth = PM_FPA_DEPTH_FPA;
         }
         if (!strcasecmp (depth, "CHIP"))    {
-            file->openDepth = PM_FPA_DEPTH_CHIP;
+            file->fileDepth = PM_FPA_DEPTH_CHIP;
         }
         if (!strcasecmp (depth, "CELL"))    {
-            file->openDepth = PM_FPA_DEPTH_CELL;
+            file->fileDepth = PM_FPA_DEPTH_CELL;
         }
         if (!strcasecmp (depth, "READOUT")) {
-            file->openDepth = PM_FPA_DEPTH_READOUT;
-        }
-    }
-
-    file->readDepth = PM_FPA_DEPTH_NONE;
-    depth = psMetadataLookupStr (&status, data, "READ.DEPTH");
+            file->fileDepth = PM_FPA_DEPTH_READOUT;
+        }
+    }
+    if (file->fileDepth == PM_FPA_DEPTH_NONE) {
+        psLogMsg (__func__, 3, "warning: FILE.DEPTH is not set for %s\n", name);
+    }
+
+    file->dataDepth = PM_FPA_DEPTH_NONE;
+    depth = psMetadataLookupStr (&status, data, "DATA.DEPTH");
     if (depth != NULL) {
         if (!strcasecmp (depth, "FPA"))     {
-            file->readDepth = PM_FPA_DEPTH_FPA;
+            file->dataDepth = PM_FPA_DEPTH_FPA;
         }
         if (!strcasecmp (depth, "CHIP"))    {
-            file->readDepth = PM_FPA_DEPTH_CHIP;
+            file->dataDepth = PM_FPA_DEPTH_CHIP;
         }
         if (!strcasecmp (depth, "CELL"))    {
-            file->readDepth = PM_FPA_DEPTH_CELL;
+            file->dataDepth = PM_FPA_DEPTH_CELL;
         }
         if (!strcasecmp (depth, "READOUT")) {
-            file->readDepth = PM_FPA_DEPTH_READOUT;
-        }
-    }
-
-    file->writeDepth = PM_FPA_DEPTH_NONE;
-    depth = psMetadataLookupStr (&status, data, "WRITE.DEPTH");
-    if (depth != NULL) {
-        if (!strcasecmp (depth, "FPA"))     {
-            file->writeDepth = PM_FPA_DEPTH_FPA;
-        }
-        if (!strcasecmp (depth, "CHIP"))    {
-            file->writeDepth = PM_FPA_DEPTH_CHIP;
-        }
-        if (!strcasecmp (depth, "CELL"))    {
-            file->writeDepth = PM_FPA_DEPTH_CELL;
-        }
-        if (!strcasecmp (depth, "READOUT")) {
-            file->writeDepth = PM_FPA_DEPTH_READOUT;
-        }
-    }
-
-    if ((file->readDepth != PM_FPA_DEPTH_NONE) && (file->writeDepth != PM_FPA_DEPTH_NONE)) {
-        psLogMsg (__func__, 3, "warning: file %s is set to both read and write; write is ignored\n", name);
-        file->writeDepth = PM_FPA_DEPTH_NONE;
-    }
-
-    if (fpa == NULL) {
-        fpa = pmFPAConstruct (camera);
-    }
-    file->fpa = fpa;
-
-    psMetadataAddPtr (files, PS_LIST_TAIL, name, PS_META_REPLACE, "", file);
+            file->dataDepth = PM_FPA_DEPTH_READOUT;
+        }
+    }
+    if (file->dataDepth == PM_FPA_DEPTH_NONE) {
+        psLogMsg (__func__, 3, "warning: DATA.DEPTH is not set for %s\n", name);
+    }
+
+    file->type = PM_FPA_FILE_NONE;
+    type = psMetadataLookupStr (&status, data, "FILE.TYPE");
+    if (type != NULL) {
+        if (!strcasecmp (type, "SX"))     {
+            file->type = PM_FPA_FILE_SX;
+        }
+        if (!strcasecmp (type, "OBJ"))     {
+            file->type = PM_FPA_FILE_OBJ;
+        }
+        if (!strcasecmp (type, "CMP"))     {
+            file->type = PM_FPA_FILE_CMP;
+        }
+        if (!strcasecmp (type, "CMF"))     {
+            file->type = PM_FPA_FILE_CMF;
+        }
+        if (!strcasecmp (type, "RAW"))     {
+            file->type = PM_FPA_FILE_RAW;
+        }
+        if (!strcasecmp (type, "IMAGE"))     {
+            file->type = PM_FPA_FILE_IMAGE;
+        }
+    }
+    if (file->type == PM_FPA_FILE_NONE) {
+        psLogMsg (__func__, 3, "warning: FILE.TYPE is not defined for %s\n", name);
+    }
+
+    file->mode = PM_FPA_MODE_NONE;
+    type = psMetadataLookupStr (&status, data, "FILE.MODE");
+    if (type != NULL) {
+        if (!strcasecmp (type, "READ"))     {
+            file->mode = PM_FPA_MODE_READ;
+        }
+        if (!strcasecmp (type, "WRITE"))     {
+            file->mode = PM_FPA_MODE_WRITE;
+        }
+    }
+    if (file->mode == PM_FPA_MODE_NONE) {
+        psLogMsg (__func__, 3, "warning: FILE.MODE is not defined for %s\n", name);
+    }
+
+    file->fpa = psMemIncrRefCounter(fpa);
+
+    psMetadataAddPtr (files, PS_LIST_TAIL, name, PS_DATA_UNKNOWN, "", file);
+
+    // we free this copy of file, but 'files' still has a copy
+    psFree (file);
+
+    // the returned value is a view into the version on 'files'
     return (file);
 }
 
+pmFPAfile *pmFPAfileConstruct (psMetadata *files, psMetadata *format, psMetadata *camera, char *name)
+{
+    pmFPA *fpa = pmFPAConstruct (camera);
+    pmFPAfile *file = pmFPAfileDefine (files, format, fpa, name);
+    psFree (fpa);
+    return file;
+}
+
+// open file (if not already opened XXX : better tracking of open state?
 bool pmFPAfileOpen (pmFPAfile *file, pmFPAview *view)
 {
@@ -131,28 +201,62 @@
     bool status;
     char *extra;
-
-    // is current depth == open depth?
-    pmFPAdepth depth = pmFPAviewDepth (view);
-    if (file->openDepth != depth) {
-        return false;
+    char *mode;
+    char *readMode = "r";
+    char *writeMode = "w";
+
+    if (file->mode == PM_FPA_MODE_NONE) {
+        return false;
+    }
+    if (file->mode == PM_FPA_MODE_READ) {
+        mode = readMode;
+    }
+    if (file->mode == PM_FPA_MODE_WRITE) {
+        mode = writeMode;
+    }
+
+    if (file->state == PM_FPA_STATE_OPEN) {
+        return true;
     }
 
     // determine the file name
-    file->filename = pmFPAviewNameFromRule (file->filerule, view, file->fpa);
+    // XXX file->filename needs to be a copy, and freed in places like this...
+    file->filename = pmFPAfileNameFromRule (file->filerule, file, view);
+    if (file->filename == NULL)
+        return false;
 
     // indirect filenames
     if (!strcasecmp (file->filename, "@FPAIO")) {
-        extra = pmFPAviewNameFromRule (file->filextra, view, file->fpa);
+        extra = pmFPAfileNameFromRule (file->filextra, file, view);
         file->filename = psMetadataLookupStr (&status, file->names, extra);
+        if (file->filename == NULL)
+            return false;
     }
     if (!strcasecmp (file->filename, "@DETDB")) {
-        extra = pmFPAviewNameFromRule (file->filextra, view, file->fpa);
+        extra = pmFPAfileNameFromRule (file->filextra, file, view);
         // file->filename = pmDetrendSelect (extra);
-    }
-
-    if (file->readDepth != PM_FPA_DEPTH_NONE) {
-        file->fits = psFitsOpen (file->filename, "r");
-    } else if (file->writeDepth != PM_FPA_DEPTH_NONE) {
-        file->fits = psFitsOpen (file->filename, "w");
+        if (file->filename == NULL)
+            return false;
+    }
+
+    switch (file->type) {
+        // open the FITS types:
+    case PM_FPA_FILE_IMAGE:
+    case PM_FPA_FILE_CMF:
+        file->fits = psFitsOpen (file->filename, mode);
+        psTrace ("pmFPAfile", 5, "opening %s (type: %d)\n", file->filename, file->type);
+        file->state = PM_FPA_STATE_OPEN;
+        break;
+
+        // defer opening TEXT types:
+    case PM_FPA_FILE_SX:
+    case PM_FPA_FILE_OBJ:
+    case PM_FPA_FILE_CMP:
+    case PM_FPA_FILE_RAW:
+        psTrace ("pmFPAfile", 5, "not opening %s (type: %d)\n", file->filename, file->type);
+        break;
+
+    default:
+        fprintf (stderr, "warning: type mismatch for %s : %d\n", file->filename, file->type);
+        return false;
     }
     return true;
@@ -161,25 +265,35 @@
 bool pmFPAfileRead (pmFPAfile *file, pmFPAview *view)
 {
-
-    // is current depth == open depth?
+    if (file->mode != PM_FPA_MODE_READ)
+        return false;
+
+    // get the current depth
     pmFPAdepth depth = pmFPAviewDepth (view);
-    if (file->readDepth != depth) {
-        return false;
-    }
-
-    if (file->readDepth == PM_FPA_DEPTH_NONE) {
-        return false;
-    }
+
+    // do we need to open this file?
+    if (depth == file->fileDepth) {
+        pmFPAfileOpen (file, view);
+    }
+
+    // do we need to read this file?
+    if (depth != file->dataDepth)
+        return false;
 
     switch (file->type) {
     case PM_FPA_FILE_IMAGE:
-        pmFPAviewReadFitsImage (view, file);
+        if (pmFPAviewReadFitsImage (view, file)) {
+            psTrace ("pmFPAfile", 5, "reading %s (type: %d)\n", file->filename, file->type);
+        } else {
+            psTrace ("pmFPAfile", 5, "skipping %s (type: %d)\n", file->filename, file->type);
+        }
         break;
 
     case PM_FPA_FILE_SX:
+    case PM_FPA_FILE_RAW:
     case PM_FPA_FILE_OBJ:
     case PM_FPA_FILE_CMP:
     case PM_FPA_FILE_CMF:
         pmFPAviewReadObjects (view, file);
+        psTrace ("pmFPAfile", 5, "reading %s (type: %d)\n", file->filename, file->type);
         break;
 
@@ -193,13 +307,17 @@
 bool pmFPAfileWrite (pmFPAfile *file, pmFPAview *view)
 {
-
-    // is current depth == open depth?
+    if (file->mode != PM_FPA_MODE_WRITE)
+        return false;
+
+    // get the current depth
     pmFPAdepth depth = pmFPAviewDepth (view);
-    if (file->writeDepth != depth) {
-        return false;
-    }
-
-    if (file->writeDepth == PM_FPA_DEPTH_NONE) {
-        return false;
+
+    // do we need to write this file?
+    if (depth != file->dataDepth)
+        return false;
+
+    // do we need to open this file?
+    if (depth >= file->fileDepth) {
+        pmFPAfileOpen (file, view);
     }
 
@@ -212,8 +330,10 @@
 
     case PM_FPA_FILE_SX:
+    case PM_FPA_FILE_RAW:
     case PM_FPA_FILE_OBJ:
     case PM_FPA_FILE_CMP:
     case PM_FPA_FILE_CMF:
         pmFPAviewWriteObjects (view, file);
+        psTrace ("pmFPAfile", 5, "wrote %s (type: %d)\n", file->filename, file->type);
         break;
 
@@ -227,17 +347,43 @@
 bool pmFPAfileClose (pmFPAfile *file, pmFPAview *view)
 {
+    if (file->state == PM_FPA_STATE_CLOSED) {
+        return true;
+    }
+
     // is current depth == open depth?
     pmFPAdepth depth = pmFPAviewDepth (view);
-    if (file->openDepth != depth) {
+    if (file->fileDepth != depth) {
         return false;
     }
 
     // check if we are actually open
-    psFitsClose (file->fits);
-    return true;
-}
-
-// attempt open and read for all pmFPAfiles in view->IO
-bool pmFPAfileReadChecks (psMetadata *files, pmFPAview *view)
+    switch (file->type) {
+        // check the FITS types
+    case PM_FPA_FILE_IMAGE:
+    case PM_FPA_FILE_CMF:
+        psFitsClose (file->fits);
+        psTrace ("pmFPAfile", 5, "closing %s (type: %d)\n", file->filename, file->type);
+        file->fits = NULL;
+        file->phu = NULL;
+        file->header = NULL;
+        file->state = PM_FPA_STATE_CLOSED;
+        break;
+
+        // ignore the TEXT types
+    case PM_FPA_FILE_SX:
+    case PM_FPA_FILE_RAW:
+    case PM_FPA_FILE_OBJ:
+    case PM_FPA_FILE_CMP:
+        break;
+
+    default:
+        fprintf (stderr, "warning: type mismatch\n");
+        return false;
+    }
+    return true;
+}
+
+// attempt open, read, write, or close pmFPAfiles in files
+bool pmFPAfileIOChecks (psMetadata *files, pmFPAview *view, pmFPAfilePlace place)
 {
     // recipe override values (command-line options):
@@ -247,6 +393,10 @@
         pmFPAfile *file = item->data.V;
 
-        pmFPAfileOpen (file, view);
-        pmFPAfileRead (file, view);
+        if (place == PM_FPA_BEFORE) {
+            pmFPAfileRead (file, view);
+        } else {
+            pmFPAfileWrite (file, view);
+            pmFPAfileClose (file, view);
+        }
     }
     psFree (iter);
@@ -254,18 +404,43 @@
 }
 
-// attempt open and read for all pmFPAfiles in view->IO
-bool pmFPAfileWriteChecks (psMetadata *files, pmFPAview *view)
-{
-    // recipe override values (command-line options):
-    psMetadataItem *item = NULL;
-    psMetadataIterator *iter = psMetadataIteratorAlloc (files, PS_LIST_HEAD, NULL);
-    while ((item = psMetadataGetAndIncrement (iter)) != NULL) {
-        pmFPAfile *file = item->data.V;
-
-        pmFPAfileWrite (file, view);
-        pmFPAfileClose (file, view);
-    }
-    psFree (iter);
-    return true;
+// select the rule from the camera configuration, perform substitutions as needed
+char *pmFPAfileNameFromRule (char *rule, pmFPAfile *file, pmFPAview *view)
+{
+
+    char *newName = NULL;     // destination for resulting name
+
+    newName = psStringCopy (rule);
+
+    if (strstr (newName, "{CHIP.NAME}") != NULL) {
+        pmChip *chip = pmFPAviewThisChip (view, file->fpa);
+        if (chip != NULL) {
+            char *name = psMetadataLookupStr (NULL, chip->concepts, "CHIP.NAME");
+            if (name != NULL) {
+                newName = psStringSubstitute (newName, name, "{CHIP.NAME}");
+            }
+        }
+    }
+    if (strstr (newName, "{CELL.NAME}") != NULL) {
+        pmCell *cell = pmFPAviewThisCell (view, file->fpa);
+        if (cell != NULL) {
+            char *name = psMetadataLookupStr (NULL, cell->concepts, "CELL.NAME");
+            if (name != NULL) {
+                newName = psStringSubstitute (newName, name, "{CELL.NAME}");
+            }
+        }
+    }
+    if (strstr (newName, "{EXTNAME}") != NULL) {
+        pmHDU *hdu = pmFPAviewThisHDU (view, file->fpa);
+        if (hdu->extname != NULL) {
+            newName = psStringSubstitute (newName, hdu->extname, "{EXTNAME}");
+        }
+    }
+    if (strstr (newName, "{OUTPUT}") != NULL) {
+        char *name = psMetadataLookupStr (NULL, file->names, "OUTPUT");
+        if (name != NULL) {
+            newName = psStringSubstitute (newName, name, "{OUTPUT}");
+        }
+    }
+    return newName;
 }
 
@@ -299,36 +474,15 @@
 }
 
-# if (0)
-    // return the named pmFPAfile
-    pmFPAfile *pmFPAfileSelect (pmFPAview *view, char *name)
-{
-
-    // select the name from the camera config data
-    pmFPAfile *file = psMetadataLookupPtr (&status, view->IO, name);
-    if (file == NULL) {
-        return NULL;
-    }
-    return file;
-}
-
-bool pmFPAfileWriteChecks (pmFPAview *view, char *name)
-{
-
-    pmFPAfile *file = pmFPAfileSelect (view, name);
-    pmFPAfileWrite (file, view);
-    return true;
-}
-#endif
-
 // given an already-opened fits file, read the components corresponding
 // to the specified view
 bool pmFPAviewReadFitsImage (pmFPAview *view, pmFPAfile *file)
 {
+    bool status;
     pmFPA *fpa = file->fpa;
     psFits *fits = file->fits;
 
     if (view->chip == -1) {
-        pmFPARead (fpa, fits, NULL);
-        return true;
+        status = pmFPARead (fpa, fits, NULL);
+        return status;
     }
 
@@ -339,6 +493,6 @@
 
     if (view->cell == -1) {
-        pmChipRead (chip, fits, NULL);
-        return true;
+        status = pmChipRead (chip, fits, NULL);
+        return status;
     }
 
@@ -349,6 +503,6 @@
 
     if (view->readout == -1) {
-        pmCellRead (cell, fits, NULL);
-        return true;
+        status = pmCellRead (cell, fits, NULL);
+        return status;
     }
 
Index: /branches/rel10_ifa/psModules/src/astrom/pmFPAfile.h
===================================================================
--- /branches/rel10_ifa/psModules/src/astrom/pmFPAfile.h	(revision 6712)
+++ /branches/rel10_ifa/psModules/src/astrom/pmFPAfile.h	(revision 6713)
@@ -7,6 +7,6 @@
 *  @author EAM, IfA
 *
-*  @version $Revision: 1.1.2.6 $ $Name: not supported by cvs2svn $
-*  @date $Date: 2006-03-14 04:40:37 $
+*  @version $Revision: 1.1.2.7 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2006-03-28 02:16:26 $
 *
 *  Copyright 2004-2005 Institute for Astronomy, University of Hawaii
@@ -21,4 +21,10 @@
 
 typedef enum {
+    PM_FPA_BEFORE,
+    PM_FPA_AFTER,
+} pmFPAfilePlace;
+
+typedef enum {
+    PM_FPA_FILE_NONE,
     PM_FPA_FILE_SX,
     PM_FPA_FILE_OBJ,
@@ -29,11 +35,27 @@
 } pmFPAfileType;
 
+typedef enum {
+    PM_FPA_MODE_NONE,
+    PM_FPA_MODE_READ,
+    PM_FPA_MODE_WRITE,
+} pmFPAfileMode;
+
+typedef enum {
+    PM_FPA_STATE_OPEN,
+    PM_FPA_STATE_CLOSED,
+} pmFPAfileState;
+
 typedef struct
 {
-    pmFPAdepth openDepth;
-    pmFPAdepth readDepth;
-    pmFPAdepth writeDepth;
+    pmFPAdepth fileDepth;
+    pmFPAdepth dataDepth;
 
+    psMetadata *phu;
+    psMetadata *header;
+
+    pmFPA *fpa;
     psFits *fits;
+    psMetadata *names;
+
     char *filerule;
     char *filextra;
@@ -45,7 +67,6 @@
 
     pmFPAfileType type;
-
-    psMetadata *names;
-    pmFPA *fpa;
+    pmFPAfileMode mode;
+    pmFPAfileState state;
 }
 pmFPAfile;
@@ -59,5 +80,5 @@
 
 bool pmFPAfileReadChecks (psMetadata *files, pmFPAview *view);
-bool pmFPAfileWriteChecks (psMetadata *files, pmFPAview *view);
+bool pmFPAfileIOChecks (psMetadata *files, pmFPAview *view, pmFPAfilePlace place);
 
 psImage *pmFPAfileReadoutImage (psMetadata *files, pmFPAview *view, char *name, int Nx, int Ny, int type);
@@ -69,3 +90,8 @@
 bool pmFPAviewWriteFitsImage (pmFPAview *view, pmFPAfile *file);
 
+// convert the rule to a name based on the current view
+char *pmFPAfileNameFromRule (char *rule, pmFPAfile *file, pmFPAview *view);
+
+pmFPAfile *pmFPAfileConstruct (psMetadata *files, psMetadata *format, psMetadata *camera, char *name);
+
 # endif
Index: /branches/rel10_ifa/psModules/src/astrom/pmFPAview.c
===================================================================
--- /branches/rel10_ifa/psModules/src/astrom/pmFPAview.c	(revision 6712)
+++ /branches/rel10_ifa/psModules/src/astrom/pmFPAview.c	(revision 6713)
@@ -3,6 +3,6 @@
  *  @author EAM, IfA
  *
- *  @version $Revision: 1.1.2.4 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2006-03-14 02:21:07 $
+ *  @version $Revision: 1.1.2.5 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2006-03-28 02:16:26 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -15,4 +15,5 @@
 #include "pslib.h"
 #include "pmHDU.h"
+#include "pmHDUUtils.h"
 #include "pmFPA.h"
 #include "pmFPAview.h"
@@ -212,5 +213,4 @@
 pmHDU *pmFPAviewThisHDU (pmFPAview *view, pmFPA *fpa)
 {
-
     // the HDU is attached to a cell, chip or fpa
     // if this view has a -1 for the level which contains the hdu,
@@ -229,36 +229,39 @@
 }
 
-// select the rule from the camera configuration, perform substitutions as needed
-char *pmFPAviewNameFromRule (char *rule, pmFPAview *view, pmFPA *fpa)
-{
-
-    char *newName = NULL;     // destination for resulting name
-
-    newName = psStringCopy (rule);
-
-    if (strstr (newName, "{CHIP.NAME}") != NULL) {
-        pmChip *chip = pmFPAviewThisChip (view, fpa);
-        if (chip != NULL) {
-            char *name = psMetadataLookupStr (NULL, chip->concepts, "CHIP.NAME");
-            if (name != NULL) {
-                newName = psStringSubstitute (newName, name, "{CHIP.NAME}");
-            }
-        }
-    }
-    if (strstr (newName, "{CELL.NAME}") != NULL) {
-        pmCell *cell = pmFPAviewThisCell (view, fpa);
-        if (cell != NULL) {
-            char *name = psMetadataLookupStr (NULL, cell->concepts, "CELL.NAME");
-            if (name != NULL) {
-                newName = psStringSubstitute (newName, name, "{CELL.NAME}");
-            }
-        }
-    }
-    if (strstr (newName, "{EXTNAME}") != NULL) {
-        pmHDU *hdu = pmFPAviewThisHDU (view, fpa);
-        if (hdu->extname != NULL) {
-            newName = psStringSubstitute (newName, hdu->extname, "{EXTNAME}");
-        }
-    }
-    return newName;
-}
+pmHDU *pmFPAviewThisPHU (pmFPAview *view, pmFPA *fpa)
+{
+    // select the HDU which corresponds to the PHU containing this view
+
+    pmHDU *hdu;
+    pmFPAview *new;
+    pmChip *chip;
+    pmCell *cell;
+
+    *new = *view;
+
+    if (view->chip < 0) {
+        hdu = pmHDUFromFPA (fpa);
+        if (hdu->phu)
+            return hdu;
+        return NULL;
+    }
+    if (view->cell < 0) {
+        chip = pmFPAviewThisChip (view, fpa);
+        hdu  = pmHDUFromChip (chip);
+        if (hdu->phu)
+            return hdu;
+        new->chip = -1;
+        hdu = pmFPAviewThisPHU (new, fpa);
+        return hdu;
+    }
+    if (view->readout < 0) {
+        cell = pmFPAviewThisCell (view, fpa);
+        hdu  = pmHDUFromCell (cell);
+        if (hdu->phu)
+            return hdu;
+        new->cell = -1;
+        hdu = pmFPAviewThisPHU (new, fpa);
+        return hdu;
+    }
+    return NULL;
+}
Index: /branches/rel10_ifa/psModules/src/astrom/pmFPAview.h
===================================================================
--- /branches/rel10_ifa/psModules/src/astrom/pmFPAview.h	(revision 6712)
+++ /branches/rel10_ifa/psModules/src/astrom/pmFPAview.h	(revision 6713)
@@ -7,6 +7,6 @@
 *  @author EAM, IfA
 *
-*  @version $Revision: 1.1.2.6 $ $Name: not supported by cvs2svn $
-*  @date $Date: 2006-03-17 01:47:44 $
+*  @version $Revision: 1.1.2.7 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2006-03-28 02:16:26 $
 *
 *  Copyright 2004-2005 Institute for Astronomy, University of Hawaii
@@ -37,5 +37,4 @@
     int nRows;                          // Maximum number of rows per readout segment read, or 0 for all
     int iRows;                          // Starting point for this read
-    pmFPA *fpa;
 }
 pmFPAview;
@@ -67,7 +66,5 @@
 // return the HDU corresponding to the current view
 pmHDU *pmFPAviewThisHDU (pmFPAview *view, pmFPA *fpa);
-
-// convert the rule to a name based on the current view
-char *pmFPAviewNameFromRule (char *rule, pmFPAview *view, pmFPA *fpa);
+pmHDU *pmFPAviewThisPHU (pmFPAview *view, pmFPA *fpa);
 
 # endif
Index: /branches/rel10_ifa/psModules/src/astrom/pmHDU.h
===================================================================
--- /branches/rel10_ifa/psModules/src/astrom/pmHDU.h	(revision 6712)
+++ /branches/rel10_ifa/psModules/src/astrom/pmHDU.h	(revision 6713)
@@ -10,4 +10,6 @@
     psMetadata *header;                 // The FITS header, or NULL if primary for FITS; or section info
     psArray *images;                    // The pixel data
+    psArray *weights;                   // The pixel data
+    psArray *masks;                     // The pixel data
     psArray *table;                     // The table data
 }
Index: /branches/rel10_ifa/psModules/src/astrom/pmHDUUtils.c
===================================================================
--- /branches/rel10_ifa/psModules/src/astrom/pmHDUUtils.c	(revision 6712)
+++ /branches/rel10_ifa/psModules/src/astrom/pmHDUUtils.c	(revision 6713)
@@ -33,4 +33,11 @@
 }
 
+pmHDU *pmHDUFromReadout (pmReadout *readout)
+{
+
+    pmCell *cell = readout->parent; // cell containing this readout;
+    pmHDU *hdu = pmHDUFromCell (cell);
+    return hdu;
+}
 
 // Get the lowest HDU
Index: /branches/rel10_ifa/psModules/src/astrom/pmHDUUtils.h
===================================================================
--- /branches/rel10_ifa/psModules/src/astrom/pmHDUUtils.h	(revision 6712)
+++ /branches/rel10_ifa/psModules/src/astrom/pmHDUUtils.h	(revision 6713)
@@ -19,3 +19,6 @@
                     );
 
+pmHDU *pmHDUFromReadout (pmReadout *readout  // Readout for which to find HDU
+                        );
+
 #endif
Index: /branches/rel10_ifa/psModules/src/astrom/pmReadout.c
===================================================================
--- /branches/rel10_ifa/psModules/src/astrom/pmReadout.c	(revision 6712)
+++ /branches/rel10_ifa/psModules/src/astrom/pmReadout.c	(revision 6713)
@@ -1,6 +1,7 @@
 #include <stdio.h>
 #include "pslib.h"
-
 #include "pmFPA.h"
+#include "pmHDUUtils.h"
+#include "pmFPAMaskWeight.h"
 
 // Get the bias images for a readout, using the CELL.BIASSEC
@@ -25,2 +26,84 @@
     return images;
 }
+
+bool pmReadoutSetWeights(pmReadout *readout)
+{
+
+    pmCell *cell = readout->parent;
+
+    float gain = psMetadataLookupF32(NULL, cell->concepts, "CELL.GAIN"); // Cell gain
+    float readnoise = psMetadataLookupF32(NULL, cell->concepts, "CELL.READNOISE"); // Cell read noise
+    psRegion *trimsec = psMetadataLookupPtr(NULL, cell->concepts, "CELL.TRIMSEC"); // Trim section
+    float saturation = psMetadataLookupF32(NULL, cell->concepts, "CELL.SATURATION"); // Saturation level
+    float bad = psMetadataLookupF32(NULL, cell->concepts, "CELL.BAD"); // Bad level
+
+    pmHDU *hdu = pmHDUFromCell (cell);
+
+    psArray *pixels = hdu->images;      // Array of images
+    psArray *weights = hdu->weights;    // Array of weight images
+    psArray *masks = hdu->masks;        // Array of mask images
+    // Generate the weights and masks if required
+    if (! weights) {
+        weights = psArrayAlloc(pixels->n);
+        for (int i = 0; i < pixels->n; i++) {
+            psImage *image = pixels->data[i];
+            weights->data[i] = psImageAlloc(image->numCols, image->numRows, PS_TYPE_F32);
+            psImageInit(weights->data[i], 0.0);
+        }
+        hdu->weights = weights;
+    }
+    if (! masks) {
+        masks = psArrayAlloc(pixels->n);
+        for (int i = 0; i < pixels->n; i++) {
+            psImage *image = pixels->data[i];
+            masks->data[i] = psImageAlloc(image->numCols, image->numRows, PS_TYPE_U8);
+            psImageInit(masks->data[i], 0);
+        }
+        hdu->masks = masks;
+    }
+
+    // Set the pixels
+    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->weight) {
+            readout->weight = psMemIncrRefCounter(psImageSubset(weights->data[i], *trimsec));
+        }
+        if (! readout->mask) {
+            readout->mask = psMemIncrRefCounter(psImageSubset(masks->data[i], *trimsec));
+        }
+
+        // Set up the mask
+        psImage *image = readout->image;// Pixels
+        psImage *mask = readout->mask;  // Mask image
+        for (int i = 0; i < image->numRows; i++) {
+            for (int j = 0; j < image->numCols; j++) {
+                if (image->data.F32[i][j] >= saturation) {
+                    mask->data.U8[i][j] = PM_MASK_SAT;
+                }
+                if (image->data.F32[i][j] <= bad) {
+                    mask->data.U8[i][j] = PM_MASK_BAD;
+                }
+            }
+        }
+
+        psImage *weight = readout->weight;  // Mask image
+        float rnoise = PS_SQR(readnoise/gain);
+        for (int i = 0; i < image->numRows; i++) {
+            for (int j = 0; j < image->numCols; j++) {
+                if (!mask->data.U8[i][j]) {
+                    weight->data.F32[i][j] = image->data.F32[i][j]/ gain + rnoise;
+                }
+            }
+        }
+
+        // Set weight image to the variance = g*f + rn^2
+        // psBinaryOp(readout->weight, image, "/", psScalarAlloc(gain, PS_TYPE_F32));
+        // psBinaryOp(readout->weight, readout->weight, "+",
+        // psScalarAlloc(readnoise*readnoise/gain/gain, PS_TYPE_F32));
+    }
+
+    return true;
+}
+
Index: /branches/rel10_ifa/psModules/src/astrom/pmReadout.h
===================================================================
--- /branches/rel10_ifa/psModules/src/astrom/pmReadout.h	(revision 6712)
+++ /branches/rel10_ifa/psModules/src/astrom/pmReadout.h	(revision 6713)
@@ -9,4 +9,5 @@
                         );
 
+bool pmReadoutSetWeights(pmReadout *readout);
 
 #endif
Index: anches/rel10_ifa/psModules/src/astrom/psAdditionals.c
===================================================================
--- /branches/rel10_ifa/psModules/src/astrom/psAdditionals.c	(revision 6712)
+++ 	(revision )
@@ -1,169 +1,0 @@
-#include <stdio.h>
-#include <strings.h>
-#include "pslib.h"
-
-#include "psAdditionals.h"
-
-
-psMetadata *pap_psMetadataCopy(psMetadata *out,
-                               const psMetadata *in)
-{
-    PS_ASSERT_PTR_NON_NULL(in,NULL);
-    if (out ==  NULL) {
-        out = psMetadataAlloc();
-    }
-    psMetadataItem *inItem = NULL;
-    psMetadataIterator *iter = psMetadataIteratorAlloc(*(psMetadata**)&in, PS_LIST_HEAD, NULL);
-    unsigned long numPointers = 0;      // Number of pointers we were forced to copy
-    while ((inItem = psMetadataGetAndIncrement(iter))) {
-        // Need to look for MULTI, which won't be picked up using the iterator.
-        psMetadataItem *multiCheckItem = psMetadataLookup(in, inItem->name);
-        unsigned int flag = PS_META_REPLACE; // Flag to indicate MULTI; otherwise, replace
-        if (multiCheckItem->type == PS_DATA_METADATA_MULTI) {
-            psTrace(__func__, 10, "MULTI: %s (%s)\n", inItem->name, inItem->comment);
-            flag = PS_DATA_METADATA_MULTI;
-        }
-
-        psTrace(__func__, 5, "Copying %s (%s)...\n", inItem->name, inItem->comment);
-
-        #define PS_METADATA_COPY_CASE(NAME,TYPE) \
-    case PS_TYPE_##NAME: \
-        if (! psMetadataAdd(out, PS_LIST_TAIL, inItem->name, PS_TYPE_##NAME | flag, inItem->comment, \
-                            inItem->data.TYPE)) { \
-            psErrorStackPrint(stderr, "Error copying %s (%s) in the metadata\n", inItem->name, \
-                              inItem->comment); \
-        } \
-        break;
-
-        switch (inItem->type) {
-            // Numerical types
-            PS_METADATA_COPY_CASE(BOOL,B);
-            PS_METADATA_COPY_CASE(S8,S8);
-            PS_METADATA_COPY_CASE(S16,S16);
-            PS_METADATA_COPY_CASE(S32,S32);
-            PS_METADATA_COPY_CASE(U8,U8);
-            PS_METADATA_COPY_CASE(U16,U16);
-            PS_METADATA_COPY_CASE(U32,U32);
-            PS_METADATA_COPY_CASE(F32,F32);
-            PS_METADATA_COPY_CASE(F64,F64);
-
-            // String: relying on the fact that this will copy the string, not point at it.
-        case PS_DATA_STRING:
-            psMetadataAdd(out, PS_LIST_TAIL, inItem->name, PS_DATA_STRING | flag, inItem->comment,
-                          inItem->data.V);
-            break;
-
-            // Metadata: copy the next level and stuff that in too
-        case PS_DATA_METADATA: {
-                psMetadata *metadata = pap_psMetadataCopy(NULL, inItem->data.md);
-                psMetadataAdd(out, PS_LIST_TAIL, inItem->name, PS_DATA_METADATA | flag, inItem->comment,
-                              metadata);
-                break;
-            }
-            // Other kinds of pointers
-        default:
-            numPointers++;
-            psTrace(__func__, 10, "Copying a pointer in the metadata: %x\n", inItem->type);
-            psMetadataAdd(out, PS_LIST_TAIL, inItem->name, inItem->type | flag, inItem->comment,
-                          inItem->data.V);
-            break;
-        }
-    }
-    psFree(iter);
-
-    if (numPointers > 0) {
-        psLogMsg(__func__, PS_LOG_WARN, "Forced to copy %d pointers when copying metadata.  Updating the "
-                 "copied psMetadata will affect the original!\n", numPointers);
-    }
-
-    return out;
-}
-
-
-void psMetadataPrint(psMetadata *md, int level)
-{
-    psMetadataIterator *iter = psMetadataIteratorAlloc(md, PS_LIST_HEAD, NULL); // Iterator
-    psMetadataItem *item = NULL;        // Item from metadata
-    while ((item = psMetadataGetAndIncrement(iter))) {
-        // Indent...
-        for (int i = 0; i < level; i++) {
-            printf(" ");
-        }
-        printf("%s", item->name);
-        if (item->comment && strlen(item->comment) > 0) {
-            printf(" (%s)", item->comment);
-        }
-        printf(": ");
-        switch (item->type) {
-        case PS_DATA_STRING:
-            printf("%s", (char*)item->data.V);
-            break;
-        case PS_DATA_BOOL:
-            if (item->data.B) {
-                printf("True");
-            } else {
-                printf("False");
-            }
-            break;
-        case PS_DATA_S32:
-            printf("%d", item->data.S32);
-            break;
-        case PS_DATA_F32:
-            printf("%f", item->data.F32);
-            break;
-        case PS_DATA_F64:
-            printf("%f", item->data.F64);
-            break;
-        case PS_DATA_METADATA:
-            printf("\n");
-            psMetadataPrint(item->data.V, level + 1);
-            break;
-        default:
-            printf("\n");
-            psError(PS_ERR_IO, false, "Non-printable metadata type: %x\n", item->type);
-        }
-        printf("\n");
-    }
-    psFree(iter);
-
-    return;
-}
-
-// XXX: This should probably be implemented using strpbrk
-psList *psStringSplit(const char *string,
-                      const char *splitters)
-{
-    psList *values = psListAlloc(NULL); // The list of values to return
-    unsigned int length = strlen(string); // The length of the string
-    unsigned int numSplitters = strlen(splitters); // Number of characters that might split
-    unsigned int start = 0;             // The position of the start of a word
-    for (int i = 1; i < length; i++) {
-        bool split = false;             // Is this character a splitter?
-        for (int j = 0; j < numSplitters && ! split; j++) {
-            if (string[i] == splitters[j]) {
-                split = true;
-            }
-        }
-        if (split) {
-            if (i == start) {
-                // Some idiot put in two spaces, or two commas or something
-                start++;
-            } else {
-                // We're at the end of the word
-                psString word = psStringNCopy(&string[start], i - start);
-                (void)psListAdd(values, PS_LIST_TAIL, word);
-                start = i + 1;
-                psFree(word);
-            }
-        }
-    }
-    if (start < length) {
-        // Copy the last word
-        psString word = psStringNCopy(&string[start], length - start);
-        (void)psListAdd(values, PS_LIST_TAIL, word);
-        psFree(word);
-    }
-
-    return values;
-}
-
Index: anches/rel10_ifa/psModules/src/astrom/psAdditionals.h
===================================================================
--- /branches/rel10_ifa/psModules/src/astrom/psAdditionals.h	(revision 6712)
+++ 	(revision )
@@ -1,25 +1,0 @@
-// Functions that should go into psLib.
-
-
-#ifndef PS_ADDITIONALS_H
-#define PS_ADDITIONALS_H
-
-#include "pslib.h"
-
-// Deep copy of metadata
-// Corrected version of MHPCC code in psLib at the moment
-psMetadata *pap_psMetadataCopy(psMetadata *out, // Target, to which the copy is made
-                               const psMetadata *in // Source, from which the copy is made
-                              );
-
-// Print out the metadata
-void psMetadataPrint(psMetadata *md,    // Metadata to print
-                     int level          // Indent level
-                    );
-
-// Split string on given characters
-psList *psStringSplit(const char *string, // String to split
-                      const char *splitters // Characters on which to split
-                     );
-
-#endif
Index: /branches/rel10_ifa/psModules/src/config/pmConfig.c
===================================================================
--- /branches/rel10_ifa/psModules/src/config/pmConfig.c	(revision 6712)
+++ /branches/rel10_ifa/psModules/src/config/pmConfig.c	(revision 6713)
@@ -3,6 +3,6 @@
  *  @author PAP, IfA
  *
- *  @version $Revision: 1.7.4.5 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2006-03-14 04:40:37 $
+ *  @version $Revision: 1.7.4.6 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2006-03-28 02:16:26 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -22,4 +22,5 @@
 {
     psFree(config->site);
+    psFree(config->files);
     psFree(config->camera);
     psFree(config->recipes);
@@ -35,4 +36,5 @@
     // Initialise
     config->site = NULL;
+    config->files = NULL;
     config->camera = NULL;
     config->recipes = NULL;
Index: /branches/rel10_ifa/psModules/src/config/pmConfig.h
===================================================================
--- /branches/rel10_ifa/psModules/src/config/pmConfig.h	(revision 6712)
+++ /branches/rel10_ifa/psModules/src/config/pmConfig.h	(revision 6713)
@@ -3,6 +3,6 @@
  *  @author PAP, IfA
  *
- *  @version $Revision: 1.3.4.3 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2006-03-14 02:20:22 $
+ *  @version $Revision: 1.3.4.4 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2006-03-28 02:16:26 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -22,5 +22,5 @@
     psMetadata *recipes;                // Recipes for processing
     psMetadata *arguments;              // Command-line arguments
-    psMetadata *files;   // pmFPAfiles used for analysis
+    psMetadata *files;                  // pmFPAfiles used for analysis
     psDB *database;                     // Database handle
 }
Index: /branches/rel10_ifa/psModules/src/pslib/Makefile.am
===================================================================
--- /branches/rel10_ifa/psModules/src/pslib/Makefile.am	(revision 6712)
+++ /branches/rel10_ifa/psModules/src/pslib/Makefile.am	(revision 6713)
@@ -4,4 +4,5 @@
 libpsmodulepslib_la_LDFLAGS  = -release $(PACKAGE_VERSION)
 libpsmodulepslib_la_SOURCES  = \
+    psAdditionals.c \
     psEllipse.c \
     psImageJpeg.c \
@@ -14,4 +15,5 @@
 psmoduleincludedir = $(includedir)
 psmoduleinclude_HEADERS = \
+    psAdditionals.h \
     psEllipse.h \
     psImageJpeg.h \
Index: /branches/rel10_ifa/psModules/src/pslib/psAdditionals.c
===================================================================
--- /branches/rel10_ifa/psModules/src/pslib/psAdditionals.c	(revision 6712)
+++ /branches/rel10_ifa/psModules/src/pslib/psAdditionals.c	(revision 6713)
@@ -2,7 +2,5 @@
 #include <strings.h>
 #include "pslib.h"
-
 #include "psAdditionals.h"
-
 
 psMetadata *pap_psMetadataCopy(psMetadata *out,
Index: /branches/rel10_ifa/psModules/src/pslib/psRegionIsBad.c
===================================================================
--- /branches/rel10_ifa/psModules/src/pslib/psRegionIsBad.c	(revision 6712)
+++ /branches/rel10_ifa/psModules/src/pslib/psRegionIsBad.c	(revision 6713)
@@ -7,2 +7,15 @@
 }
 
+bool psRegionIsNaN (psRegion region)
+{
+
+    if (!isfinite(region.x0))
+        return true;
+    if (!isfinite(region.x1))
+        return true;
+    if (!isfinite(region.y0))
+        return true;
+    if (!isfinite(region.y1))
+        return true;
+    return false;
+}
Index: /branches/rel10_ifa/psModules/src/pslib/psRegionIsBad.h
===================================================================
--- /branches/rel10_ifa/psModules/src/pslib/psRegionIsBad.h	(revision 6712)
+++ /branches/rel10_ifa/psModules/src/pslib/psRegionIsBad.h	(revision 6713)
@@ -6,3 +6,7 @@
 bool psRegionIsBad(const psRegion region);
 
+// test is any element of the region is not finite
+bool psRegionIsNaN (psRegion region // test for this region
+                   );
+
 #endif
Index: /branches/rel10_ifa/psModules/src/psmodules.h
===================================================================
--- /branches/rel10_ifa/psModules/src/psmodules.h	(revision 6712)
+++ /branches/rel10_ifa/psModules/src/psmodules.h	(revision 6713)
@@ -2,53 +2,73 @@
 #define PS_MODULES_H
 
-#include "pslib.h"
+// XXX should this be included explicitly?
+#include <pslib.h>
 
-#include "psImageJpeg.h"
-#include "psLine.h"
-#include "psPolynomialUtils.h"
-#include "psSparse.h"
-#include "psEllipse.h"
-//#include "pmChipMosaic.h"
-#include "pmConcepts.h"
-#include "pmConceptsRead.h"
-#include "pmConceptsStandard.h"
-#include "pmConceptsWrite.h"
-#include "pmHDU.h"
-#include "pmFPA.h"
-//#include "pmFPAAstrometry.h"
-#include "pmFPAConstruct.h"
-#include "pmFPARead.h"
-#include "pmFPAWrite.h"
-#include "pmReadout.h"
-#include "pmFPAfile.h"
-#include "pmFPAview.h"
-#include "pmConfig.h"
-#include "pmFlatField.h"
-#include "pmFlatFieldErrors.h"
-#include "pmMaskBadPixels.h"
-#include "pmMaskBadPixelsErrors.h"
-#include "pmNonLinear.h"
-#include "pmImageCombine.h"
-//#include "pmReadoutCombine.h"
-#include "pmImageSubtract.h"
-#include "pmSubtractBias.h"
-//#include "pmSubtractSky.h"
+// the following headers are from psModule:pslib
+#include <psImageJpeg.h>
+#include <psLine.h>
+#include <psPolynomialUtils.h>
+#include <psSparse.h>
+#include <psEllipse.h>
+#include <psAdditionals.h>
+#include <psRegionIsBad.h>
+#include <psMetadataItemParse.h>
 
-// #include "pmGrowthCurve.h"
-// #include "pmObjects.h"
-// #include "pmObjectsIO.h"
-// #include "pmModel.h"
-// #include "pmPSF.h"
-// #include "pmPSFtry.h"
-// #include "pmMoments.h"
-// #include "pmPeaks.h"
-// #include "pmSource.h"
-// #include "pmSourceContour.h"
-// #include "pmSourceFitModel.h"
-// #include "pmSourceFitSet.h"
-// #include "pmSourcePhotometry.h"
-// #include "pmSourceSky.h"
-// #include "pmSourceIO.h"
-// #include "pmModelGroup.h"
+// the following headers are from psModule:config
+#include <pmConfig.h>
+
+// the following headers are from psModule:astrom
+#include <pmConcepts.h>
+#include <pmConceptsRead.h>
+#include <pmConceptsStandard.h>
+#include <pmConceptsWrite.h>
+#include <pmHDU.h>
+#include <pmHDUUtils.h>
+#include <pmFPA.h>
+#include <pmFPAview.h>
+#include <pmFPAfile.h>
+#include <pmFPARead.h>
+#include <pmFPAConstruct.h>
+#include <pmFPAConstruct.h>
+#include <pmFPARead.h>
+#include <pmFPAWrite.h>
+#include <pmReadout.h>
+#include <pmFPAfile.h>
+#include <pmFPAview.h>
+// #include <pmChipMosaic.h>
+// #include <pmFPAAstrometry.h>
+
+// the following headers are from psModule:detrend
+#include <pmFlatField.h>
+#include <pmFlatFieldErrors.h>
+#include <pmMaskBadPixels.h>
+#include <pmMaskBadPixelsErrors.h>
+#include <pmNonLinear.h>
+
+// the following headers are from psModule:imcombine
+#include <pmImageCombine.h>
+// #include <pmReadoutCombine.h>
+
+// the following headers are from psModule:detrend
+#include <pmSubtractBias.h>
+#include <pmImageSubtract.h>
+// #include <pmSubtractSky.h>
+
+// the following headers are from psModule:objects
+# include <pmPeaks.h>
+# include <pmMoments.h>
+# include <pmModel.h>
+# include <pmSource.h>
+# include <pmSourceIO.h>
+# include <pmSourceSky.h>
+# include <pmSourceFitModel.h>
+# include <pmSourceFitSet.h>
+# include <pmSourceContour.h>
+# include <pmGrowthCurve.h>
+# include <pmPSF.h>
+# include <pmPSFtry.h>
+# include <pmModelGroup.h>
+# include <pmSourcePhotometry.h>
+# include <pmFPAviewObjectsIO.h>
 
 #endif
